From c1904b50ced20d2423d5134e95fa1a174375a6a5 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Mon, 2 Jun 2025 12:57:07 +0200 Subject: [PATCH] Imlac: Model MSB and LSB accumulators. --- imlac/imlac_dp.c | 81 +++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/imlac/imlac_dp.c b/imlac/imlac_dp.c index 1fbf5fea..dc928f1e 100644 --- a/imlac/imlac_dp.c +++ b/imlac/imlac_dp.c @@ -35,7 +35,8 @@ static uint16 SP = 0; static uint16 ON = 0; static uint16 HALT = 0; static uint16 MODE = 0; -static uint16 XA, YA; +static uint16 XMSB, YMSB; +static uint16 XLSB, YLSB; static uint16 SCALE = 2; static uint16 BLOCK = 0; static uint16 MIT8K; @@ -68,8 +69,10 @@ static REG dp_reg[] = { { ORDATAD (MODE, MODE, 1, "Display mode") }, { BRDATAD (DT, DT, 8, 16, 8, "Return address stack") }, { ORDATAD (SP, SP, 3, "Stack pointer") }, - { ORDATAD (XA, XA, 11, "X accumulator") }, - { ORDATAD (YA, YA, 11, "Y accumulator") }, + { ORDATAD (XMSB, XMSB, 7, "X accumulator MSB") }, + { ORDATAD (XLSB, XLSB, 5, "X accumulator LSB") }, + { ORDATAD (YMSB, YMSB, 7, "Y accumulator MSB") }, + { ORDATAD (YLSB, YLSB, 5, "Y accumulator LSB") }, { ORDATAD (SCALE, SCALE, 3, "Scale") }, { ORDATAD (BLOCK, BLOCK, 3, "Block") }, { ORDATAD (MIT8K, MIT8K, 1, "MIT 8K addressing") }, @@ -167,6 +170,25 @@ dp_iot (uint16 insn, uint16 AC) return AC; } +static uint16 deflect (uint16 msb, uint16 lsb) +{ + return (msb << 5) + lsb; +} + +static void increment (uint16 *msb, uint16 *lsb, uint16 x) +{ + *lsb += SCALE * x; + *msb += *lsb >> 5; + *lsb &= 037; +} + +static void decrement (uint16 *msb, uint16 *lsb, uint16 x) +{ + *lsb -= SCALE * x; + *msb += ((int16)*lsb) >> 5; + *lsb &= 037; +} + static t_stat dp_opr(uint16 insn) { @@ -204,7 +226,7 @@ dp_opr(uint16 insn) } if (insn & 00020) { /* DDSP */ sim_debug (DBG, &dp_dev, "DDSP "); - crt_point (XA, YA); + crt_point (deflect (XMSB, XLSB), deflect (YMSB, YLSB)); } if (insn & 00040) { /* DRJM */ sim_debug (DBG, &dp_dev, "DRJM "); @@ -215,19 +237,19 @@ dp_opr(uint16 insn) } if (insn & 00100) { /* DDYM */ sim_debug (DBG, &dp_dev, "DDYM "); - YA -= 040; + YMSB--; } if (insn & 00200) { /* DDXM */ sim_debug (DBG, &dp_dev, "DDXM "); - XA -= 040; + XMSB--; } if (insn & 00400) { /* DIYM */ sim_debug (DBG, &dp_dev, "DIYM "); - YA += 040; + YMSB++; } if (insn & 01000) { /* DIXM */ sim_debug (DBG, &dp_dev, "DIXM "); - XA += 040; + XMSB++; } if (insn & 02000) { /* DHVC */ sim_debug (DBG, &dp_dev, "DHVC "); @@ -296,7 +318,7 @@ dp_opt (uint16 insn) static void dp_inc_vector (uint16 byte) { - uint16 x1 = XA, y1 = YA; + uint16 x1 = deflect (XMSB, XLSB), y1 = deflect (YMSB, YLSB); uint16 dx, dy; if (byte == 0200) { @@ -311,19 +333,18 @@ dp_inc_vector (uint16 byte) sim_debug (DBG, &dp_dev, "%o", byte & 3); } - dx = SCALE * ((byte >> 3) & 3); - dy = SCALE * (byte & 3); + dx = (byte >> 3) & 3; + dy = byte & 3; if (byte & 040) - XA -= dx; + decrement (&XMSB, &XLSB, dx); else - XA += dx; + increment (&XMSB, &XLSB, dx); if (byte & 4) - YA -= dy; + decrement (&YMSB, &YLSB, dy); else - YA += dy; + increment (&YMSB, &YLSB, dy); if (byte & 0100) - crt_line (x1, y1, XA, YA); - + crt_line (x1, y1, deflect (XMSB, XLSB), deflect (YMSB, YLSB)); } static void @@ -347,15 +368,15 @@ dp_inc_escape (uint16 byte) sim_debug (DBG, &dp_dev, "stack underflow"); } if (byte & 020) - XA += 040; + XMSB++; if (byte & 010) - XA &= 03740; + XLSB = 0; if (byte & 4) /* Enter PPM mode. */ ; if (byte & 2) - YA += 040; + YMSB++; if (byte & 1) - YA &= 03740; + YLSB = 0; } static void @@ -382,7 +403,7 @@ dp_deim (uint16 insn) static void dp_dlvh (uint16 insn1, uint16 insn2, uint16 insn3) { - uint16 x1 = XA, y1 = YA; + uint16 x1 = deflect (XMSB, XLSB), y1 = deflect (YMSB, YLSB); uint16 m, n, dx, dy; m = insn2 & 07777; n = insn3 & 07777; @@ -394,15 +415,15 @@ dp_dlvh (uint16 insn1, uint16 insn2, uint16 insn3) dy = n; } if (insn3 & 040000) - XA -= SCALE * dx; + decrement (&XMSB, &XLSB, dx); else - XA += SCALE * dx; + increment (&XMSB, &XLSB, dx); if (insn3 & 020000) - YA -= SCALE * dy; + decrement (&YMSB, &YLSB, dy); else - YA += SCALE * dy; + increment (&YMSB, &YLSB, dy); if (insn2 & 020000) - crt_line (x1, y1, XA, YA); + crt_line (x1, y1, deflect (XMSB, XLSB), deflect (YMSB, YLSB)); } static void @@ -414,11 +435,13 @@ dp_insn (uint16 insn) break; case 1: /* DLXA */ sim_debug (DBG, &dp_dev, "DLXA\n"); - XA = (insn & 01777) << 1; + XMSB = (insn >> 4) & 0077; + XLSB = (insn << 1) & 0036; break; case 2: /* DLYA */ sim_debug (DBG, &dp_dev, "DLYA\n"); - YA = (insn & 01777) << 1; + YMSB = (insn >> 4) & 0077; + YLSB = (insn << 1) & 0036; break; case 3: /* DEIM */ sim_debug (DBG, &dp_dev, "DEIM ");