From c6a602f2c9de02b2a1e18800c0d7488316a722bb Mon Sep 17 00:00:00 2001 From: "Howard M. Harte" Date: Wed, 23 Nov 2022 20:43:23 -0800 Subject: [PATCH] AltairZ80: SIO: Support 32-bits for setFCBAddressCmd. The M68K requires more than 16-bits for the FCB address. Expand to 32-bits. --- AltairZ80/altairz80_sio.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/AltairZ80/altairz80_sio.c b/AltairZ80/altairz80_sio.c index b1e1e501..76ea6e00 100644 --- a/AltairZ80/altairz80_sio.c +++ b/AltairZ80/altairz80_sio.c @@ -1768,19 +1768,45 @@ static int32 simh_out(const int32 port, const int32 data) { } break; case setFCBAddressCmd: - if (setFCBAddressPos == 0) { + /* SETFCBADDR command always takes four bytes: + * Byte Z80 8086 68000 32-Bit Address Space (future) + * ---- ----- ----- ----- ----------------------------- + * 1 A7:0 A7:0 A7:0 A7:0 + * 2 A15:8 A15:8 A15:8 A15:8 + * 3 0 DS A23:16 A23:16 + * 4 0 0 0 A31:24 + * For 8086, the FCB address is updated by writing the fourth + * byte, using the offset A15:0 from the first two bytes and + * taking the segment from the CPU's DS register. + */ + switch (setFCBAddressPos) { + case 0: /* Address 7:0 */ FCBAddress = data; - setFCBAddressPos = 1; - } - else { + setFCBAddressPos++; + break; + case 1: /* Address 15:8 */ FCBAddress |= (data << 8); + setFCBAddressPos++; + break; + case 2: /* Address 23:16 */ + FCBAddress |= (data << 16); + setFCBAddressPos++; + break; + default: /* Address 31:24 */ if (chiptype == CHIP_TYPE_8086) { + /* Mask the offset to 16-bits and add in the segment from DS register. */ setViewRegisters(); + FCBAddress &= 0xFFFF; FCBAddress += (DS_S << 4); sim_debug(CMD_MSG, &simh_device, "SIMH: " ADDRESS_FORMAT " FCBAddress=0x%05x, DS=0x%04x\n", PCX, FCBAddress, DS_S); + } else { + FCBAddress |= (data << 24); + sim_debug(CMD_MSG, &simh_device, "SIMH: " ADDRESS_FORMAT + " FCBAddress=0x%08x\n", PCX, FCBAddress); } setFCBAddressPos = lastCommand = 0; + break; } break; @@ -1919,6 +1945,8 @@ static int32 simh_out(const int32 port, const int32 data) { markTimeSP = 0; lastCommand = 0; deleteNameList(); + setFCBAddressPos = 0; + FCBAddress = CPM_FCB_ADDRESS; break; case showTimerCmd: /* show time difference to timer on top of stack */