From 4e76e43b40f93c2f5082ed421a5105256d1ee1d4 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Thu, 20 Sep 2018 00:11:45 -0400 Subject: [PATCH] ICL1900: Changes to get E6RM to load. --- ICL1900/icl1900_cp.c | 2 +- ICL1900/icl1900_cpu.c | 257 +++++++++++++++++++++++++++++++--------- ICL1900/icl1900_cr.c | 2 +- ICL1900/icl1900_defs.h | 1 + ICL1900/icl1900_lp.c | 4 +- ICL1900/icl1900_mt.c | 39 +++--- ICL1900/icl1900_stdio.c | 6 +- ICL1900/icl1900_sys.c | 72 ++++++++--- ICL1900/icl1900_tp.c | 16 ++- ICL1900/icl1900_tr.c | 18 ++- 10 files changed, 313 insertions(+), 104 deletions(-) diff --git a/ICL1900/icl1900_cp.c b/ICL1900/icl1900_cp.c index bf0afb5..cf00bbb 100644 --- a/ICL1900/icl1900_cp.c +++ b/ICL1900/icl1900_cp.c @@ -127,7 +127,7 @@ void cdp_cmd(int dev, uint32 cmd, uint32 *resp) { return; if (cmd == 020) { /* Send Q */ *resp = uptr->STATUS & TERMINATE; /* TERMINATE */ - if ((uptr->flags & UNIT_ATT) != 0 || uptr->STATUS & 07700) + if ((uptr->flags & UNIT_ATT) == 0 || (uptr->STATUS & 07700) == 0) *resp |= 040; if ((uptr->flags & BUSY) == 0) *resp |= STOPPED; diff --git a/ICL1900/icl1900_cpu.c b/ICL1900/icl1900_cpu.c index 87144e0..fcf46f4 100644 --- a/ICL1900/icl1900_cpu.c +++ b/ICL1900/icl1900_cpu.c @@ -31,6 +31,7 @@ */ #include "icl1900_defs.h" +#include #include "sim_timer.h" #define UNIT_V_MSIZE (UNIT_V_UF + 0) @@ -123,7 +124,6 @@ uint8 exe_mode = 1; /* Executive mode */ #define AM22 010 /* 22 bit addressing */ #define EXTRC 004 /* Executive trace mode */ /* 002 */ /* unused mode bit */ -#define ZERSUP 001 /* Zero suppression */ uint8 OIP; /* Obey instruction */ uint8 PIP; /* Pre Modify instruction */ uint8 OPIP; /* Saved Pre Modify instruction */ @@ -183,7 +183,7 @@ t_stat cpu_set_hist(UNIT * uptr, int32 val, CONST char *cptr, t_stat cpu_help(FILE *, DEVICE *, UNIT *, int32, const char *); /* Interval timer */ t_stat rtc_srv(UNIT * uptr); - +void time_read(uint32 *word); int32 rtc_tps = 60 ; int32 tmxr_poll = 10000; @@ -203,29 +203,29 @@ CPUMOD cpu_modtab[] = { { "1903S", MOD3S, TYPE_C2|FLOAT_STD|FLOAT_OPT|MULT_OPT|SV, EXT_IO, 10 }, { "1903T", MOD3T, TYPE_A2|FLOAT_STD|FLOAT_OPT|MULT_OPT|WG, 0, 10 }, { "1904", MOD4, TYPE_B2|FLOAT_OPT|MULT|WG, 0, 1 }, - { "1904A", MOD4A, TYPE_C2|FLOAT_OPT|MULT|WG, EXT_IO, 10 }, - { "1904E", MOD4E, TYPE_C2|FLOAT_OPT|MULT|WG, EXT_IO, 10 }, - { "1904F", MOD4F, TYPE_C2|FLOAT_OPT|MULT|WG, EXT_IO, 10 }, - { "1904S", MOD4S, TYPE_C2|FLOAT_OPT|MULT|WG, EXT_IO, 10 }, + { "1904A", MOD4A, TYPE_C2|FLOAT_OPT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1904E", MOD4E, TYPE_C2|FLOAT_OPT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1904F", MOD4F, TYPE_C2|FLOAT_OPT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1904S", MOD4S, TYPE_C2|FLOAT_OPT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, { "1905", MOD5, TYPE_A2|FLOAT|MULT|WG, 0, 1 }, - { "1905A", MOD5A, TYPE_A2|FLOAT|MULT|WG, 0, 10 }, - { "1905E", MOD5E, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1905F", MOD5F, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1905S", MOD5S, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1906", MOD6, TYPE_A2|FLOAT|MULT|WG, 0, 10 }, - { "1906A", MOD6A, TYPE_A2|FLOAT|MULT|WG, 0, 100 }, - { "1906E", MOD6E, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1906F", MOD6F, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1906S", MOD6S, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 100 }, - { "1907", MOD7, TYPE_A2|FLOAT|MULT|WG, 0, 10 }, - { "1907A", MOD7A, TYPE_A2|FLOAT|MULT|WG, 0, 10 }, - { "1907E", MOD7E, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1907F", MOD7F, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1907S", MOD7S, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1908", MOD8, TYPE_A2|FLOAT|MULT|WG, 0, 10 }, - { "1908A", MOD8A, TYPE_A2|FLOAT|MULT|WG, 0, 10 }, - { "1908S", MOD8S, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 10 }, - { "1909", MOD9, TYPE_C2|FLOAT|MULT|WG, EXT_IO, 1 }, + { "1905A", MOD5A, TYPE_A2|FLOAT|MULT|WG|SL_FLOAT, 0, 10 }, + { "1905E", MOD5E, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1905F", MOD5F, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1905S", MOD5S, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1906", MOD6, TYPE_A2|FLOAT|MULT|WG|SL_FLOAT, 0, 10 }, + { "1906A", MOD6A, TYPE_A2|FLOAT|MULT|WG|SL_FLOAT, 0, 100 }, + { "1906E", MOD6E, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1906F", MOD6F, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1906S", MOD6S, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 100 }, + { "1907", MOD7, TYPE_A2|FLOAT|MULT|WG|SL_FLOAT, 0, 10 }, + { "1907A", MOD7A, TYPE_A2|FLOAT|MULT|WG|SL_FLOAT, 0, 10 }, + { "1907E", MOD7E, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1907F", MOD7F, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1907S", MOD7S, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1908", MOD8, TYPE_A2|FLOAT|MULT|WG|SL_FLOAT, 0, 10 }, + { "1908A", MOD8A, TYPE_A2|FLOAT|MULT|WG|SL_FLOAT, 0, 10 }, + { "1908S", MOD8S, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 10 }, + { "1909", MOD9, TYPE_C2|FLOAT|MULT|WG|SL_FLOAT, EXT_IO, 1 }, { NULL, 0, 0, 0, 0}, }; @@ -347,6 +347,7 @@ uint8 Mem_test(uint32 addr) { uint8 Mem_read(uint32 addr, uint32 *data, uint8 flag) { addr &= M22; + SR1++; if (!exe_mode) { if (addr < 8) { *data = XR[addr]; @@ -449,9 +450,12 @@ intr: exe_mode = 1; loading = 0; /* Store registers */ - if (cpu_flags & FLOAT) { - Mem_write(RD+13, &facch, 0); /* Save F.P.U. */ + if (cpu_flags & FLOAT && cpu_flags & SL_FLOAT) { Mem_write(RD+12, &faccl, 0); + RT = facch; + if (fovr) + RT |= B0; + Mem_write(RD+13, &RT, 0); /* Save F.P.U. */ } RA = 0; /* Build ZSTAT */ if (cpu_flags & SV) { @@ -725,7 +729,7 @@ obey: case OP_STOZ: /* Store Zero */ /* Stevenage Machines */ - if ((cpu_flags & SV) != 0 && exe_mode) + if ((cpu_flags & SV) != 0 && exe_mode && RX != 0) XR[RX] = RA; RB = 0; BCarry = 0; @@ -1289,6 +1293,8 @@ branch: case OP_BFP1: if ((cpu_flags & FLOAT) == 0) goto voluntary; + if ((RX & 04) == 0 && fovr) + BV = 1; switch (RX & 06) { case 0: n = (faccl | facch) != 0; break; case 2: n = (faccl & B0) != 0; break; @@ -1777,7 +1783,7 @@ norm1: /* Sign of result */ if ((faccl & B0) != 0) n |= 4; -//fprintf(stderr, "FAD6: %08o %08o %08o %d %d\n\r", faccl, facch, RC, temp, temp2); +//fprintf(stderr, "FAD6: %08o %08o %08o %o\n\r", faccl, facch, RC, n); /* Result sign not equal same sign as addens */ if (n == 3 || n == 4) { if (faccl & 1) @@ -1788,8 +1794,10 @@ norm1: if ((n & 4) == 0) faccl |= B0; /* Set sign */ e1++; -//fprintf(stderr, "FAD6a: %08o %08o %08o %d %d\n\r", faccl, facch, RC, temp, temp2); +//fprintf(stderr, "FAD6a: %08o %08o %08o\n\r", faccl, facch, RC); } + if (n == 7) /* Handle minus with overflow */ + e1--; fn: /* Common normalize routine */ faccl &= FMASK; @@ -1828,7 +1836,7 @@ fn: facch &= M23; //fprintf(stderr, "FADr: %08o %08o %08o %03o %d\n\r", faccl, facch, RC, e1, e1); } -//fprintf(stderr, "FADR: %08o %08o %08o %03o %d\n\r", faccl, facch, RC, e1, temp2); +//fprintf(stderr, "FADR: %08o %08o %08o %03o\n\r", faccl, facch, RC, e1); } faccl &= FMASK; facch &= MMASK; @@ -2140,8 +2148,8 @@ fexp: } RA = facch; if (fovr) { - RA |= B0; - BV = 1; + RA |= B0; + BV = 1; if (!exe_mode && (Mode & 7) == 4) SR64 |= B2; } @@ -2153,23 +2161,93 @@ fexp: faccl = facch = fovr = 0; break; - case 0150: - case 0151: case 0160: /* Stevenage machines */ /* Load accumulators */ + if ((cpu_flags & SV) != 0 && exe_mode) { + /* Restore registers */ + for (n = 0; n < 8; n++) /* Restore user mode registers */ + Mem_read(RB+n, &XR[n], 0); + break; + } + /* Fall through */ + case 0161: /* Stevenage machines */ /* Store accumulators */ + if ((cpu_flags & SV) != 0 && exe_mode) { + /* Dump registers */ + for (n = 0; n < 8; n++) /* Restore user mode registers */ + Mem_write(RB+n, &XR[n], 0); + break; + } + /* Fall through */ + case 0162: /* Stevenage machines */ - case 0163: /* Stevenage machines */ /* Stope and Display */ + case 0163: /* Stevenage machines */ /* Stop and Display */ case 0164: /* Stevenage machines */ /* Search List N for Word X */ - case 0165: /* Stevenage machines */ /* Parity Search */ - if (exe_mode) { + if ((cpu_flags & SV) != 0 && exe_mode) { + RK = RB; + RB = XR[(RX+1) & 07] & adrmask; + do { + if (Mem_read(RA, &RT, 1)) { + goto intr; + } + RB++; + if (RA == RT) + BCarry = 1; + RK = (RK - 1) & 0777; + } while (RA != RT && RK != 0); + XR[(RX+1) & 07] = RB; break; } + /* Fall through */ + + case 0165: /* Stevenage machines */ /* Parity Search */ + if ((cpu_flags & SV) != 0 && exe_mode) { + RK = RB; + RB = XR[(RX+1) & 07] & adrmask; + do { + if (Mem_read(RA, &RT, 1)) { + goto intr; + } + RA++; + RB++; + RK = (RK - 1) & 0777; + } while (RK != 0); + XR[RX] = RA; + XR[(RX+1) & 07] = RB; + break; + } + /* Fall through */ + + case 0166: /* Stevenage machines */ /* Test X unequal */ + if ((cpu_flags & SV) != 0 && exe_mode) { + if (RA != RB) + BCarry = 1; + break; + } + /* Fall through */ + + case 0167: /* Stevenage machines */ /* Test X Less */ + if ((cpu_flags & SV) != 0 && exe_mode) { + RB += BCarry; + if (RB != RA) + BCarry = (RB > RA); + break; + } + + /* If we get here and not in executive mode do volintary */ + if (exe_mode) { + reason = SCPE_STOP; + break; + } + /* Fall through */ + case 0170: /* Read special register */ if (exe_mode) { RA = 0; switch(RB) { - case 0: /* Time of day clock */ break; - case 1: RA = SR1; break; + case 0: /* Time of day clock */ + time_read(&RA); + break; + case 1: RA = SR1; SR1 = 0; break; case 64: RA = SR64; SR64 &= 003777777; break; case 65: RA = SR65; break; default: if (RB < 64) @@ -2230,9 +2308,13 @@ fexp: Zero = 1; } RC &= (Mode & (EJM|AM22)) ? M22 : M15; - /* Restore floating point ACC from D12/D13 */ - Mem_read(RD+12, &faccl, 0); /* Restore F.P.U. */ - Mem_read(RD+13, &facch, 0); /* Restore F.P.U. */ + if (cpu_flags & FLOAT && cpu_flags & SL_FLOAT) { + /* Restore floating point ACC from D12/D13 */ + Mem_read(RD+12, &faccl, 0); /* Restore F.P.U. */ + Mem_read(RD+13, &facch, 0); /* Restore F.P.U. */ + fovr = (facch & B0) != 0; + facch &= M23; + } exe_mode = 0; break; } @@ -2267,6 +2349,22 @@ fexp: BCarry = 1; break; } + case 0140: + case 0141: + case 0142: + case 0143: + case 0144: + case 0145: + case 0146: + case 0147: + case 0150: + case 0151: + case 0152: + case 0153: + case 0154: + case 0155: + case 0156: + case 0157: default: /* Voluntary entry to executive */ voluntary: @@ -2277,36 +2375,49 @@ voluntary: if ((CPU_TYPE < TYPE_C1) && !exe_mode) RC += RD; exe_mode = 1; - /* Store registers */ - Mem_write(RD+13, &facch, 0); /* Save F.P.U. */ - Mem_write(RD+12, &faccl, 0); + if (cpu_flags & FLOAT && cpu_flags & SL_FLOAT) { + /* Store registers */ + Mem_write(RD+12, &faccl, 0); + RT = facch; + if (fovr) + RT |= B0; + Mem_write(RD+13, &RT, 0); /* Save F.P.U. */ + } if (CPU_TYPE >= TYPE_C1) { - Mem_read(RD+9, &RA, 0); - RA &= M15; + Mem_read(RD+9, &RT, 0); + RT &= M15; /* Build ZSTAT and ASTAT */ if (Zero) - RA |= B3; + RT |= B3; if (OPIP) - RA |= B2; - Mem_write(RD+9, &RA, 0); + RT |= B2; + Mem_write(RD+9, &RT, 0); } - RA = RC; + RT = RC; if (BV) - RA |= B0; + RT |= B0; if (BCarry) - RA |= B1; + RT |= B1; /* Type A & B */ if (CPU_TYPE < TYPE_C1 && Zero) - RA |= B8; - Mem_write(RD+8, &RA, 0); + RT |= B8; + Mem_write(RD+8, &RT, 0); for (n = 0; n < 8; n++) Mem_write(RD+n, &XR[n], 0); Zero = Mode = 0; BCarry = BV = 0; adrmask = M15; - XR[1] = RB; - XR[2] = temp; - RC = 040; + if ((cpu_flags & SV) != 0) { + if ((RF & 070) == 140 || (RF & 170) == 0110) + XR[1] = RD+RX; + XR[2] = RB; + XR[3] = RF & 07; + RC = 020 + ((RF >> 3) & 017); + } else { + XR[1] = RB; + XR[2] = temp; + RC = 040; + } break; } @@ -2330,9 +2441,37 @@ rtc_srv(UNIT * uptr) t = sim_rtcn_calb(rtc_tps, TMR_RTC); sim_activate_after(uptr, 1000000/rtc_tps); SR64 |= B3; -// tmxr_poll = t; return SCPE_OK; } + +int +bcd_2d(int n) +{ + uint8 d1, d2; + + d1 = n / 10; + d2 = n % 10; + return (d1 << 4) | d2; +} + +void +time_read(uint32 *word) +{ + time_t curtim; + struct tm *tptr; + int ms; + + curtim = time(NULL); /* get time */ + tptr = localtime(&curtim); /* decompose */ + if (tptr == NULL) + return; /* error? */ + + /* Convert and fill buffer */ + *word = bcd_2d(tptr->tm_sec); + *word |= bcd_2d(tptr->tm_min) << 7; + *word |= bcd_2d(tptr->tm_hour) << 14; + return; +} /* Reset routine */ t_stat diff --git a/ICL1900/icl1900_cr.c b/ICL1900/icl1900_cr.c index 21db71c..a41a6a3 100644 --- a/ICL1900/icl1900_cr.c +++ b/ICL1900/icl1900_cr.c @@ -138,7 +138,7 @@ void cdr_cmd(int dev, uint32 cmd, uint32 *resp) { return; if (cmd == 020) { /* Send Q */ *resp = uptr->STATUS & TERMINATE; /* Terminate */ - if ((uptr->flags & UNIT_ATT) != 0 || uptr->STATUS & 016) + if ((uptr->flags & UNIT_ATT) == 0 || (uptr->STATUS & 016) == 0) *resp |= 040; if ((uptr->STATUS & BUSY) == 0) *resp |= STOPPED; diff --git a/ICL1900/icl1900_defs.h b/ICL1900/icl1900_defs.h index 1c66a81..e72aa01 100755 --- a/ICL1900/icl1900_defs.h +++ b/ICL1900/icl1900_defs.h @@ -102,6 +102,7 @@ typedef struct _cpumod #define MULT 0400 /* Multiply/Divide installed */ #define SV 01000 /* Stevenage Machine */ #define WG 00000 /* West Gorton Machine */ +#define SL_FLOAT 02000 /* Store and load floating point registers */ /* Definitions for io_flags */ #define EXT_IO 0001 /* I/O channels at 256 and above */ diff --git a/ICL1900/icl1900_lp.c b/ICL1900/icl1900_lp.c index b4ee0c6..1511c8b 100644 --- a/ICL1900/icl1900_lp.c +++ b/ICL1900/icl1900_lp.c @@ -161,9 +161,7 @@ void lpr_cmd(int dev, uint32 cmd, uint32 *resp) { chan_clr_done(GET_UADDR(uptr->flags)); *resp = 5; } else if (cmd == SEND_Q) { - if ((uptr->flags & UNIT_ATT) != 0) - *resp = 040; - if (uptr->STATUS & 06) + if ((uptr->flags & UNIT_ATT) == 0 || (uptr->STATUS & 06) == 0) *resp = 040; *resp |= uptr->STATUS & TERMINATE; uptr->STATUS &= ~1; diff --git a/ICL1900/icl1900_mt.c b/ICL1900/icl1900_mt.c index f648abe..9e45b0d 100644 --- a/ICL1900/icl1900_mt.c +++ b/ICL1900/icl1900_mt.c @@ -173,8 +173,10 @@ void mt_cmd(int dev, uint32 cmd, uint32 *resp) { *resp |= STQ_TPT_RDY; if (!sim_tape_wrp(uptr)) *resp |= STQ_WRP; - if (uptr->STATUS & 07776 || (uptr->CMD & MT_BUSY) == 0) - *resp |= STQ_P1; +// if ((uptr->STATUS & 07776) == 0) + // *resp |= STQ_P1; + } else { + *resp |= STQ_P1; } chan_clr_done(dev); } else if (cmd == SEND_P) { @@ -182,10 +184,10 @@ void mt_cmd(int dev, uint32 cmd, uint32 *resp) { *resp = uptr->STATUS & 036; if ((uptr->CMD & MT_BUSY) == 0) *resp |= ST1_OK; - if (uptr->STATUS & 07700) + if (uptr->STATUS & 017700) *resp |= ST1_P2; } - uptr->STATUS &= 07700; + uptr->STATUS &= 017700; } else if (cmd == SEND_P2) { if ((uptr->flags & UNIT_ATT) != 0) *resp = (uptr->STATUS >> 6) & 077; @@ -256,11 +258,11 @@ t_stat mt_svc (UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, " error %d\n", r); uptr->STATUS = STQ_TERM; if (r == MTSE_TMK) - uptr->STATUS |= ST2_TM; + uptr->STATUS |= ST1_WARN; else if (r == MTSE_WRP) uptr->STATUS |= ST1_ERR; else if (r == MTSE_EOM) - uptr->STATUS |= ST1_WARN; + uptr->STATUS |= ST1_ERR|ST2_BLNK; else uptr->STATUS |= ST1_ERR; uptr->CMD = 0; @@ -293,7 +295,7 @@ t_stat mt_svc (UNIT *uptr) uptr->STATUS = (stop << 12) | STQ_TERM; if (uptr->POS < uptr->hwmark) uptr->STATUS |= ST1_LONG; - sim_debug(DEBUG_DATA, dptr, "unit=%d read done %08o\n", unit, uptr->STATUS); + sim_debug(DEBUG_DATA, dptr, "unit=%d read done %08o %d\n", unit, uptr->STATUS, uptr->POS); uptr->CMD = 0; mt_busy = 0; chan_set_done(dev); @@ -355,7 +357,7 @@ t_stat mt_svc (UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, " error %d\n", r); uptr->STATUS = STQ_TERM; if (r == MTSE_TMK) - uptr->STATUS |= ST2_TM; + uptr->STATUS |= ST1_WARN; else if (r == MTSE_EOM) uptr->STATUS |= ST1_WARN; else @@ -385,6 +387,7 @@ t_stat mt_svc (UNIT *uptr) uptr->STATUS = (stop << 12) |STQ_TERM; if (uptr->POS != 0) uptr->STATUS |= ST1_LONG; + sim_debug(DEBUG_DATA, dptr, "unit=%d read done %08o %d\n", unit, uptr->STATUS, uptr->POS); uptr->CMD = 0; mt_busy = 0; chan_set_done(dev); @@ -398,7 +401,7 @@ t_stat mt_svc (UNIT *uptr) case 0: sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d\n", unit); uptr->POS ++; - sim_activate(uptr, 500); + sim_activate(uptr, 1000); break; case 1: sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit); @@ -406,19 +409,21 @@ t_stat mt_svc (UNIT *uptr) if (r == MTSE_TMK) { uptr->POS++; sim_debug(DEBUG_DETAIL, dptr, "MARK\n"); - uptr->STATUS = ST2_TM; + uptr->STATUS = 000003; //ST2_TM; sim_activate(uptr, 50); } else if (r == MTSE_EOM) { uptr->POS++; - uptr->STATUS = ST1_WARN; + uptr->STATUS = ST1_ERR|ST2_BLNK|STQ_TERM; sim_activate(uptr, 50); } else { sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen); - sim_activate(uptr, 10 + (10 * reclen)); + sim_activate(uptr, 10 + (20 * reclen)); } break; case 2: sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d done\n", unit); +// M[257+4*dev] = 0; +// M[259+4*dev] = 0; uptr->CMD = 0; mt_busy = 0; chan_set_done(dev); @@ -464,11 +469,11 @@ t_stat mt_svc (UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit); r = sim_tape_sprecr(uptr, &reclen); if (r == MTSE_TMK) - uptr->STATUS = ST2_TM; + uptr->STATUS = ST1_WARN|STQ_TERM; else if (r == MTSE_BOT) - uptr->STATUS = ST1_WARN|ST1_ERR; + uptr->STATUS = ST1_WARN|STQ_TERM; else - uptr->STATUS = ST1_WARN; + uptr->STATUS = ST1_ERR|STQ_TERM; uptr->CMD = 0; mt_busy = 0; chan_set_done(dev); @@ -494,7 +499,7 @@ t_stat mt_svc (UNIT *uptr) if (r == MTSE_TMK || r == MTSE_BOT) { uptr->POS++; if (r == MTSE_TMK) - uptr->STATUS = ST2_TM; + uptr->STATUS = ST1_WARN|STQ_TERM; if (r == MTSE_BOT) uptr->STATUS = ST1_WARN|ST1_ERR; sim_activate(uptr, 50); @@ -505,6 +510,8 @@ t_stat mt_svc (UNIT *uptr) break; case 2: uptr->CMD = 0; + M[257+4*dev] = 0; + M[259+4*dev] = 0; mt_busy = 0; chan_set_done(dev); } diff --git a/ICL1900/icl1900_stdio.c b/ICL1900/icl1900_stdio.c index 9c94f33..285e038 100644 --- a/ICL1900/icl1900_stdio.c +++ b/ICL1900/icl1900_stdio.c @@ -250,9 +250,10 @@ get_ccw(int dev, uint32 *addr, uint8 type) { if (type & WORD_DEV) cw0 |= WORDCCW; if (cw0 & WORDCCW) { - if (cw0 & BACKWARD) + if (cw0 & BACKWARD) { cw1 = ((cw1 + M22) & M22) | (cw1 & CMASK); - else + *addr = cw1; + } else cw1 = ((cw1 + 1) & M22) | (cw1 & CMASK); } else { if (cw0 & BACKWARD) { @@ -261,6 +262,7 @@ get_ccw(int dev, uint32 *addr, uint8 type) { } else { cw1 = ((cw1 - 1) & M22) | CMASK; } + *addr = cw1; } else { if ((cw1 & CMASK) == CMASK) { cw1 = (cw1 + 1) & M22; diff --git a/ICL1900/icl1900_sys.c b/ICL1900/icl1900_sys.c index eb325cf..d98133b 100755 --- a/ICL1900/icl1900_sys.c +++ b/ICL1900/icl1900_sys.c @@ -231,7 +231,48 @@ sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag) uint8 image[80]; int checksum; - if (match_ext(fnam, "card")) { + if (match_ext(fnam, "wush")) { + while (fgets(buffer, 100, fileref)) { + char *p = &buffer[0]; + /* Convert bits into image */ + if (*p++ != '*') { + fprintf(stderr, "Buffer %s\n", buffer); + return SCPE_FMT; + } + addr = 0; + while (*p != '\0') { + if (*p == ':') + break; + if (*p < '0' || *p > '7') { + break; + } + addr = (addr << 3) | (*p++ - '0'); + } + while (*p != '*') { + if (*p == '\0' || *p == '\n') { + fprintf(stderr, "Buffer %s\n", buffer); + return SCPE_FMT; + } + p++; + } + p++; + data = 0; + while (*p != '\0') { + if (*p < '0' || *p > '7') + break; + data = (data << 3) | (*p++ - '0'); + } + if (addr == 077777777) { + RC = data; + break; + } + if (addr < 8) + XR[addr] = data; + M[addr] = data; + } + return SCPE_OK; + + } else if (match_ext(fnam, "card")) { fgets(buffer, 100, fileref); addr = 020; @@ -241,14 +282,15 @@ sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag) for (j = 0; j < 80; j++) { if (buffer[j] == '\n') break; - image[j] = ascii_to_mem[buffer[j]]; + if ((buffer[j] & 0377) == 0243) + image[j] = 024; + else + image[j] = ascii_to_mem[buffer[j]]; if (image[j] < 0) { - fprintf(stderr, "Char %c: %s", buffer[j], buffer); + fprintf(stderr, "Char %c: %s\n", buffer[j], buffer); return SCPE_FMT; } - fprintf(stderr, "'%c' %02o ", buffer[j], image[j]); } - fprintf(stderr, "\n\r"); for (j = 0; j < 64; ) { data = 0; for (k = 0; k < 4; k++) @@ -267,7 +309,10 @@ sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag) for (j = 0; j < 80; j++) { if (buffer[j] == '\n') break; - image[j] = ascii_to_mem[buffer[j]]; + if ((buffer[j] & 0377) == 0243) + image[j] = 024; + else + image[j] = ascii_to_mem[buffer[j]]; if (image[j] < 0) { fprintf(stderr, "Char %c: %s", buffer[j], buffer); return SCPE_FMT; @@ -285,20 +330,19 @@ sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag) addr = 0; for (; j < 8; j++) addr = (addr << 6) | image[j]; - checksum += addr; + checksum = (checksum + addr) & FMASK; for (i = 3; i < image[1]; i++) { data = 0; for (k = 0; k < 4; k++) data = (data << 6) | image[j++]; - checksum += data; + checksum = (checksum + data) & FMASK; M[addr++] = data; } data = 0; for (k = 0; k < 4; k++) data = (data << 6) | image[j++]; - data = FMASK & (checksum + data); - if (data != 0) - fprintf(stderr, "Check %08o %08o: %s", addr, data, buffer); + if ((FMASK & (checksum + data)) != 0) + fprintf(stderr, "Check %08o %08o %08o: %s", addr, data, checksum, buffer); break; case 1: fprintf(stderr, "%c%c%c%c\n", buffer[4], buffer[5], buffer[6], buffer[7]); @@ -311,14 +355,14 @@ sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag) addr = 0; for (; j < 8; j++) addr = (addr << 6) | image[j]; - checksum += addr; + checksum = (checksum + addr) & FMASK; RC = addr; data = 0; for (i = 3; i < image[1]; i++) { data = 0; for (k = 0; k < 4; k++) data = (data << 6) | image[j++]; - checksum += data; + checksum = (checksum + data) & FMASK; } for (k = 0; k < 4; k++) data = (data << 6) | image[j++]; @@ -335,8 +379,6 @@ sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag) fprintf(stderr, "B? :%s", buffer); return SCPE_FMT; } -// if (load_rec(image)) - // return SCPE_OK; } return SCPE_OK; } diff --git a/ICL1900/icl1900_tp.c b/ICL1900/icl1900_tp.c index 7761b61..8a84455 100644 --- a/ICL1900/icl1900_tp.c +++ b/ICL1900/icl1900_tp.c @@ -32,8 +32,8 @@ #endif #define PP_V_MODE (UNIT_V_UF + 0) -#define PP_M_MODE (1 << PP_V_MODE) -#define UNIT_V_TYPE (UNIT_V_UF + 1) +#define PP_M_MODE (3 << PP_V_MODE) +#define UNIT_V_TYPE (UNIT_V_UF + 2) #define UNIT_TYPE (0xf << UNIT_V_TYPE) #define GET_TYPE(x) ((UNIT_TYPE & (x)) >> UNIT_V_TYPE) #define SET_TYPE(x) (UNIT_TYPE & ((x) << UNIT_V_TYPE)) @@ -42,6 +42,7 @@ #define SI_TYPE(x) ((GET_TYPE(x) & 1) != 0) #define PP_MODE_7B 0 #define PP_MODE_7P 1 +#define PP_MODE_7X 2 #define CMD u3 #define STATUS u4 @@ -124,6 +125,7 @@ UNIT ptp_unit[] = { MTAB ptp_mod[] = { { PP_M_MODE, PP_MODE_7B, "7b", "7B", NULL }, { PP_M_MODE, PP_MODE_7P, "7p", "7P", NULL }, + { PP_M_MODE, PP_MODE_7X, "7x", "7X", NULL }, { UNIT_TYPE, SET_TYPE(T1925_1), "1925/1", "1925/1", NULL, NULL, "ICL 1925/1 NSI 300CPM punch."}, { UNIT_TYPE, SET_TYPE(T1925_2), "1925/2", "1925/2", NULL, NULL, "ICL 1922/2 SI 300CPM punch."}, { UNIT_TYPE, SET_TYPE(T1926_1), "1926/1", "1926/1", NULL, NULL, "ICL 1926/1 NSI 1000CPM punch."}, @@ -206,7 +208,7 @@ void ptp_cmd(int dev, uint32 cmd, uint32 *resp) { if ((uptr->CMD & BUSY) != 0) *resp |= 030; } - if ((uptr->STATUS & ERROR) != 0) + if ((uptr->STATUS & ERROR) == 0) *resp |= 040; } else if (cmd == 024) { /* Send P */ if ((uptr->flags & UNIT_ATT) != 0) @@ -407,7 +409,14 @@ t_stat ptp_svc (UNIT *uptr) ch = ch ^ (ch << 2); ch = ch ^ (ch << 1); data |= ch; + } else if ((uptr->flags & PP_M_MODE) == PP_MODE_7X) { + if (data == 044) { + data = 0243; + } else if (data == 0174) { + data = 044; + } } + fputc(data, uptr->fileref); uptr->pos = ftell(uptr->fileref); if (ferror (uptr->fileref)) { @@ -451,6 +460,7 @@ t_stat ptp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cpt fprintf (st, "The Paper Tape Punch can be set to one of two modes: 7P, or 7B\n\n"); fprintf (st, " 7P Generate even parity tapes.\n"); fprintf (st, " 7B Generate 7 bit tapes.\n"); + fprintf (st, " 7X Generate translated 7 bit tapes\n"); fprintf (st, "The default mode is 7B.\n\n"); fprintf (st, "The device number can be set with DEV=# command.\n"); diff --git a/ICL1900/icl1900_tr.c b/ICL1900/icl1900_tr.c index 5e3927a..6b185c7 100644 --- a/ICL1900/icl1900_tr.c +++ b/ICL1900/icl1900_tr.c @@ -34,8 +34,8 @@ #if (NUM_DEVS_PTR > 0) #define PP_V_MODE (UNIT_V_UF + 0) -#define PP_M_MODE (1 << PP_V_MODE) -#define UNIT_V_TYPE (UNIT_V_UF + 1) +#define PP_M_MODE (3 << PP_V_MODE) +#define UNIT_V_TYPE (UNIT_V_UF + 2) #define UNIT_TYPE (0xf << UNIT_V_TYPE) #define GET_TYPE(x) ((UNIT_TYPE & (x)) >> UNIT_V_TYPE) #define SET_TYPE(x) (UNIT_TYPE & ((x) << UNIT_V_TYPE)) @@ -44,6 +44,7 @@ #define SI_TYPE(x) ((GET_TYPE(x) & 1) != 0) #define PP_MODE_7B 0 #define PP_MODE_7P 1 +#define PP_MODE_7X 2 #define CMD u3 #define STATUS u4 @@ -128,6 +129,7 @@ UNIT ptr_unit[] = { MTAB ptr_mod[] = { { PP_M_MODE, PP_MODE_7B, "7b", "7B", NULL }, { PP_M_MODE, PP_MODE_7P, "7p", "7P", NULL }, + { PP_M_MODE, PP_MODE_7X, "7x", "7X", NULL }, { UNIT_TYPE, SET_TYPE(T1915_1), "1915/1", "1915/1", NULL, NULL, "ICL 1915/1 NSI 300CPM reader."}, { UNIT_TYPE, SET_TYPE(T1915_2), "1915/2", "1915/2", NULL, NULL, "ICL 1912/2 SI 300CPM reader."}, { UNIT_TYPE, SET_TYPE(T1916_1), "1916/1", "1916/1", NULL, NULL, "ICL 1916/1 NSI 1000CPM reader."}, @@ -203,12 +205,12 @@ void ptr_cmd(int dev, uint32 cmd, uint32 *resp) { case 020: if (cmd == 020) { /* Send Q */ *resp = uptr->STATUS & TERMINATE; - if ((uptr->flags & UNIT_ATT) != 0) { + if ((uptr->flags & UNIT_ATT) == 0) { *resp = 040; if ((uptr->CMD & BUSY) == 0) *resp |= 030; } - if ((uptr->STATUS & ERROR) != 0) + if ((uptr->STATUS & ERROR) == 0) *resp |= 040; sim_debug(DEBUG_STATUS, &ptr_dev, "STATUS: %03o %03o\n", cmd, *resp); uptr->STATUS &= ~TERMINATE; @@ -384,6 +386,12 @@ t_stat ptr_svc (UNIT *uptr) if (ch != 0) uptr->STATUS = TERMINATE | ERROR; chan_set_done(dev); + } else if ((uptr->flags & PP_M_MODE) == PP_MODE_7X) { + if (data == 0243) { + data = 044; + } else if (data == 044) { + data = 0174; + } } data &= 0177; if ((data == 0 || data == 0177) && (uptr->CMD & IGN_BLNK) != 0) { @@ -414,6 +422,7 @@ t_stat ptr_svc (UNIT *uptr) ch = 060 | (data & 017); break; } + sim_debug(DEBUG_DATA, &ptr_dev, "xlt: '%c' %03o\n", data, ch); } else { switch (data & 0160) { case 0000: @@ -542,6 +551,7 @@ t_stat ptr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cpt fprintf (st, "The Paper Tape Reader can be set to one of two modes: 7P, or 7B\n\n"); fprintf (st, " 7P Process even parity input tapes. \n"); fprintf (st, " 7B Ignore parity of input data.\n"); + fprintf (st, " 7X Ignore parity and translate British Pound to correct character\n"); fprintf (st, "The default mode is 7B.\n\n"); fprintf (st, "The device number can be set with DEV=# command.\n"); return SCPE_OK;