Skip to content

Commit

Permalink
z80ctc wip
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Jul 14, 2024
1 parent 8d43c17 commit 1a056c5
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
17 changes: 10 additions & 7 deletions src/chips/z80ctc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ pub fn Z80CTC(comptime P: Pins, comptime Bus: anytype) type {
var bus = in_bus;
const data = getData(bus);
const chn_id: usize = (bus >> P.CS[0]) & 3;
var chn = self.chn[chn_id];
var chn = &self.chn[chn_id];
if (chn.control & CTRL.CONST_FOLLOWS != 0) {
// timer constant following control word
chn.control &= ~(CTRL.CONST_FOLLOW | CTRL.RESET);
chn.control &= ~(CTRL.CONST_FOLLOWS | CTRL.RESET);
chn.constant = data;
if (chn.control & CTRL.MODE == CTRL.MODE_TIMER) {
if (chn.control & CTRL.TRIGGER == CTRL.TRIGGER_WAIT) {
Expand Down Expand Up @@ -208,19 +208,21 @@ pub fn Z80CTC(comptime P: Pins, comptime Bus: anytype) type {
// are then computed from the base vector plus 2 bytes per channel
if (0 == chn_id) {
for (0..NUM_CHANNELS) |i| {
self.chn[i].int_vector = (data & 0xF8) + 2 * i;
self.chn[i].int_vector = @truncate((data & 0xF8) + 2 * i);
}
}
}
return bus;
}

fn _tick(bus: Bus) Bus {
fn _tick(self: *Self, bus: Bus) Bus {
_ = self; // autofix
// FIXME
return bus;
}

fn irq(bus: Bus) Bus {
fn irq(self: *Self, bus: Bus) Bus {
_ = self; // autofix
// FIXME:
return bus;
}
Expand All @@ -246,6 +248,7 @@ pub fn Z80CTC(comptime P: Pins, comptime Bus: anytype) type {
chn.waiting_for_trigger = false;
chn.down_counter = chn.constant;
}
return bus;
}

// called when the downcounter reaches zero, request interrupt,
Expand All @@ -254,13 +257,13 @@ pub fn Z80CTC(comptime P: Pins, comptime Bus: anytype) type {
fn counterZero(chn: *Channel, in_bus: Bus, chn_id: usize) Bus {
var bus = in_bus;
// down counter has reached zero, trigger interrupt and ZCTO pin
if (chn.ctrl & CTRL.EI != 0) {
if (chn.control & CTRL.EI != 0) {
chn.irq_state |= IRQ.INT_NEEDED;
}
// last channel doesn't have a ZCTO pin
if (chn_id < 3) {
// set the zcto pin
bus |= ZCTO0 << chn_id;
bus |= ZCTO0 << @truncate(chn_id);
}
// reload the down counter
chn.down_counter = chn.constant;
Expand Down
45 changes: 45 additions & 0 deletions tests/z80ctc.test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,55 @@ const Pins = z80ctc.DefaultPins;
const Bus = u32;
const Z80CTC = z80ctc.Z80CTC(Pins, Bus);

const setData = Z80CTC.setData;
const CE = Z80CTC.CE;
const IORQ = Z80CTC.IORQ;
const CS0 = Z80CTC.CS0;
const CS1 = Z80CTC.CS1;
const ZCTO1 = Z80CTC.ZCTO1;

const CTRL = Z80CTC.CTRL;

test "init Z80CTC" {
const ctc = Z80CTC.init();
for (0..3) |i| {
try expect(ctc.chn[i].control & Z80CTC.CTRL.RESET != 0);
try expect(ctc.chn[i].prescaler_mask == 0x0F);
}
}

test "write int vector" {
var ctc = Z80CTC.init();
var bus = setData(CE | IORQ, 0xE0);
bus = ctc.tick(bus);
try expect(bus == setData(CE | IORQ, 0xE0));
try expect(ctc.chn[0].int_vector == 0xE0);
try expect(ctc.chn[1].int_vector == 0xE2);
try expect(ctc.chn[2].int_vector == 0xE4);
try expect(ctc.chn[3].int_vector == 0xE6);
}

test "timer" {
var ctc = Z80CTC.init();
const ctrl = CTRL.EI | CTRL.MODE_TIMER | CTRL.PRESCALER_16 | CTRL.TRIGGER_AUTO | CTRL.CONST_FOLLOWS | CTRL.CONTROL;
// write control word
var bus = ctc.tick(setData(CE | IORQ | CS0, ctrl));
try expect(ctc.chn[1].control == ctrl);
try expect(ctc.chn[1].prescaler_mask == 0x0F);
// write timer constant
bus = ctc.tick(setData(CE | IORQ | CS0, 10));
try expect(0 == ctc.chn[1].control & CTRL.CONST_FOLLOWS);
try expect(10 == ctc.chn[1].constant);
try expect(10 == ctc.chn[1].down_counter);
bus = 0;
for (0..3) |_| {
for (0..160) |tick| {
bus = ctc.tick(bus);
if (tick != 159) {
try expect(0 == bus & ZCTO1);
}
}
try expect(0 != bus & ZCTO1);
try expect(10 == ctc.chn[1].down_counter);
}
}

0 comments on commit 1a056c5

Please sign in to comment.