diff --git a/Visual Studio Projects/sigma.vcproj b/Visual Studio Projects/sigma.vcproj index e71d86363..e42fddbf4 100644 --- a/Visual Studio Projects/sigma.vcproj +++ b/Visual Studio Projects/sigma.vcproj @@ -205,10 +205,18 @@ RelativePath="..\sigma\sigma_coc.c" > + + + + diff --git a/Visual Studio Projects/sigma.vcxproj b/Visual Studio Projects/sigma.vcxproj index 45483478e..14583e326 100755 --- a/Visual Studio Projects/sigma.vcxproj +++ b/Visual Studio Projects/sigma.vcxproj @@ -240,7 +240,9 @@ + + diff --git a/makefile b/makefile index 456205098..79755eb24 100644 --- a/makefile +++ b/makefile @@ -2147,7 +2147,8 @@ SIGMA = ${SIGMAD}/sigma_cpu.c ${SIGMAD}/sigma_sys.c ${SIGMAD}/sigma_cis.c \ ${SIGMAD}/sigma_coc.c ${SIGMAD}/sigma_dk.c ${SIGMAD}/sigma_dp.c \ ${SIGMAD}/sigma_fp.c ${SIGMAD}/sigma_io.c ${SIGMAD}/sigma_lp.c \ ${SIGMAD}/sigma_map.c ${SIGMAD}/sigma_mt.c ${SIGMAD}/sigma_pt.c \ - ${SIGMAD}/sigma_rad.c ${SIGMAD}/sigma_rtc.c ${SIGMAD}/sigma_tt.c + ${SIGMAD}/sigma_rad.c ${SIGMAD}/sigma_rtc.c ${SIGMAD}/sigma_tt.c \ + ${SIGMAD}/sigma_cr.c ${SIGMAD}/sigma_cp.c SIGMA_OPT = -I ${SIGMAD} SEL32D = ${SIMHD}/SEL32 diff --git a/sigma/CMakeLists.txt b/sigma/CMakeLists.txt index 829936da4..3e17a9474 100644 --- a/sigma/CMakeLists.txt +++ b/sigma/CMakeLists.txt @@ -31,6 +31,8 @@ add_simulator(sigma sigma_rad.c sigma_rtc.c sigma_tt.c + sigma_cp.c + sigma_cr.c INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} LABEL sigma diff --git a/sigma/Design Notes on the Sigma 7.doc b/sigma/Design Notes on the Sigma 7.doc index 1a99ffaf2..8c03cf010 100644 Binary files a/sigma/Design Notes on the Sigma 7.doc and b/sigma/Design Notes on the Sigma 7.doc differ diff --git a/sigma/sigma_bugs.txt b/sigma/sigma_bugs.txt index 27ae7e321..829fe4ed4 100644 --- a/sigma/sigma_bugs.txt +++ b/sigma/sigma_bugs.txt @@ -114,36 +114,32 @@ 108. DP: TIO status routine always returns DVS_AUTO instead of proper status. 109. DP: DP_SEEK definition is off by 1. 110. DP: reset does not properly initialize controller, seek threads. -111. DP: device address must include unit identifier everywhere, for interrupt generation. -112. DK: device address must include unit identifier everywhere, for interrupt generation. -113. MT: device address must include unit identifier everywhere, for interrupt generation. -114: RAD: device address must include unit identifier everywhere, for interrupt generation. -115. MT: error handling not consistent. -116: IO: dangling else in write direct mode 1 code causes incorrect behavior. -117: CPU: sim_interval is decremented before breakpoint test, which is incorrect. -118. MT: revised error handling failed to set tape mark status on space file forward/reverse. -119. IO: UEND flag in the wrong bit position in status word. -120. DP: SEEK(I), RECAL(I) must be coded as fast operations. -121. COC: Transmit long space is 0x6, and stop transmit is 0xE. -122. COC: Received break generates a data-in channel transaction with a flag bit set +111. DP, DK, MT, RAD: device address must include unit identifier everywhere, for interrupt generation. +112. MT: error handling not consistent. +113: IO: dangling else in write direct mode 1 code causes incorrect behavior. +114: CPU: sim_interval is decremented before breakpoint test, which is incorrect. +115. MT: revised error handling failed to set tape mark status on space file forward/reverse. +116. IO: UEND flag in the wrong bit position in status word. +117. DP: SEEK(I), RECAL(I) must be coded as fast operations. +118. COC: Transmit long space is 0x6, and stop transmit is 0xE. +119. COC: Received break generates a data-in channel transaction with a flag bit set in the line number. -123. DP: dp_inv_adr error must set a TDV visible flag (i.e., PGE) before UEND. -124. IO, all devices: moved SIO reject-on-interrupt test to devices. -125. DP: SIO will knock down pending device interrupts and allow operation to proceed. -126. MT: AIO must mask unit number before calling TDV status. -127. IO: location 20/21 set incorrectly in the even, non-zero register case. -128. CPU: WAIT must be implemented for correct operation of CP-V. -129. DP: On 10 byte models, SENSE length errors can't happen. On 16 byte models, +120. DP: dp_inv_adr error must set a TDV visible flag (i.e., PGE) before UEND. +121. IO, all devices: moved SIO reject-on-interrupt test to devices. +122. DP: SIO will knock down pending device interrupts and allow operation to proceed. +123. MT: AIO must mask unit number before calling TDV status. +124. IO: location 20/21 set incorrectly in the even, non-zero register case. +125. CPU: WAIT must be implemented for correct operation of CP-V. +126. DP: On 10 byte models, SENSE length errors can't happen. On 16 byte models, SENSE length errors only occur if length == 0 || length > 16. -130. IO: DVT_NOTDEV macro incorrect. -131. DP: Test for non-existent device returns wrong status. -132. DK: Test for non-existent device returns wrong status. -133. MT: Test for non-existent device returns wrong status. -134. RAD: Test for non-existent device returns wrong status. -135. DP: TIO status should return non-operational for unattached device. -136. DK: TIO status should return non-operational for unattached device. -137. NT: TIO status should return non-operational for unattached device. -138. IO: Device mapping algorithm creates false dispatch points. +127. IO: DVT_NOTDEV macro incorrect. +128. DP, DK, MT, RAD: Test for non-existent device returns wrong status. +129. DP, DK, MT: TIO status should return non-operational for unattached device. +130. IO: Device mapping algorithm creates false dispatch points. +131. All devices: dispatch time to INIT state must be 0. +132. LPT: device must flag illegal commands in IDLE state. +133. COC: must flag 0xFF as illegal command in IDLE state. +134. IO: multiplexor channel implements a "chain modifier" capability, needed by punch. Diagnostic Notes ---------------- diff --git a/sigma/sigma_coc.c b/sigma/sigma_coc.c index e93aad6dc..5f0f1c788 100755 --- a/sigma/sigma_coc.c +++ b/sigma/sigma_coc.c @@ -1,6 +1,6 @@ /* sigma_coc.c: Sigma character-oriented communications subsystem simulator - Copyright (c) 2007-2022, Robert M Supnik + Copyright (c) 2007-2024, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,9 @@ coc 7611 communications multiplexor + 17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector) + Detect and UEN on 0xFF order + 15-Dec-22 RMS Moved SIO int pending test to devices 24-Aug-22 RMS Transmit long space is 0x6, not 0xD (Ken Rector) Added LNORDER modifier */ @@ -281,7 +284,7 @@ switch (op) { /* case on op */ *dvst |= (CC2 << DVT_V_CC); /* SIO fails */ else if ((*dvst & DVS_CST) == 0) { /* ctrl idle? */ muxc_cmd = MUXC_INIT; /* start dev thread */ - sim_activate (&mux_unit[MUXC], chan_ctl_time); + sim_activate (&mux_unit[MUXC], 0); } break; @@ -405,7 +408,11 @@ else { /* receive */ return 0; } -/* Unit service - channel overhead */ +/* Unit service - channel overhead + + The documentation says that the channel command is thrown away, + but the system exerciser requires a UEN on command 0xFF. +*/ t_stat muxc_svc (UNIT *uptr) { @@ -417,6 +424,10 @@ if (muxc_cmd == MUXC_INIT) { /* init state? */ if (CHS_IFERR (st)) /* channel error? */ mux_chan_err (st); /* go idle */ else muxc_cmd = MUXC_RCV; /* no, receive */ + if (cmd == 0xFF) { /* invalid cmd? */ + chan_uen (mux_dib.dva); /* uend */ + return SCPE_OK; + } } else if (muxc_cmd == MUXC_END) { /* end state? */ st = chan_end (mux_dib.dva); /* set channel end */ diff --git a/sigma/sigma_cp.c b/sigma/sigma_cp.c new file mode 100644 index 000000000..203b642ce --- /dev/null +++ b/sigma/sigma_cp.c @@ -0,0 +1,339 @@ +/* sigma_cp.c Sigma 7160 Card Punch + + Copyright (c) 2024, Ken Rector + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + KEN RECTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of Ken Rector shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Ken Rector. + + cp 7160 300 cpm card punch + + The 7160 card punch is described in the SDS Reference Manual, 900971A. + + The simulator writes 120 byte records to the cp attached output file. There + is no control or formatting meta data included in the file. + + Output requests in EBCDIC mode produce hollerith encoded card images. + Output in binary mode produces column binary card images. + + Capacity describes the number of punched cards in the outout stacker. This + accumulates indefinitely. It is not reset when the output file is detached. + +*/ + +#include "sigma_io_defs.h" +#include "sim_card.h" + + +/* Local unit Commands */ + +#define CPS_INIT 0x101 +#define CPS_STOP 0x00 /* stop*/ +#define CPS_PU01 0x01 /* punch binary normal */ +#define CPS_PU05 0x05 /* punch ebcdic normal */ +#define CPS_PU09 0x09 /* punch binary, error alternate */ +#define CPS_PU0D 0x0d /* punch ebcdic, error alternate */ +#define CPS_PU11 0x11 /* punch binary, alternate */ +#define CPS_PU15 0x15 /* punch ebcdic, alternate */ +#define CPS_PU19 0x19 /* punch binary, alternate */ +#define CPS_PU1D 0x1d /* punch ebcdic, alternate */ +#define CPS_STOPI 0x80 /* stop and interrupt */ + + +#define UST u3 /* unit status */ +#define UCMD u4 /* unit command */ + +#define LEN 120 /* output length */ + +#define DPS_UEN 0x04 /* unusual end occured */ + +char cp_buffer[LEN]; /* card output image */ +int32 cp_bptr = 0; /* buf ptr */ +int32 cp_row = 0; /* row counter */ +int32 cp_stacker1; +int32 cp_stacker2; + +uint32 cp_disp(uint32 fnc, uint32 inst, uint32 *dat); +uint32 cp_tio_status(void); +uint32 cp_tdv_status(void); +t_stat cp_chan_err (uint32 st); +t_stat cp_svc(UNIT *); +t_stat cp_reset (DEVICE *dptr); +t_stat cp_attach(UNIT * uptr, CONST char *file); +t_stat cp_detach(UNIT * uptr); +t_stat cp_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc); + +uint8 cp_op[] = { + 1, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1 +}; + + +extern uint32 chan_ctl_time; +extern uint16 ebcdic_to_hol[]; + +dib_t cp_dib = { DVA_CP, cp_disp, 0, NULL }; + +UNIT cp_unit = {UDATA(&cp_svc, UNIT_ATTABLE , 0), 2000 }; + +MTAB cp_mod[] = { + {MTAB_XTD | MTAB_VDV, 0, "CHANNEL", "CHANNEL", + &io_set_dvc,&io_show_dvc,NULL}, + { MTAB_XTD|MTAB_VDV, 0, "CAPACITY", NULL, + NULL, &cp_show_cap, NULL, "Punch stacker Count" }, + {0} +}; + +REG cp_reg[] = { + { BRDATA (BUFF, cp_buffer, 8, 8, sizeof(cp_buffer)/sizeof(*cp_buffer)), REG_HRO}, + { DRDATA (BPTR, cp_bptr, 18), PV_LEFT }, + { DRDATA (POS, cp_unit.pos, T_ADDR_W), PV_LEFT }, + { NULL } +}; + +DEVICE cp_dev = { + "CP", &cp_unit, cp_reg, cp_mod, + 1, 10, 31, 1, 16, 8, + NULL, NULL, &cp_reset, NULL, &cp_attach, &cp_detach, + &cp_dib, 0 +}; + +/* Card Punch : IO Dispatch rotine*/ + +uint32 cp_disp (uint32 op, uint32 dva, uint32 *dvst) { + + switch (op) { + + case OP_SIO: /* start I/O */ + *dvst = cp_tio_status (); /* get status */ + /* if automatic mode and ready */ + if ((*dvst & DVS_AUTO) && !sim_is_active(&cp_unit)) { + cp_unit.UCMD = CPS_INIT; /* start dev thread */ + cp_unit.UST = 0; + cp_row = 0; + sim_activate (&cp_unit, 0); + } + break; + + case OP_TIO: /* test status */ + *dvst = cp_tio_status (); /* return status */ + break; + + case OP_TDV: /* test status */ + *dvst = cp_tdv_status (); /* return status */ + break; + + case OP_HIO: /* halt I/O */ + chan_clr_chi (cp_dib.dva); /* clear int */ + *dvst = cp_tio_status (); /* get status */ + if ((*dvst & DVS_DST) != 0) { /* busy? */ + sim_cancel (&cp_unit); /* stop dev thread */ + cp_unit.UST = DPS_UEN; + chan_uen (cp_dib.dva); /* uend */ + cp_unit.UCMD = 0; /* ctlr idle */ + } + break; + + case OP_AIO: /* acknowledge int */ + chan_clr_chi (cp_dib.dva); /* clr int*/ + *dvst = 0; /* no status */ + break; + + default: + *dvst = 0; + return SCPE_IERR; + } + + return 0; +} + + +/* punch service */ +t_stat cp_svc(UNIT *uptr) { + uint32 cmd; + uint32 dva = cp_dib.dva; + uint32 st; + uint32 i; + uint32 c; + + if (uptr->UCMD == CPS_INIT) { /* init state? */ + st = chan_get_cmd (cp_dib.dva, &cmd); /* get order */ + if (CHS_IFERR (st)) + return cp_chan_err (st); + if ((cmd > 0x80) || + (cp_op[cmd] == 0)) { /* invalid order? */ + uptr->UST = DPS_UEN; + chan_uen (cp_dib.dva); /* report uend */ + return SCPE_OK; + } + uptr->UCMD = cmd; + sim_activate (uptr, chan_ctl_time); + return SCPE_OK; + } + + switch (uptr->UCMD) { + case CPS_PU01: + case CPS_PU05: + case CPS_PU09: + case CPS_PU0D: + case CPS_PU11: + case CPS_PU15: + case CPS_PU19: + case CPS_PU1D: + if (cp_row++ == 11) { /* last row? */ + memset(cp_buffer,0,sizeof(cp_buffer)); + if (uptr->UCMD & 0x4) { /* mode? */ + i = 0; /* ebcdic */ + while (i < LEN) { + unsigned short int col; + st = chan_RdMemB(dva,&c); + if (CHS_IFERR (st)) /* channel error? */ + return cp_chan_err (st); + col = ebcdic_to_hol[c]; /* byte and 1/2 */ + cp_buffer[i++] = (col >> 4) & 0xff; + cp_buffer[i] = (col & 0x0f) << 4; + if (st == CHS_ZBC) /* end request size? */ + break; + st = chan_RdMemB(dva,&c); + if (CHS_IFERR (st)) /* channel error? */ + return cp_chan_err (st); + col = ebcdic_to_hol[c]; /* 1/2 and byte */ + cp_buffer[i++] |= (col >> 8) & 0xf; + cp_buffer[i++] = (col & 0xff); + if (st == CHS_ZBC) /* end request size? */ + break; + } + } + else { + for (i = 0; i < LEN; i++) { /* Binary */ + st = chan_RdMemB(dva,&c); + if (CHS_IFERR (st)) /* channel error? */ + return cp_chan_err (st); + cp_buffer[i] = c; + if (st == CHS_ZBC) /* end request size? */ + break; + + } + } + sim_fwrite (cp_buffer, LEN, 1, uptr->fileref); + cp_stacker1++; + chan_set_cm (dva); /* set Chaining Modifier flag */ + } + st = chan_end (dva); + uptr->UCMD = CPS_INIT; + break; + case CPS_STOPI: + chan_set_chi(dva,CHI_END); /* interrupt */ + case CPS_STOP: + st = chan_end (dva); /* set channel end */ + if (CHS_IFERR (st)) /* channel error? */ + return cp_chan_err (st); + return SCPE_OK; /* done */ + } + sim_activate (uptr, chan_ctl_time); + return SCPE_OK; +} + +/* CP status routine */ + +uint32 cp_tio_status (void) +{ + uint32 st; + + st = cp_unit.flags & UNIT_ATT? DVS_AUTO: 0; /* AUTO : MANUAL */ + if (sim_is_active (&cp_unit)) /* dev busy? */ + st |= ( DVS_DBUSY | (CC2 << DVT_V_CC)); + st |= cp_unit.UST; /* uend? */ + return st; +} + +uint32 cp_tdv_status (void) +{ + + if (cp_unit.flags & UNIT_ATT) /* rdr att? */ + return cp_unit.UST; /* uend */ + return CC2 << DVT_V_CC; +} + +/* Channel error */ + +t_stat cp_chan_err (uint32 st) +{ + cp_unit.UST = DPS_UEN; + chan_uen (cp_dib.dva); /* uend */ + if (st < CHS_ERR) + return st; + return SCPE_OK; +} + +/* Reset routine */ + +t_stat cp_reset (DEVICE *dptr) +{ + + sim_cancel (&cp_unit); /* stop dev thread */ + cp_bptr = 0; + cp_row = 0; + chan_reset_dev (cp_dib.dva); /* clr int, active */ + return SCPE_OK; +} + +/* Attach routine */ + +t_stat cp_attach(UNIT * uptr, CONST char *cptr) { + + return (attach_unit(uptr, cptr)); +} + +t_stat cp_detach(UNIT * uptr) { + + return (detach_unit(uptr)); +} + + +t_stat cp_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc) { + int n; + + if ((n = cp_stacker1) == 0) + fprintf(st,"stacker empty"); + else { + if (n == 1) + fprintf(st,"1 card"); + else + fprintf(st,"%d cards",n); + fprintf(st," in stacker"); + } + return SCPE_OK; +} diff --git a/sigma/sigma_cr.c b/sigma/sigma_cr.c new file mode 100644 index 000000000..c518796cd --- /dev/null +++ b/sigma/sigma_cr.c @@ -0,0 +1,437 @@ +/* sigma_cr.c: Sigma 7120/7122/7140 card reader + + Copyright (c) 2024, Ken Rector + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + KEN RECTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of Ken Rector shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Ken Rector. + + cr 7120 card reader + + 27-Feb-2024 kenr Initial version + + The 7120, 7122 and 7140 card readers are described in the SDS + reference manual, 900970C. + + The simulator expects input data to be a file of 120 byte records with no control + or other extraneous data, to simulate a punched card deck. Each 120 byte record + is translated to 80 16 bit columns with data in the loworder 12 bits. In + automatic mode each column (1-1/2 bytes) is translated from a hollerith code + to an ebcdic character (1 byte). In binary mode each pair of columns is + translated to 3 data bytes. + + A length error in the input data will not be detected until the end of file + and results in an Invalid Length and Unusual End status. CPV sets the ignore + incorrect length flag so this can cause trouble in the symbiont input process. + + Card reader speed for the 7120, 7122 and 7140 machines was 400, 400 and 1500 + cards per minute respectively, or 150, 150 and 40 msec per card. The simulator + runs much faster than this, transmitting 80 columns in ~400 instruction cycles, + or 5 cycles per column. + + The cr device capacity indicates the number of cards in the hopper and stacker. + There is no limit on the number of records in the hopper or stacker. The + stacker is never emptied and the count can overflow. The hopper counter is + set when a file is attached and reduced as each card is read. + + The cardreader is detached from the input file when the hopper count + reaches zero. + + The card reader reports a Data Transmission Error if an incorrect EBCDIC character + is detected, (more than 1 punch in rows 1-7). + + */ + +#include +#include "sigma_io_defs.h" +#include "sim_card.h" + + +/* Unit status */ + +#define CDR_DTE 0x08 /* data error */ + +/* Device States */ + +#define CRS_INIT 0x101 /* feed card */ +#define CRS_END 0x102 /* end card */ + +#define UST u3 /* unit status */ +#define UCMD u4 /* unit command */ + +uint32 cr_bptr; /* buffer index */ +uint32 cr_blnt; /* buffer length */ +uint32 cr_col; /* current column */ +uint32 cr_hopper; /* hopper count */ +uint32 *cr_stkptr; /* selected stacker */ +uint32 cr_stacker = 0; /* stacker count */ +uint32 cr_stacker1 = 0; /* stacker 1 count */ +uint32 cr_stacker2 = 0; /* stacker 2 count */ +uint16 cr_buffer[80]; /* 80 column data */ +uint32 cr_ebcdic_init = 0; /* translate initial flag */ +uint16 hol_to_ebcdic[4096]; /* translation table */ + +uint8 cr_ord[] = { /* valid order codes*/ + 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0 +}; + +extern uint32 chan_ctl_time; +extern uint16 ebcdic_to_hol[]; + + +uint32 cr_disp (uint32 op, uint32 dva, uint32 *dvst); +t_stat cr_readrec (UNIT *uptr); +uint32 cr_tio_status (void); +uint32 cr_tdv_status (void); +t_stat cr_chan_err (uint32 st); +t_stat cr_svc (UNIT *uptr); +t_stat cr_reset (DEVICE *dptr); +t_stat cr_attach (UNIT *uptr, CONST char *cptr); +t_stat cr_detach (UNIT *uptr); +t_stat cr_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc); + + +dib_t cr_dib = { DVA_CR, cr_disp, 0, NULL }; + +UNIT cr_unit = { + UDATA(&cr_svc, UNIT_ATTABLE | UNIT_RO , 0), + 60 +}; + +REG cr_reg[] = { + { DRDATA (BPTR, cr_bptr, 17), PV_LEFT }, + { DRDATA (BLNT, cr_blnt, 17), PV_LEFT }, + { NULL } +}; + +MTAB cr_mod[] = { + {MTAB_XTD | MTAB_VDV, 0, "CHANNEL", "CHANNEL", + &io_set_dvc,&io_show_dvc,NULL}, + {MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", + &io_set_dva, &io_show_dva, NULL }, + {MTAB_XTD|MTAB_VDV, 0, "CAPACITY", NULL, + NULL, &cr_show_cap, NULL, "Card hopper size" }, + {0} +}; + +DEVICE cr_dev = { + "CR", &cr_unit, cr_reg, cr_mod, + 1, 10, 31, 1, 16, 8, + NULL, NULL, &cr_reset, &io_boot,&cr_attach,&cr_detach, + &cr_dib, 0 +}; + + +/* Card Reader : IO dispatch routine */ + +uint32 cr_disp (uint32 op, uint32 dva, uint32 *dvst) +{ + switch (op) { /* case on op */ + + case OP_SIO: /* start I/O */ + *dvst = cr_tio_status (); /* get status */ + if ((*dvst & DVS_AUTO) && !sim_is_active(&cr_unit)) { + cr_unit.UCMD = CRS_INIT; /* start dev thread */ + cr_stkptr = &cr_stacker; + sim_activate (&cr_unit, 0); + } + break; + + case OP_TIO: /* test status */ + *dvst = cr_tio_status (); /* return status */ + break; + + case OP_TDV: /* test status */ + *dvst = cr_tdv_status (); /* return status */ + break; + + case OP_HIO: /* halt I/O */ + chan_clr_chi (cr_dib.dva); /* clear int */ + *dvst = cr_tio_status (); + if ((*dvst & DVS_DST) != 0) { /* busy? */ + sim_cancel (&cr_unit); /* stop dev thread */ + chan_uen (cr_dib.dva); /* uend */ + } + break; + + case OP_AIO: /* acknowledge int */ + chan_clr_chi (cr_dib.dva); /* clr int*/ + *dvst = 0; /* no status */ + break; + + default: + *dvst = 0; + return SCPE_IERR; + } + + return 0; +} + +/* Service routine */ + +t_stat cr_svc (UNIT *uptr) +{ + uint32 cmd = uptr->UCMD; + t_stat st; + char c; + + if (cmd == CRS_INIT) { /* init state */ + st = chan_get_cmd (cr_dib.dva, &cmd); /* get order */ + if (CHS_IFERR (st)) /* bad device id, inactive state */ + return cr_chan_err (st); + if ((cmd > 0x3e) || /* invalid order? */ + (cr_ord[cmd] == 0)) { + chan_uen (cr_dib.dva); + return SCPE_OK; + } + uptr->UCMD = cmd; /* save order */ + cr_blnt = 0; /* empty buffer */ + cr_col = 0; /* initial column */ + switch (cmd & 0x30) { /* note stacker */ + case 0x10: + cr_stkptr = &cr_stacker1; + break; + case 0x30: + cr_stkptr = &cr_stacker2; + break; + default: + cr_stkptr = &cr_stacker; + break; + } + sim_activate (uptr, chan_ctl_time); + return SCPE_OK; + } + if (cmd == CRS_END) { /* end of card */ + st = chan_end (cr_dib.dva); /* set channel end, inactive */ + if (CHS_IFERR (st)) /* bad dev/inactive? */ + return cr_chan_err (st); + ++*cr_stkptr; /* add to stacker */ + if (--cr_hopper == 0) /* remove from hopper */ + cr_detach(uptr); /* end input deck */ + if (st == CHS_CCH) { /* command chain? */ + uptr->UCMD = CRS_INIT; /* restart thread */ + sim_activate (uptr, chan_ctl_time); + } + return SCPE_OK; + } + + if (cr_blnt == 0) { /* card arriving? */ + if (cr_readrec (uptr) == 0) { /* unexpected EOF, inv reclnt? */ + uptr->UCMD = CRS_END; /* end state */ + sim_activate (uptr, chan_ctl_time); /* sched ctlr */ + return SCPE_OK; + } + if ((cmd & 0x04) && /* mode change? */ + ((cr_buffer[0] & 0x180) == 0x180)) { + cmd &= ~0x04; /* automatic(EBCDIC) and row 1 2 */ + uptr->UCMD = cmd; /* switch to binary mode */ + } + } + if (cmd & 0x04) { /* mode? */ + int i = 0; /* invalid punches? */ + int n = cr_buffer[cr_bptr++] & 0x1fc; + c = (char) hol_to_ebcdic[cr_buffer[cr_bptr-1]]; /* automatic */ + while (n) { /* Kerninghams bit count alg */ + n &= (n-1); /* count bits in row 1-7 */ + i++; + } + if (i > 1) { /* >2 punches? */ + c = 0x00; /* return 0x00 */ + uptr->UST |= CDR_DTE; /* Transmission Data Error*/ + chan_set_chf (cr_dib.dva, CHF_XMDE); /* operational status byte */ + } + } + else { + switch (cr_col % 3) { /* binary */ + case 0: + c = ((cr_buffer[cr_bptr] >> 4) & 0xff); + break; + case 1: + c = ((cr_buffer[cr_bptr] & 0x0f) << 4); + cr_bptr++; + c |= ((cr_buffer[cr_bptr] & 0xf00) >> 8); + break; + case 2: + c = (cr_buffer[cr_bptr++] & 0xff); + break; + } + } + cr_col++; + st = chan_WrMemB (cr_dib.dva, c); /* write to memory */ + if (CHS_IFERR (st)) /* channel error? */ + return cr_chan_err (st); + if ((st != CHS_ZBC) && (cr_bptr != cr_blnt)) { /* not done? */ + sim_activate (uptr, chan_ctl_time); /* continue */ + return SCPE_OK; + } + if (((st == CHS_ZBC) ^ (cr_bptr == cr_blnt)) && /* length err? */ + chan_set_chf (cr_dib.dva, CHF_LNTE)) /* Incorrect Length */ + return SCPE_OK; /* to operational status byte */ + + uptr->UCMD = CRS_END; /* end state */ + sim_activate (uptr, chan_ctl_time); /* sched ctlr */ + return SCPE_OK; +} + + +/* get next record */ + +t_stat cr_readrec (UNIT *uptr) { + + int col; + FILE *fp = uptr->fileref; + + for (col = 0; col < 80; ) { + int16 i; + int c1, c2, c3; + + c1 = fgetc (fp); /* read 3 bytes */ + c2 = fgetc (fp); + c3 = fgetc (fp); + if (feof(fp) || (c1 == EOF) || (c2 == EOF) || (c3 == EOF)) { + cr_blnt = cr_bptr = 0; + chan_set_chf (cr_dib.dva, CHF_LNTE); + return 0; + } + i = ((c1 << 4) | ( c2 >> 4)) & 0xFFF; /* pack 1-1/2 bytes per column */ + cr_buffer[col] = i; + col++; + i = (((c2 & 017) << 8) | c3) & 0xFFF; + cr_buffer[col] = i; + col++; + } + cr_bptr = 0; + cr_blnt = 80; + return 80; +} + + +/* CR status routine */ + +uint32 cr_tio_status (void) +{ + uint32 st; + + st = (cr_unit.flags & UNIT_ATT) ? DVS_AUTO: 0; /* AUTO : MANUAL */ + if (sim_is_active (&cr_unit)) /* dev busy? */ + st |= ( DVS_CBUSY | DVS_DBUSY | (CC2 << DVT_V_CC)); + return st; +} + +uint32 cr_tdv_status (void) +{ + uint32 st; + + if (cr_unit.flags & UNIT_ATT && + (cr_hopper > 0)) /* rdr att? */ + st = cr_unit.UST; + else + st = (CC2 << DVT_V_CC); + return st; +} + +/* Channel error */ + +t_stat cr_chan_err (uint32 st) +{ + chan_uen (cr_dib.dva); + if (st < CHS_ERR) + return st; + return SCPE_OK; +} + +/* Reset routine */ + +t_stat cr_reset (DEVICE *dptr) +{ + int i; + if (!cr_ebcdic_init) { /* initialize translate table */ + for (i = 0; i < 4096; i++) + hol_to_ebcdic[i] = 0x100; /* a la sim_card */ + for (i = 0; i < 256; i++) { + uint16 temp = ebcdic_to_hol[i]; + if (hol_to_ebcdic[temp] != 0x100) { + fprintf(stderr, "Translation error %02x is %03x and %03x\n", + i, temp, hol_to_ebcdic[temp]); + } else { + hol_to_ebcdic[temp] = i; + } + } + cr_ebcdic_init = 1; + } + sim_cancel (&cr_unit); /* stop dev thread */ + chan_reset_dev (cr_dib.dva); /* clr int, active */ + return SCPE_OK; +} + +/* Attach routine */ + +t_stat cr_attach (UNIT *uptr, CONST char *cptr) +{ + char *saved_filename; + int r; + + saved_filename = uptr->filename; + uptr->filename = NULL; + if ((r = attach_unit(uptr, cptr)) != SCPE_OK) { + uptr->filename = saved_filename; + return r; + } + r = sim_fsize(uptr->fileref); + if ((r % 120) != 0) { /* multiple of 120 byte cards? */ + detach_unit(uptr); + fprintf(stderr,"CR file size error\n"); + return SCPE_IOERR; + } + cr_hopper = r / 120; + return SCPE_OK; +} + +/* Detach routine */ + +t_stat cr_detach (UNIT *uptr) +{ + cr_hopper = 0; + return detach_unit(uptr); +} + +t_stat cr_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc) { + + if (cr_hopper == 0) + fprintf(st,"hopper empty"); + else { + if (cr_hopper == 1) + fprintf(st,"1 card"); + else + fprintf(st,"%d cards",cr_hopper); + fprintf(st," in hopper"); + } + fprintf(st,"\nNormal Stacker %d\n",cr_stacker); + fprintf(st,"Alt Stacker 1 %d\n",cr_stacker1); + fprintf(st,"Alt Stacker 2 %d",cr_stacker2); + return SCPE_OK; +} diff --git a/sigma/sigma_dk.c b/sigma/sigma_dk.c index 7af0e75c7..379012d3c 100644 --- a/sigma/sigma_dk.c +++ b/sigma/sigma_dk.c @@ -25,6 +25,7 @@ dk 7250/7251-7252 cartridge disk + 17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector) 11-Feb-24 RMS Report non-operational if not attached (Ken Rector) 01-Feb-24 RMS Fixed nx unit test (Ken Rector) 15-Dec-22 RMS Moved SIO interrupt test to devices @@ -179,7 +180,7 @@ switch (op) { /* case on op */ *dvst |= (CC2 << DVT_V_CC); /* SIO fails */ else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ dk_cmd = DKS_INIT; /* start dev thread */ - sim_activate (&dk_unit[un], chan_ctl_time); + sim_activate (&dk_unit[un], 0); } break; diff --git a/sigma/sigma_dp.c b/sigma/sigma_dp.c index 861e69924..00e714a3f 100644 --- a/sigma/sigma_dp.c +++ b/sigma/sigma_dp.c @@ -25,6 +25,8 @@ dp moving head disk pack controller + 05-Apr-24 RMS Added case points for RDEES, CRIOF (Ken Rector) + 17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector) 11-Feb-24 RMS Report non-operational if not attached (Ken Rector) 01-Feb-24 RMS Fixed nx unit test (Ken Rector) 03-Jun-23 RMS Fixed SENSE length error detection (Ken Rector) @@ -623,7 +625,7 @@ switch (op) { /* case on op */ } if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ uptr->UCMD = DPS_INIT; /* start dev thread */ - sim_activate (uptr, chan_ctl_time); + sim_activate (uptr, 0); } break; @@ -883,6 +885,7 @@ switch (uptr->UCMD) { return SCPE_OK; /* err or cont */ break; + case DPS_RDEES: /* read */ case DPS_READ: /* read */ if (dp_inv_ad (uptr, &da)) { /* invalid addr? */ ctx->dp_flags |= DPF_PGE; @@ -934,6 +937,7 @@ switch (uptr->UCMD) { return SCPE_OK; break; + case DPS_CRIOF: /* cond rls intr */ case DPS_RSRV: /* reserve */ case DPS_RLS: /* release */ case DPS_RLSA: /* release */ diff --git a/sigma/sigma_io.c b/sigma/sigma_io.c index b33165fca..6759dff17 100644 --- a/sigma/sigma_io.c +++ b/sigma/sigma_io.c @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 19-Mar-2024 RMS Added chaining modifier flag (Ken Rector) 11-Feb-2024 RMS Fixed false dispatch bug (Ken Rector) 04-May-2023 RMS Fixed location 21 usage in even register case (Ken Rector) 15-Dec-2022 RMS Moved SIO interrupt test to devices diff --git a/sigma/sigma_io_defs.h b/sigma/sigma_io_defs.h index ecab6c657..639cd50c6 100644 --- a/sigma/sigma_io_defs.h +++ b/sigma/sigma_io_defs.h @@ -23,6 +23,9 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 19-Mar-24 RMS Added chaining modifier flag (Ken Rector) + 01-Feb-24 RMS Fixed DVT_NODEV definition (Ken Rector) + 15-Dec-22 RMS Added chan_chk_dvi definition 21-Jul-22 RMS Channel UEND flag in wrong bit position (Ken Rector) */ diff --git a/sigma/sigma_lp.c b/sigma/sigma_lp.c index 9a2106fcc..728d02ef2 100644 --- a/sigma/sigma_lp.c +++ b/sigma/sigma_lp.c @@ -1,6 +1,6 @@ /* sigma_lp.c: Sigma 7440/7450 line printer - Copyright (c) 2007-2021, Robert M. Supnik + Copyright (c) 2007-2024, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,9 @@ lp 7440/7445 or 7450 line printer + 18-Feb-2024 RMS Zero delay from SIO to INIT state (Ken Rector) + Added INIT test for illegal command (Ken Rector) + 15-Dec-2022 RMS Moved SIO interrupt test to devices 10-Jun-2021 RMS Removed use of ftell for pipe compatibility 09-Mar-2017 RMS Fixed unclosed file returns in CCT load (COVERITY) */ @@ -97,6 +100,24 @@ uint8 lp_to_ascii[64] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '#', '@', '\'', '=', '"' }; +static uint8 lp_valid_cmd[256] = { + 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0n */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4n */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; extern uint32 chan_ctl_time; @@ -184,7 +205,7 @@ switch (op) { /* case on op */ *dvst |= (CC2 << DVT_V_CC); /* SIO fails */ else if ((*dvst & DVS_DST) == 0) { /* idle? */ lp_cmd = LPS_INIT; /* start dev thread */ - sim_activate (&lp_unit, chan_ctl_time); + sim_activate (&lp_unit, 0); } break; @@ -232,6 +253,10 @@ switch (lp_cmd) { /* case on state */ st = chan_get_cmd (lp_dib.dva, &cmd); /* get command */ if (CHS_IFERR (st)) /* channel error? */ return lp_chan_err (st); + if (lp_valid_cmd[cmd] == 0) { /* bad command? */ + chan_uen (lp_dib.dva); /* uend */ + return SCPE_OK; + } lp_inh = 0; /* clear inhibit, */ lp_run = 0; /* runaway */ lp_cmd = lp_lastcmd = cmd; /* save command */ diff --git a/sigma/sigma_mt.c b/sigma/sigma_mt.c index 5ea3abeab..d6b08c17b 100644 --- a/sigma/sigma_mt.c +++ b/sigma/sigma_mt.c @@ -25,6 +25,7 @@ mt 7320 and 7322/7323 magnetic tape + 17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector) 11-Feb-24 RMS Report non-operational if not attached (Ken Rector) 01-Feb-24 RMS Fixed nx unit test (Ken Rector) 01-Nov-23 RMS Fixed reset not to clear BOT @@ -248,7 +249,7 @@ switch (op) { /* case on op */ *dvst |= (CC2 << DVT_V_CC); /* SIO fails */ else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ uptr->UCMD = MCM_INIT; /* start dev thread */ - sim_activate (uptr, chan_ctl_time); + sim_activate (uptr, 0); } break; diff --git a/sigma/sigma_pt.c b/sigma/sigma_pt.c index 3551115d8..0735de3ff 100644 --- a/sigma/sigma_pt.c +++ b/sigma/sigma_pt.c @@ -1,6 +1,6 @@ /* sigma_pt.c: Sigma 7060 paper tape reader/punch - Copyright (c) 2007-2018, Robert M. Supnik + Copyright (c) 2007-2024, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ pt 7060 paper-tape reader/punch + 17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector) + 15-Dec-2022 RMS Moved SIO interrupt test to devices 02-Jun-2018 RMS Defanged clang signed/unsigned whining (Mark Pizzolato) */ @@ -123,7 +125,7 @@ switch (op) { /* case on op */ *dvst |= (CC2 << DVT_V_CC); /* SIO fails */ else if ((*dvst & DVS_DST) == 0) { /* idle? */ pt_cmd = PTS_INIT; /* start dev thread */ - sim_activate (&pt_unit[PTR], chan_ctl_time); + sim_activate (&pt_unit[PTR], 0); } break; diff --git a/sigma/sigma_rad.c b/sigma/sigma_rad.c index 4556a6bfd..ab7869a30 100644 --- a/sigma/sigma_rad.c +++ b/sigma/sigma_rad.c @@ -1,6 +1,6 @@ /* sigma_rad.c: Sigma 7211/7212 or 7231/7232 fixed head disk simulator - Copyright (c) 2007-2022, Robert M Supnik + Copyright (c) 2007-2024, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,9 @@ rad 7211/7212 or 7231/7232 fixed head disk + 17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector) + 01-Feb-24 RMS Fixed nx unit test (Ken Rector) + 22-Apr-23 RMS Fixed write protect test (Ken Rector) 02-Jul-22 RMS Fixed bugs in multi-unit operation The RAD is a head-per-track disk. To minimize overhead, the entire RAD @@ -206,8 +209,10 @@ int32 iu; UNIT *uptr; if ((un >= RAD_NUMDR) || /* inv unit num? */ - (rad_unit[un].flags & UNIT_DIS)) /* disabled unit? */ - return DVT_NODEV; + (rad_unit[un].flags & UNIT_DIS)) { /* disabled unit? */ + *dvst = DVT_NODEV; + return 0; + } switch (op) { /* case on op */ case OP_SIO: /* start I/O */ @@ -216,7 +221,7 @@ switch (op) { /* case on op */ *dvst |= (CC2 << DVT_V_CC); /* SIO fails */ else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ rad_cmd = RADS_INIT; /* start dev thread */ - sim_activate (&rad_unit[un], chan_ctl_time); + sim_activate (&rad_unit[un], 0); } break; diff --git a/sigma/sigma_sys.c b/sigma/sigma_sys.c index 1d92f030e..c5254dfb4 100644 --- a/sigma/sigma_sys.c +++ b/sigma/sigma_sys.c @@ -1,6 +1,6 @@ /* sigma_sys.c: Sigma system interface - Copyright (c) 2007-2017, Robert M Supnik + Copyright (c) 2007-2024, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 03-Apr-2024 RMS Added CR, CP support (Ken Rector) 09-Mar-2017 RMS Added LOAD processor for CCT */ @@ -43,6 +44,8 @@ extern DEVICE rad_dev; extern DEVICE dk_dev; extern DEVICE dp_dev[]; extern DEVICE mt_dev; +extern DEVICE cr_dev; +extern DEVICE cp_dev; extern DEVICE mux_dev, muxl_dev; extern REG cpu_reg[]; extern uint32 *M; @@ -93,6 +96,8 @@ DEVICE *sim_devices[] = { &dp_dev[1], &mux_dev, &muxl_dev, + &cr_dev, + &cp_dev, NULL }; @@ -166,6 +171,73 @@ uint8 ebcdic_to_ascii[256] = { '8', '9', 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, }; +uint16 ebcdic_to_hol[256] = { + /* T918 T91 T92 T93 T94 T95 T96 T97 0x0x */ + 0xB03, 0x901, 0x881, 0x841, 0x821, 0x811, 0x809, 0x805, + /* T98, T189 , T289, T389, T489, T589, T689, T789 */ + 0x803, 0x903, 0x883, 0x843, 0x823, 0x813, 0x80B, 0x807, + /* TE189 E91 E92 E93 E94 E95 E96 E97 0x1x */ + 0xD03, 0x501, 0x481, 0x441, 0x421, 0x411, 0x409, 0x405, + /* E98 E918 E928 E938 E948 E958 E968 E978 */ + 0x403, 0x503, 0x483, 0x443, 0x423, 0x413, 0x40B, 0x407, + /* E0918 091 092 093 094 095 096 097 0x2x */ + 0x703, 0x301, 0x281, 0x241, 0x221, 0x211, 0x209, 0x205, + /* 098 0918 0928 0938 0948 0958 0968 0978 */ + 0x203, 0x303, 0x283, 0x243, 0x223, 0x213, 0x20B, 0x207, + /* TE0918 91 92 93 94 95 96 97 0x3x */ + 0xF03, 0x101, 0x081, 0x041, 0x021, 0x011, 0x009, 0x005, + /* 98 189 289 389 489 589 689 789 */ + 0x003, 0x103, 0x083, 0x043, 0x023, 0x013, 0x00B, 0x007, + /* T091 T092 T093 T094 T095 T096 T097 0x4x */ + 0x000, 0xB01, 0xA81, 0xA41, 0xA21, 0xA11, 0xA09, 0xA05, + /* T098 T18 T28 T38 T48 T58 T68 T78 */ + 0xA03, 0x902, 0x882, 0x842, 0x822, 0x812, 0x80A, 0x806, + /* T TE91 TE92 TE93 TE94 TE95 TE96 TE97 0x5x */ + 0x800, 0xD01, 0xC81, 0xC41, 0xC21, 0xC11, 0xC09, 0xC05, + /* TE98 E18 E28 E38 E48 E58 E68 E78 */ + 0xC03, 0x502, 0x482, 0x442, 0x422, 0x412, 0x40A, 0x406, + /* E 01 E092 E093 E094 E095 E096 E097 0x6x */ + 0x400, 0x300, 0x681, 0x641, 0x621, 0x611, 0x609, 0x605, + /* E098 018 TE 038 048 68 068 078 */ + 0x603, 0x302, 0xC00, 0x242, 0x222, 0x212, 0x20A, 0x206, + /* TE0 TE091 TE092 TE093 TE094 TE095 TE096 TE097 0x7x */ + 0xE00, 0xF01, 0xE81, 0xE41, 0xE21, 0xE11, 0xE09, 0xE05, + /* TE098 18 28 38 48 58 68 78 */ + 0xE03, 0x102, 0x082, 0x042, 0x022, 0x012, 0x00A, 0x006, + /* T018 T01 T02 T03 T04 T05 T06 T07 0x8x */ + 0xB02, 0xB00, 0xA80, 0xA40, 0xA20, 0xA10, 0xA08, 0xA04, + /* T08 T09 T028 T038 T048 T058 T068 T078 */ + 0xA02, 0xA01, 0xA82, 0xA42, 0xA22, 0xA12, 0xA0A, 0xA06, + /* TE18 TE1 TE2 TE3 TE4 TE5 TE6 TE7 0x9x */ + 0xD02, 0xD00, 0xC80, 0xC40, 0xC20, 0xC10, 0xC08, 0xC04, + /* TE8 TE9 TE28 TE38 TE48 TE58 TE68 TE78 */ + 0xC02, 0xC01, 0xC82, 0xC42, 0xC22, 0xC12, 0xC0A, 0xC06, + /* E018 E01 E02 E03 E04 E05 E06 E07 0xax */ + 0x702, 0x700, 0x680, 0x640, 0x620, 0x610, 0x608, 0x604, + /* E08 E09 E028 E038 E048 E058 E068 E078 */ + 0x602, 0x601, 0x682, 0x642, 0x622, 0x612, 0x60A, 0x606, + /* TE018 TE01 TE02 TE03 TE04 TE05 TE06 TE07 0xbx */ + 0xF02, 0xF00, 0xE80, 0xE40, 0xE20, 0xE10, 0xE08, 0xE04, + /* TE08 TE09 TE028 TE038 TE048 TE058 TE068 TE078 */ + 0xE02, 0xE01, 0xE82, 0xE42, 0xE22, 0xE12, 0xE0A, 0xE06, + /* T0 T1 T2 T3 T4 T5 T6 T7 0xcx */ + 0xA00, 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, + /* T8 T9 T0928 T0938 T0948 T0958 T0968 T0978 */ + 0x802, 0x801, 0xA83, 0xA43, 0xA23, 0xA13, 0xA0B, 0xA07, + /* E0 E1 E2 E3 E4 E5 E6 E7 0xdx */ + 0x600, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404, + /* E8 E9 TE928 TE938 TE948 TE958 TE968 TE978 */ + 0x402, 0x401, 0xC83, 0xC43, 0xC23, 0xC13, 0xC0B, 0xC07, + /* 028 E091 02 03 04 05 06 07 0xex */ + 0x282, 0x701, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204, + /* 08 09 E0928 E0938 E0948 E0958 E0968 E0978 */ + 0x202, 0x201, 0x683, 0x643, 0x623, 0x613, 0x60B, 0x607, + /* 0 1 2 3 4 5 6 7 0xfx */ + 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, + /* 8 9 TE0928 TE0938 TE0948 TE0958 TE0968 TE0978 */ + 0x002, 0x001, 0xE83, 0xE43, 0xE23, 0xE13, 0xE0B, 0xE07 +}; + /* Binary loader */ t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) diff --git a/sigma/sigma_tt.c b/sigma/sigma_tt.c index ed605c139..8ac801e4e 100644 --- a/sigma/sigma_tt.c +++ b/sigma/sigma_tt.c @@ -1,6 +1,6 @@ /* sigma_tt.c: Sigma 7012 console teletype - Copyright (c) 2007-2018, Robert M. Supnik + Copyright (c) 2007-2024, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -31,6 +31,8 @@ ^H input, mapped to EOM and not echoed HT input or output, simulates tabbing with fixed 8 character stops + 18-Feb-2024 RMS Zero delay from SIO to INIT state (Ken Rector) + 15-Dec-2022 RMS Moved SIO int pending test to devices 02-Jun-2018 RMS Defanged clang signed/unsigned whining (Mark Pizzolato) */ @@ -138,7 +140,7 @@ switch (op) { /* case on op */ *dvst |= (CC2 << DVT_V_CC); /* SIO fails */ else if ((*dvst & DVS_DST) == 0) { /* idle? */ tt_cmd = TTS_INIT; /* start dev thread */ - sim_activate (&tt_unit[TTO], chan_ctl_time); + sim_activate (&tt_unit[TTO], 0); } break;