diff --git a/SDS/sds_cp.c b/SDS/sds_cp.c new file mode 100644 index 00000000..4ec439fd --- /dev/null +++ b/SDS/sds_cp.c @@ -0,0 +1,318 @@ +/* sds_cp.c - SDS-930 Card Punch + + Copyright (c) 2020, 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. + + 03-Mar-20 kenr Initial Version + +*/ + +/* + This card punch simulator uses sim_card.c to write output records + in CBN format. Data is passed directly to sim_card.c when binary + mode is specified by the buffer control EOM. When BCD mode is + specified by the EOM, output data is translated into Hollerith code + from SDS Internal Code as defined by the SDS 930 Computer Reference Manual + + The SDS card punch protocol defined by the 930 Computer Reference manual + specifies that the output image be sent to the buffer 12 times, once + for each row. In this simulator the card image is only written after + termination (TOP) of the twelfth image output. + + The Symbol assembler punch routine uses the PBT (Punch Buffer Test) + before issueing a connect EOM to determine if it needs to write 12 rows + per card, or just 1. To make Symbol work right we always return TRUE, + (skip) for this test. + + I can't find anything in the computer reference manuals that describes + how this should work. Why did Symbol do this? + + */ + + +#include "sds_defs.h" +#include "sim_card.h" + +#define CARD_IN_PUNCH 00004000 /* Card ready to punch */ + +#define STATUS u3 + +extern uint32 xfr_req; +extern int32 stop_invins, stop_invdev, stop_inviop; + +uint16 cp_buffer[80]; /* card output image */ +int32 cp_bptr = 0; /* buf ptr */ +int32 cp_blnt = 0; /* buf length */ +int32 cp_row = 0; /* row counter */ +int32 cp_chr = 0; +int32 cp_eor; +int32 cp_inst; /* saved instr */ + +t_stat cp_devio(uint32 fnc, uint32 inst, uint32 *dat); +t_stat cp_svc(UNIT *); +t_stat cp_attach(UNIT * uptr, CONST char *file); +t_stat cp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +t_stat cp_detach(UNIT * uptr); +t_stat cp_wrend(UNIT * uptr); +t_stat cp_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +void cp_set_err (UNIT *uptr); + + + +DSPT cp_tplt[] = { { 1, 0 }, { 0, 0 } }; /* template */ + +DIB cp_dib = { CHAN_W, DEV_CP, XFR_CP, cp_tplt, &cp_devio }; + +UNIT cp_unit = {UDATA(&cp_svc, UNIT_ATTABLE , 0), 2000 }; + +MTAB cp_mod[] = { + {MTAB_XTD | MTAB_VDV, 0, "CHANNEL", "CHANNEL", + &set_chan, &show_chan, + NULL, "Device Channel"}, + {MTAB_XTD | MTAB_VDV, 0, "FORMAT", "FORMAT", + &sim_card_set_fmt, &sim_card_show_fmt, + NULL,"Card Format"}, + { MTAB_XTD|MTAB_VDV, 0, "CAPACITY", NULL, + NULL, &cp_show_cap, NULL, "Stacker Count" }, + {0} +}; + +REG cp_reg[] = { + { BRDATA (BUFF, cp_buffer, 16, 16, sizeof(cp_buffer)/sizeof(*cp_buffer)), REG_HRO}, + { DRDATA (BPTR, cp_bptr, 18), PV_LEFT }, + { DRDATA (BLNT, cp_blnt, 18), PV_LEFT }, + { FLDATA (XFR, xfr_req, XFR_V_CP) }, + { ORDATA (INST, cp_inst, 24) }, + { DRDATA (POS, cp_unit.pos, T_ADDR_W), PV_LEFT }, + { NULL } +}; + +DEVICE cp_dev = { + "CP", &cp_unit, cp_reg, cp_mod, + 1, 8, 15, 1, 8, 8, + NULL, NULL, NULL, NULL, &cp_attach, &cp_detach, + &cp_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, NULL, + NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* Convert SDS BCD character into hollerith code */ + +uint16 sdsbcd_to_hol(uint8 bcd) { + uint16 hol; + + /* Handle space correctly */ + if (bcd == 0) /* 0 to row 10 */ + return 0x200; + if (bcd == 060) /* 60 no punch */ + return 0; + + /* Convert to top column */ + switch (bcd & 060) { + default: + case 000: + hol = 0x000; /* no zone */ + break; + case 020: + hol = 0x800; /* 0x200 row 12 */ + break; + case 040: + hol = 0x400; /* row 11 */ + break; + case 060: + hol = 0x200; /* row 10 */ + break; + } + + /* Convert to 0-9 row */ + bcd &= 017; + if (bcd > 9) { + hol |= 0x2; /* row 8 */ + bcd -= 8; + } + if (bcd != 0) + hol |= 1 << (9 - bcd); + return hol; +} + +t_stat cp_devio(uint32 fnc, uint32 inst, uint32 *dat) { + UNIT *uptr = &cp_unit; + int32 new_ch; + uint8 chr; + t_stat r; + uint32 t; + + switch (fnc) { + case IO_CONN: + new_ch = I_GETEOCH (inst); /* get new chan */ + if (new_ch != cp_dib.chan) /* wrong chan? err */ + return SCPE_IERR; + if (sim_is_active(uptr)) + CRETIOP; + if (uptr->flags & UNIT_ATT) { + cp_inst = inst; + cp_blnt = 0; + cp_bptr = 0; + xfr_req = xfr_req & ~XFR_CP; /* clr xfr flag */ + sim_activate (uptr, uptr->wait); /* start timer */ + } + else { + cp_set_err (uptr); /* no, err, disc */ + CRETIOP; + } + break; + case IO_EOM1: /* I/O Control EOM */ + break; + case IO_DISC: /* disconnect TOP */ + xfr_req = xfr_req & ~XFR_CP; /* clr xfr flag */ + cp_row++; + if (cp_row >= 12) { + if ((r = cp_wrend(uptr)) != SCPE_OK) + return r; + uptr->STATUS &= ~CARD_IN_PUNCH; + } + sim_cancel (uptr); /* deactivate unit */ + break; + case IO_WREOR: /* write eor */ + break; + case IO_SKS: + new_ch = I_GETSKCH (inst); /* get chan # */ + if (new_ch != cp_dib.chan) /* wrong chan? */ + return SCPE_IERR; + t = I_GETSKCND (inst); /* get skip cond */ + switch (t) { /* case sks cond */ + case 010: /* sks 12046 */ + // PBT + // /* skip if punch buffer empty */ + *dat = 1; + break; + case 020: /* sks 14046 */ + // CPT + /* skip if punch is ready to accept connection */ + if ((uptr->flags & UNIT_ATT) && + !(uptr->STATUS & CARD_IN_PUNCH)) + *dat = 1; + break; + } + break; + case IO_WRITE: + if (!(uptr->STATUS & CARD_IN_PUNCH)) + break; + chr = (*dat) & 077; + xfr_req = xfr_req & ~XFR_CP; /* clr xfr flag */ + if (cp_bptr < cp_blnt) { + if (cp_inst & 01000) { + if (cp_chr & 1) /* column binary */ + cp_buffer[cp_bptr++] |= chr; + else + cp_buffer[cp_bptr] = (chr << 6); + cp_chr++; + } + else { + cp_buffer[cp_bptr++] = sdsbcd_to_hol(chr); /* bcd */ + } + chan_set_ordy (cp_dib.chan); + } + break; + case IO_READ: + CRETINS; + } + + return SCPE_OK; +} + + +/* punch service */ +t_stat cp_svc(UNIT *uptr) { + + uptr->STATUS |= CARD_IN_PUNCH; + cp_bptr = 0; + cp_blnt = 80; + cp_chr = 0; + chan_set_ordy (cp_dib.chan); + return SCPE_OK; +} + +t_stat cp_wrend(UNIT * uptr) { + t_stat st; + + st = sim_punch_card(uptr, cp_buffer); + cp_row = 0; + if (st != CDSE_OK) { + cp_set_err(uptr); + return SCPE_IOERR; + } + uptr->STATUS = 0; + return SCPE_OK; +} + +/* Fatal error */ +void cp_set_err (UNIT *uptr) +{ + chan_set_flag (cp_dib.chan, CHF_EOR | CHF_ERR); /* eor, error */ + chan_disc (cp_dib.chan); /* disconnect */ + xfr_req = xfr_req & ~XFR_CP; /* clear xfr */ + sim_cancel (uptr); /* stop */ + cp_bptr = 0; /* buf empty */ + return; +} + +t_stat cp_attach(UNIT * uptr, CONST char *cptr) { + t_stat r; + + sim_card_set_fmt (uptr,0,"CBN",NULL); + if ((r = sim_card_attach(uptr, cptr)) != SCPE_OK) + return r; + cp_row = 0; + return SCPE_OK; +} + +t_stat cp_detach(UNIT * uptr) { + + if (uptr->STATUS & CARD_IN_PUNCH) + sim_punch_card(uptr, cp_buffer); + return sim_card_detach(uptr); +} + +/* Channel assignment routines */ + +t_stat cp_set_chan (UNIT *uptr, int32 val, CONST char *sptr, void *desc) +{ + t_stat r; + r = set_chan (uptr, val, sptr, desc); + return r; +} + +t_stat cp_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc) { + int n; + + if ((n = sim_card_output_hopper_count(uptr)) == 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/SDS/sds_cpu.c b/SDS/sds_cpu.c index 8acda63e..d942e27c 100644 --- a/SDS/sds_cpu.c +++ b/SDS/sds_cpu.c @@ -200,10 +200,11 @@ int32 rtc_tps = 60; /* rtc ticks/sec */ t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_reset (DEVICE *dptr); -t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_set_type (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc); +t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs); +t_stat cpu_set_size (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat cpu_set_type (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat cpu_set_hist (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat Ea (uint32 wd, uint32 *va); t_stat EaSh (uint32 wd, uint32 *va); t_stat Read (uint32 va, uint32 *dat); @@ -222,8 +223,8 @@ void inst_hist (uint32 inst, uint32 pc, uint32 typ); t_stat rtc_inst (uint32 inst); t_stat rtc_svc (UNIT *uptr); t_stat rtc_reset (DEVICE *dptr); -t_stat rtc_set_freq (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, void *desc); +t_stat rtc_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc); extern t_bool io_init (void); extern t_stat op_wyim (uint32 inst, uint32 *dat); @@ -440,8 +441,8 @@ while (reason == 0) { /* loop until halted */ if (btyp) { if (btyp & SWMASK ('E')) /* unqualified breakpoint? */ reason = STOP_IBKPT; /* stop simulation */ - // else if (btyp & BRK_TYP_DYN_STEPOVER) /* stepover breakpoint? */ - // reason = STOP_DBKPT; /* stop simulation */ + else if (btyp & BRK_TYP_DYN_STEPOVER) /* stepover breakpoint? */ + reason = STOP_DBKPT; /* stop simulation */ else switch (btyp) { /* qualified breakpoint */ case SWMASK ('M'): /* monitor mode */ reason = STOP_MBKPT; /* stop simulation */ @@ -453,6 +454,7 @@ while (reason == 0) { /* loop until halted */ reason = STOP_UBKPT; /* stop simulation */ break; } + sim_interval++; /* don't count non-executed instruction */ break; } } @@ -1531,9 +1533,126 @@ if (pcq_r) else return SCPE_IERR; sim_brk_dflt = SWMASK ('E'); sim_brk_types = SWMASK ('E') | SWMASK ('M') | SWMASK ('N') | SWMASK ('U'); +sim_vm_is_subroutine_call = cpu_is_pc_a_subroutine_call; return SCPE_OK; } +/* For Next command, determine if should use breakpoints + to step over a subroutine branch or POP or SYSPOP. Return + TRUE if so with a list of addresses where dynamic (temporary) + breakpoints should be set. +*/ +typedef enum Next_Case { /* Next Next Atomic Next Forward */ + Next_BadOp = 0, /* FALSE FALSE FALSE */ + Next_Branch, /* FALSE EA FALSE */ + Next_BRM, /* P+1,P+2,P+3 EA+1,P+1,P+2,P+3 P+1,P+2,P+3 */ + Next_BRX, /* FALSE EA,P+1 P+1 */ + Next_Simple, /* FALSE P+1 P+1 */ + Next_POP, /* P+1,P+2 100+OP,P+1,P+2 P+1,P+2 */ + Next_Skip, /* P+1,P+2 P+1,P+2 P+1,P+2 */ + Next_EXU /* ?? ?? ?? */ +} Next_Case; + +Next_Case Op_Cases[64] = { + Next_BadOp, Next_Branch, Next_Simple, Next_BadOp, /* HLT BRU EOM ... */ + Next_BadOp, Next_BadOp, Next_Simple, Next_BadOp, /* ... ... EOD ... */ + Next_Simple, Next_Branch, Next_Simple, Next_Simple, /* MIY BRI MIW POT */ + Next_Simple, Next_BadOp, Next_Simple, Next_Simple, /* ETR ... MRG EOR */ + Next_Simple, Next_BadOp, Next_Simple, Next_EXU, /* NOP ... ROV EXU */ + Next_BadOp, Next_BadOp, Next_BadOp, Next_BadOp, /* ... ... ... ... */ + Next_Simple, Next_BadOp, Next_Simple, Next_Simple, /* YIM ... WIM PIN */ + Next_BadOp, Next_Simple, Next_Simple, Next_Simple, /* ... STA STB STX */ + Next_Skip, Next_BRX, Next_BadOp, Next_BRM, /* SKS BRX ... BRM */ + Next_BadOp, Next_BadOp, Next_Simple, Next_BadOp, /* ... ... RCH ... */ + Next_Skip, Next_Branch, Next_Skip, Next_Skip, /* SKE BRR SKB SKN */ + Next_Simple, Next_Simple, Next_Simple, Next_Simple, /* SUB ADD SUC ADC */ + Next_Skip, Next_Simple, Next_Simple, Next_Simple, /* SKR MIN XMA ADM */ + Next_Simple, Next_Simple, Next_Simple, Next_Simple, /* MUL DIV RSH LSH */ + Next_Skip, Next_Simple, Next_Skip, Next_Skip, /* SKM LDX SKA SKG */ + Next_Skip, Next_Simple, Next_Simple, Next_Simple }; /* SKD LDB LDA EAX */ + +t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs) +{ +static t_addr returns[10]; +uint32 inst; +Next_Case op_case; +int32 atomic, forward; +t_addr *return_p; +uint32 va; +int32 exu_cnt = 0; + +*ret_addrs = return_p = returns; +atomic = sim_switches & SWMASK('A'); +forward = sim_switches & SWMASK('F'); + +if (Read (P, &inst) != SCPE_OK) /* get instruction */ + return FALSE; + +Exu_Loop: +if (I_POP & inst) { /* determine inst case */ + if ((inst & ((I_M_OP << I_V_OP) | I_USR)) == 047000000) + op_case = Next_BRM; /* Treat SBRM like BRM */ + else + op_case = Next_POP; + } +else + op_case = Op_Cases[I_GETOP(inst)]; + +switch (op_case) { + case Next_BadOp: + break; + case Next_BRM: + *return_p++ = (P + 1) & VA_MASK; + *return_p++ = (P + 2) & VA_MASK; + *return_p++ = (P + 3) & VA_MASK; + if (atomic) { + if (Ea (inst, &va) != SCPE_OK) + return FALSE; + *return_p++ = (va + 1) & VA_MASK; + } + break; + case Next_Branch: + if (atomic) { + if (Ea (inst, &va) != SCPE_OK) + return FALSE; + *return_p++ = va & VA_MASK; + } + break; + case Next_BRX: + if (atomic) { + if (Ea (inst, &va) != SCPE_OK) + return FALSE; + *return_p++ = va & VA_MASK; + } + /* -- fall through to Next_Simple case -- */ + case Next_Simple: + if (atomic || forward) + *return_p++ = (P + 1) & VA_MASK; + break; + case Next_POP: + if (atomic) + *return_p++ = 0100 + I_GETOP(inst); + /* -- fall through to Next_Skip case -- */ + case Next_Skip: + *return_p++ = (P + 1) & VA_MASK; + *return_p++ = (P + 2) & VA_MASK; + break; + case Next_EXU: /* execute inst at EA */ + if (++exu_cnt > exu_lim) /* too many? */ + return FALSE; + if (Ea (inst, &va) != SCPE_OK) /* decode eff addr */ + return FALSE; + if (Read (va, &inst) != SCPE_OK) /* get operand */ + return FALSE; + goto Exu_Loop; + } +if (return_p == returns) /* if no cases added, */ + return FALSE; /* return FALSE */ +else + *return_p = (t_addr)0; /* else append terminator */ +return TRUE; /* and return TRUE */ +} + /* Memory examine */ t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) @@ -1567,7 +1686,7 @@ return SCPE_OK; /* Set memory size */ -t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) +t_stat cpu_set_size (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { int32 mc = 0; uint32 i; @@ -1586,7 +1705,7 @@ return SCPE_OK; /* Set system type (1 = Genie, 0 = standard) */ -t_stat cpu_set_type (UNIT *uptr, int32 val, char *cptr, void *desc) +t_stat cpu_set_type (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { extern t_stat drm_reset (DEVICE *dptr); extern DEVICE drm_dev, mux_dev, muxl_dev; @@ -1664,7 +1783,7 @@ return SCPE_OK; /* Set frequency */ -t_stat rtc_set_freq (UNIT *uptr, int32 val, char *cptr, void *desc) +t_stat rtc_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { if (cptr) return SCPE_ARG; @@ -1676,7 +1795,7 @@ return SCPE_OK; /* Show frequency */ -t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, void *desc) +t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc) { fprintf (st, (rtc_tps == 50)? "50Hz": "60Hz"); return SCPE_OK; @@ -1703,7 +1822,7 @@ return; /* Set history */ -t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc) +t_stat cpu_set_hist (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { int32 i, lnt; t_stat r; @@ -1742,15 +1861,14 @@ return SCPE_OK; /* Show history */ -t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc) +t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, CONST void *desc) { int32 ov, k, di, lnt; -char *cptr = (char *) desc; +CONST char *cptr = (CONST char *) desc; t_stat r; -extern t_value *sim_eval; InstHistory *h; -static char *cyc[] = { " ", " ", "INT", "TRP" }; -static char *modes = "NMU?"; +static const char *cyc[] = { " ", " ", "INT", "TRP" }; +static const char *modes = "NMU?"; if (hst_lnt == 0) /* enabled? */ return SCPE_NOFNC; diff --git a/SDS/sds_cr.c b/SDS/sds_cr.c new file mode 100644 index 00000000..06ea3483 --- /dev/null +++ b/SDS/sds_cr.c @@ -0,0 +1,381 @@ +/* sds_cr.c: SDS-930 card reader simulator + + Copyright (c) 2020, 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. + + 03-Mar-20 kenr Initial Version + + */ + +/* + This card reader simulator uses sim_card.c to attach and read input records + in CBN format. When BCD mode is specified by the buffer control EOM, input data + is translated from the Hollerith encoded data in the card columns to the + SDS Internal Code as defined by the SDS 930 Computer Reference Manual. The + translation function was modified from the sim_card.c code to provide SDS + Internal BCD codes. + + The card reader delays the disconnect after the last character until the trailing + edge of the card is detected. In this simulator, this delay is accomplished + by scheduling a final service request after the last characters have been + delivered too the channel. The timing for this service has been adjusted to + handle some example SDS programs. Too long a delay causes errors in some, too short + a delay affects others. + */ + +#include "sds_defs.h" +#include "sim_card.h" + +#define FEEDING 00001000 /* feeding card to read station */ +#define READING 00004000 /* Card at read station */ + +#define STATUS u3 /* status */ + +#define CARD_RDY(u) (sim_card_input_hopper_count(u) > 0 || \ +sim_card_eof(u) == 1) + +extern uint32 xfr_req; +extern int32 stop_invins, stop_invdev, stop_inviop; +extern uint8 chan_cpw[NUM_CHAN]; /* char per word */ +extern uint8 chan_cnt[NUM_CHAN]; /* char count */ + +int32 cr_bptr = 0; /* buf ptr */ +int32 cr_blnt = 0; /* buf length */ +int32 cr_chr = 0; /* char no.*/ +int32 cr_inst = 0; /* saved instr */ +int32 cr_eor = 0; /* end of record */ +uint16 cr_buffer[80]; /* card record */ + +DSPT cr_tplt[] = {{1,0},{0,0}}; /* template */ + +t_stat cr_svc(UNIT *); +t_stat cr_boot(int32, DEVICE *); +t_stat cr_reset(DEVICE *); +t_stat cr_attach(UNIT *, CONST char *); +t_stat cr_detach(UNIT *); +t_stat cr_devio(uint32 fnc, uint32 inst, uint32 *dat); +t_stat cr_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat cr_readrec (UNIT *uptr); +void cr_set_err (UNIT *uptr); + +DIB cr_dib = { CHAN_W, DEV_CR, XFR_CR, cr_tplt, &cr_devio }; + +UNIT cr_unit = { + UDATA(&cr_svc, UNIT_ATTABLE | UNIT_RO | UNIT_DISABLE | MODE_029 | MODE_CBN,0), + 60 +}; + +REG cr_reg[] = { + { DRDATA (BPTR, cr_bptr, 18), PV_LEFT }, + { DRDATA (BLNT, cr_blnt, 18), PV_LEFT }, + { FLDATA (XFR, xfr_req, XFR_V_CR) }, + { ORDATA (INST, cr_inst, 24) }, + { DRDATA (POS, cr_unit.pos, T_ADDR_W), PV_LEFT }, + { NULL } +}; + +MTAB cr_mod[] = { + {MTAB_XTD | MTAB_VDV, 0, "CHANNEL", "CHANNEL", + &set_chan,&show_chan,NULL, "Device Channel"}, + {MTAB_XTD | MTAB_VDV, 0, "FORMAT", "FORMAT", + &sim_card_set_fmt, &sim_card_show_fmt, + NULL,"Card Format"}, + { MTAB_XTD|MTAB_VDV, 0, "CAPACITY", NULL, + NULL, &cr_show_cap, NULL, "Card Input Status" }, + {0} +}; + +DEVICE cr_dev = { + "CR", &cr_unit, cr_reg, cr_mod, + 1, 10, 31, 1, 8, 8, + NULL, NULL, &cr_reset, &cr_boot, &cr_attach,NULL, + &cr_dib, DEV_DISABLE | DEV_CARD, 0, NULL, + NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* Returns the SDS Internal style BCD of the + hollerith code or 0x7f if error + */ +uint8 hol_to_sdsbcd(uint16 hol) { + uint8 bcd; + + /* Convert 10,11,12 rows */ + switch (hol & 0xe00) { + case 0x000: + if ((hol & 0x1ff) == 0) + return 060; + bcd = 000; // digits 1-9 + break; + case 0x200: /* 0 */ + if ((hol & 0x1ff) == 0) + return 00; // digit 0 + bcd = 060; // /,S-Z + break; + case 0x400: /* 11 */ + bcd = 040; // -,J-R + break; + case 0x600: /* 11-10 Punch */ + bcd = 052; + break; + case 0x800: /* 12 */ + bcd = 020; // +,A-I + break; + case 0xA00: /* 12-10 Punch */ + bcd = 032; + break; + default: /* Double punch in 10,11,12 rows */ + return 0x7f; + } + + hol &= 0x1ff; /* Mask rows 0-9 */ + /* Check row 8 punched */ + if (hol & 0x2) { + bcd += 8; + hol &= ~0x2; + } + + /* Convert rows 0-9 */ + while (hol != 0 && (hol & 0x200) == 0) { + bcd++; + hol <<= 1; + } + + /* Any more columns punched? */ + if ((hol & 0x1ff) != 0) + return 0x7f; + return bcd; +} + +/* device i/o routine */ +t_stat cr_devio (uint32 fnc, uint32 inst, uint32 *dat) { + UNIT *uptr = &cr_unit; /* get unit ptr */ + int32 new_ch; + int32 t; + t_stat r; + unsigned char chr; + + switch (fnc) { /* case function */ + case IO_CONN: /* bufer control EOM */ + new_ch = I_GETEOCH (inst); /* get new chan */ + if (new_ch != cr_dib.chan) /* wrong chan? */ + return SCPE_IERR; + if (sim_is_active(uptr)) /* busy ?*/ + CRETIOP; + /* if not reading and no card in reader and hopper has cards */ + if ((uptr->STATUS & (FEEDING|READING)) == 0 && + (sim_card_input_hopper_count(uptr) > 0)) { + uptr->STATUS = FEEDING; + cr_inst = inst; + cr_blnt = 0; + cr_bptr = 0; + xfr_req = xfr_req & ~XFR_CR; /* clr xfr flag */ + sim_activate (uptr,2*uptr->wait); /* start timer */ + } + else { + /* if feeding or reading in different mode */ + if ((inst & 01000) != (cr_inst & 01000)) { + if (cr_inst & 01000) { + if (cr_chr & 1) { /* was binary - at 2nd 6 bits + */ + cr_bptr++; /* skip to next column*/ + } + } + cr_chr = 0; + } + } + cr_inst = inst; /* save EOM with mode */ + break; + case IO_EOM1: /* I/O Control EOM */ + new_ch = I_GETEOCH (inst); /* get new chan */ + if (new_ch != cr_dib.chan) /* wrong chan? err */ + return SCPE_IERR; + if ((inst & 07700) == 02000) { /* skip remainder of card*/ + sim_cancel (uptr); /* stop timer */ + chan_set_flag (cr_dib.chan, CHF_EOR); /* end record */ + uptr->STATUS = 0; + chan_disc (cr_dib.chan); + xfr_req = xfr_req & ~XFR_CR; /* clr xfr flag */ + } + break; + case IO_DISC: /* disconnect */ + xfr_req = xfr_req & ~XFR_CR; /* clr xfr flag */ + sim_cancel (uptr); /* deactivate unit */ + break; + case IO_SKS: /* SKS */ + new_ch = I_GETSKCH (inst); /* get chan # */ + if (new_ch != cr_dib.chan) /* wrong chan? */ + return SCPE_IERR; + t = I_GETSKCND (inst); /* get skip cond */ + switch (t) { /* case sks cond */ + case 004: /* sks 1100n */ + // CFT + if ((uptr->STATUS & (FEEDING|READING)) == 0 && + (sim_card_input_hopper_count(uptr) > 0)) + *dat = 1; /* skip if not EOF */ + break; + case 010: /* sks 1200n */ + // CRT + // hopper not empty + // no feed or read cycle is in progress + if ((uptr->STATUS & (FEEDING|READING)) == 0 && + (sim_card_input_hopper_count(uptr) > 0)) + *dat = 1; /* skip if reader ready */ + break; + case 020: /* sks 1400n */ + if ((uptr->STATUS & READING) && /* first column test */ + (((cr_inst & 01000) && (cr_chr < 2)) || + (cr_chr < 1))) + *dat = 1; /* skip if first column*/ + break; + } + break; + case IO_READ: + xfr_req = xfr_req & ~XFR_CR; + if (cr_blnt == 0) { /* first read? */ + r = cr_readrec (uptr); /* get data */ + if ((r != SCPE_OK) || (cr_blnt == 0)) /* err, inv reclnt? */ + return r; + } + if (cr_blnt) { + if (cr_inst & 01000) { + if (cr_chr & 1) /* binary */ + chr =cr_buffer[cr_bptr++] & 077; + else + chr = (cr_buffer[cr_bptr] >> 6) & 077; + cr_chr++; + *dat = chr & 077; + } + else { + chr = hol_to_sdsbcd(cr_buffer[cr_bptr++]); /* bcd */ + *dat = chr & 077; + } + } + if (cr_bptr >= cr_blnt) { + /* The card reader doesn't disconnect from the channel until the + trailing edge of the card passes the read station so we need to + schedule another service event here. But if it disconnects too + soon some programs (Fortran and 850647 (unencode) don't work right + and if it takes too long Symbol will try to connect to the LP + before it's disconnected. + */ + cr_eor = 1; + sim_cancel(uptr); + sim_activate (uptr, 50); + } + break; + case IO_WREOR: + case IO_WRITE: + CRETINS; + } + return SCPE_OK; +} + + +/* Service routine */ +t_stat cr_svc(UNIT * uptr) { + xfr_req = xfr_req & ~XFR_CR; + if (cr_eor) { + cr_eor = 0; + sim_cancel (uptr); + chan_set_flag (cr_dib.chan, CHF_EOR); + uptr->STATUS = 0; + return SCPE_OK; + } + xfr_req = xfr_req | XFR_CR; + sim_activate (uptr, 50); + return SCPE_OK; +} + + +/* Read start - get next record */ +t_stat cr_readrec (UNIT *uptr) { + int r; + + switch(r = sim_read_card(uptr, cr_buffer)) { + case CDSE_EOF: /* parser found tape mark attach */ + case CDSE_EMPTY: /* not attached or hopper empty */ + case CDSE_ERROR: /* parser found error during attach */ + default: + uptr->STATUS = 0; /* read failed, no card in reader */ + cr_set_err(uptr); + return r; + case CDSE_OK: + uptr->STATUS = READING; + cr_bptr = 0; + cr_blnt = 80; + cr_chr = 0; + break; + } + return SCPE_OK; +} + +/* Fatal error */ +void cr_set_err (UNIT *uptr) { + chan_set_flag (cr_dib.chan, CHF_EOR | CHF_ERR); /* eor, error */ + chan_disc (cr_dib.chan); /* disconnect */ + xfr_req = xfr_req & ~XFR_CR; /* clear xfr */ + sim_cancel (uptr); /* stop */ + cr_bptr = 0; /* buf empty */ + return; +} + +t_stat cr_reset (DEVICE *dptr) { + chan_disc (cr_dib.chan); /* disconnect */ + cr_bptr = cr_blnt = 0; + xfr_req = xfr_req & ~XFR_CR; /* clr xfr flag */ + sim_cancel (&cr_unit); /* deactivate unit */ + return SCPE_OK; +} + +t_stat cr_attach (UNIT *uptr, CONST char *cptr) { + return sim_card_attach(uptr, cptr); +} + +/* Boot routine - simulate FILL console command */ +t_stat cr_boot (int32 unitno, DEVICE *dptr) { + extern uint32 P, M[]; + + cr_reset(dptr); + M[0] = 077777771; /* -7B */ + M[1] = 007100000; /* LDX 0 */ + M[2] = 000203606; /* EOM 3606 read card binary */ + M[3] = 003200002; /* WIM 2 */ + M[4] = 000100002; /* BRU 2 */ + P = 1; /* start at 1 */ + return SCPE_OK; +} + +t_stat cr_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc) { + int n; + + if ((n = sim_card_input_hopper_count(uptr)) == 0) + fprintf(st,"hopper empty"); + else { + if (n == 1) + fprintf(st,"1 card"); + else + fprintf(st,"%d cards",n); + fprintf(st," in hopper"); + } + return SCPE_OK; +} diff --git a/SDS/sds_defs.h b/SDS/sds_defs.h index 6654a73b..32e2e617 100644 --- a/SDS/sds_defs.h +++ b/SDS/sds_defs.h @@ -1,6 +1,6 @@ /* sds_defs.h: SDS 940 simulator definitions - Copyright (c) 2001-2010, Robert M. Supnik + Copyright (c) 2001-2020, 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. + 09-Nov-20 RMS Added definitions for card reader/punch (Ken Rector) 22-May-10 RMS Added check for 64b definitions 25-Apr-03 RMS Revised for extended file support */ @@ -350,11 +351,13 @@ typedef struct sdsdib DIB; #define DEV_MASK 077 /* device mask */ #define DEV_TTI 001 /* teletype */ #define DEV_PTR 004 /* paper tape rdr */ +#define DEV_CR 006 /* card punch */ #define DEV_MT 010 /* magtape */ #define DEV_RAD 026 /* fixed head disk */ #define DEV_DSK 026 /* moving head disk */ #define DEV_TTO 041 /* teletype */ #define DEV_PTP 044 /* paper tape punch */ +#define DEV_CP 046 /* card punch */ #define DEV_LPT 060 /* line printer */ #define DEV_MTS 020 /* MT scan/erase */ #define DEV_OUT 040 /* output flag */ @@ -375,6 +378,8 @@ typedef struct sdsdib DIB; #define XFR_V_RAD 6 /* fixed hd disk */ #define XFR_V_DSK 7 /* mving hd disk */ #define XFR_V_MT0 8 /* magtape */ +#define XFR_V_CR 9 /* card reader */ +#define XFR_V_CP 10 /* card punch */ #define XFR_TTI (1 << XFR_V_TTI) #define XFR_TTO (1 << XFR_V_TTO) @@ -384,6 +389,8 @@ typedef struct sdsdib DIB; #define XFR_RAD (1 << XFR_V_RAD) #define XFR_DSK (1 << XFR_V_DSK) #define XFR_MT0 (1 << XFR_V_MT0) +#define XFR_CR (1 << XFR_V_CR) +#define XFR_CP (1 << XFR_V_CP) /* PIN/POT ordinals (0 is reserved) */ @@ -418,9 +425,13 @@ void chan_set_flag (int32 ch, uint32 fl); void chan_set_ordy (int32 ch); void chan_disc (int32 ch); void chan_set_uar (int32 ch, uint32 dev); -t_stat set_chan (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat show_chan (FILE *st, UNIT *uptr, int32 val, void *desc); +t_stat set_chan (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat show_chan (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat chan_process (void); t_bool chan_testact (void); +/* Translation tables */ +extern const int8 odd_par[64]; + + #endif diff --git a/SDS/sds_diag.txt b/SDS/sds_diag.txt index 6f095a7f..eb0144b6 100644 --- a/SDS/sds_diag.txt +++ b/SDS/sds_diag.txt @@ -111,3 +111,6 @@ Bugs 36. CPU: EOD 20000 used by diagnostic (EM change is NOP) 37. CPU: SKD sets all 24b of X, not just exponent 38. CPU: reset should not clear A, B, X +39. LPT: carriage control position lost on spacing operation +40. IO: TOP disconnects the channel rather than setting CHF_EOR +41. TTY: TTO was outputing spurious extra character, even if no leader set diff --git a/SDS/sds_drm.c b/SDS/sds_drm.c index ec22cf82..4aacc1f0 100644 --- a/SDS/sds_drm.c +++ b/SDS/sds_drm.c @@ -106,7 +106,6 @@ int32 drm_ftime = 3; /* time to fetch */ int32 drm_xtime = 1; /* time to xfr */ int32 drm_stopioe = 1; /* stop on error */ -DEVICE drm_dev; t_stat drm (uint32 fnc, uint32 inst, uint32 *dat); t_stat drm_svc (UNIT *uptr); t_stat drm_reset (DEVICE *dptr); @@ -238,7 +237,7 @@ if (drm_sta != DRM_SXFR) { /* fetch drum prog? */ case DRM_EIE: /* end, int if err */ if (!drm_err) return SCPE_OK; - /* fall through */ + /* fall through */ case DRM_EIU: /* end, int uncond */ int_req = int_req | INT_DRM; return SCPE_OK; diff --git a/SDS/sds_dsk.c b/SDS/sds_dsk.c index 22d0a7a3..6b170816 100644 --- a/SDS/sds_dsk.c +++ b/SDS/sds_dsk.c @@ -87,7 +87,6 @@ DSPT dsk_tplt[] = { /* template */ { 0, 0 } }; -DEVICE dsk_dev; t_stat dsk_svc (UNIT *uptr); t_stat dsk_reset (DEVICE *dptr); t_stat dsk_fill (uint32 dev); diff --git a/SDS/sds_io.c b/SDS/sds_io.c index dd55afa0..a59723a7 100644 --- a/SDS/sds_io.c +++ b/SDS/sds_io.c @@ -1,6 +1,6 @@ /* sds_io.c: SDS 940 I/O simulator - Copyright (c) 2001-2012, Robert M. Supnik + Copyright (c) 2001-2020, 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,8 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 01-Nov-2020 RMS Fixed overrun/underrun handling in single-word IO + 23-Oct-2020 RMS TOP disconnects the channel rather than setting CHF_EOR 19-Mar-2012 RMS Fixed various declarations (Mark Pizzolato) */ @@ -149,7 +151,7 @@ extern void set_dyn_map (void); support all widths. */ -t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc); +t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, CONST void *desc); struct aldisp { t_stat (*pin) (uint32 num, uint32 *dat); /* altnum, *dat */ @@ -222,11 +224,11 @@ uint32 dev_map[64][NUM_CHAN]; /* dev_dsp maps device and channel numbers to dispatch routines */ -t_stat (*dev_dsp[64][NUM_CHAN])() = { {NULL} }; +t_stat (*dev_dsp[64][NUM_CHAN])(uint32 fnc, uint32 dev, uint32 *dat) = { {NULL} }; /* dev3_dsp maps system device numbers to dispatch routines */ -t_stat (*dev3_dsp[64])() = { NULL }; +t_stat (*dev3_dsp[64])(uint32 fnc, uint32 dev, uint32 *dat) = { NULL }; /* dev_alt maps alert numbers to dispatch routines */ @@ -389,7 +391,7 @@ switch (mod) { if (ch_dev & DEV_OUT) { /* to output dev? */ if (chan_cnt[ch] || (chan_flag[ch] & CHF_ILCE)) /* busy, DMA? */ chan_flag[ch] = chan_flag[ch] | CHF_TOP; /* TOP pending */ - else return dev_wreor (ch, ch_dev); /* idle, write EOR */ + else return dev_disc (ch, ch_dev); /* idle, disconnect */ } /* end else TOP */ else if (ch_dev & DEV_MT) { /* change to scan? */ chan_uar[ch] = chan_uar[ch] | DEV_MTS; /* change dev addr */ @@ -577,7 +579,7 @@ return SCPE_OK; IORD, IORP, IOSP: ZWC interrupt IOSD: ZWC interrupt, EOR interrupt, disconnect - Note that the channel can be disconnected if CHN_EOR is set, but must + Note that the channel can be disconnected if CHF_EOR is set, but must not be if XFR_REQ is set */ t_stat chan_read (int32 ch) @@ -587,20 +589,23 @@ uint32 dev = chan_uar[ch] & DEV_MASK; uint32 tfnc = CHM_GETFNC (chan_mode[ch]); t_stat r = SCPE_OK; -if (dev && TST_XFR (dev, ch)) { /* ready to xfr? */ - if (INV_DEV (dev, ch)) CRETIOP; /* can't read? */ +if ((dev != 0) && TST_XFR (dev, ch)) { /* ready to xfr? */ + if (INV_DEV (dev, ch)) /* can't read? */ + CRETIOP; r = dev_dsp[dev][ch] (IO_READ, dev, &dat); /* read data */ - if (r) /* error? */ + if ((r != 0) || (chan_cnt[ch] > chan_cpw[ch])) /* error or overrun? */ chan_flag[ch] = chan_flag[ch] | CHF_ERR; - if (chan_flag[ch] & CHF_24B) /* 24B? */ - chan_war[ch] = dat; - else if (chan_flag[ch] & CHF_12B) /* 12B? */ - chan_war[ch] = ((chan_war[ch] << 12) | (dat & 07777)) & DMASK; - else chan_war[ch] = ((chan_war[ch] << 6) | (dat & 077)) & DMASK; + else { /* no, precess data */ + if (chan_flag[ch] & CHF_24B) /* 24B? */ + chan_war[ch] = dat; + else if (chan_flag[ch] & CHF_12B) /* 12B? */ + chan_war[ch] = ((chan_war[ch] << 12) | (dat & 07777)) & DMASK; + else chan_war[ch] = ((chan_war[ch] << 6) | (dat & 077)) & DMASK; + } if (chan_flag[ch] & CHF_SCAN) /* scanning? */ chan_cnt[ch] = chan_cpw[ch]; /* never full */ else chan_cnt[ch] = chan_cnt[ch] + 1; /* insert char */ - if (chan_cnt[ch] > chan_cpw[ch]) { /* full? */ + if (chan_cnt[ch] > chan_cpw[ch]) { /* full now? */ if (chan_flag[ch] & CHF_ILCE) { /* interlace on? */ chan_write_mem (ch); /* write to mem */ if (chan_wcr[ch] == 0) { /* wc zero? */ @@ -697,26 +702,26 @@ if (dev && TST_XFR (dev, ch)) { /* ready to xfr? */ chan_cnt[ch] = chan_cpw[ch] + 1; /* set cnt */ } else { /* ilce off */ - CLR_XFR (dev, ch); /* cant xfr */ - if (TST_EOR (dev)) /* EOR? */ + if (TST_EOR (dev)) /* EOR? */ return chan_eor (ch); chan_flag[ch] = chan_flag[ch] | CHF_ERR; /* rate err */ - return SCPE_OK; } /* end else ilce */ } /* end if cnt */ - chan_cnt[ch] = chan_cnt[ch] - 1; /* decr cnt */ - if (chan_flag[ch] & CHF_24B) /* 24B? */ - dat = chan_war[ch]; - else if (chan_flag[ch] & CHF_12B) { /* 12B? */ - dat = (chan_war[ch] >> 12) & 07777; /* get halfword */ - chan_war[ch] = (chan_war[ch] << 12) & DMASK; /* remove from war */ - } - else { /* 6B */ - dat = (chan_war[ch] >> 18) & 077; /* get char */ - chan_war[ch] = (chan_war[ch] << 6) & DMASK; /* remove from war */ - } + if (chan_cnt[ch] != 0) { /* if not underrun */ + chan_cnt[ch] = chan_cnt[ch] - 1; /* decr cnt */ + if (chan_flag[ch] & CHF_24B) /* 24B? */ + dat = chan_war[ch]; + else if (chan_flag[ch] & CHF_12B) { /* 12B? */ + dat = (chan_war[ch] >> 12) & 07777; /* get halfword */ + chan_war[ch] = (chan_war[ch] << 12) & DMASK;/* remove from war */ + } + else { /* 6B */ + dat = (chan_war[ch] >> 18) & 077; /* get char */ + chan_war[ch] = (chan_war[ch] << 6) & DMASK; /* remove from war */ + } + } /* end no underrun */ r = dev_dsp[dev][ch] (IO_WRITE, dev, &dat); /* write */ - if (r) /* error? */ + if (r != 0) /* error? */ chan_flag[ch] = chan_flag[ch] | CHF_ERR; if (chan_cnt[ch] == 0) { /* buf empty? */ if (chan_flag[ch] & CHF_ILCE) { /* ilce on? */ @@ -737,14 +742,14 @@ if (dev && TST_XFR (dev, ch)) { /* ready to xfr? */ } /* end if SD */ else if (!(tfnc && CHM_SGNL) || /* IORx or IOSP TOP? */ (chan_flag[ch] & CHF_TOP)) - dev_wreor (ch, dev); /* R: write EOR */ + dev_disc (ch, dev); /* R: disconnect */ chan_flag[ch] = chan_flag[ch] & ~CHF_TOP; } /* end else comp */ } /* end if wcr */ } /* end if ilce */ else if (chan_flag[ch] & CHF_TOP) { /* off, TOP pending? */ chan_flag[ch] = chan_flag[ch] & ~CHF_TOP; /* clear TOP */ - dev_wreor (ch, dev); /* write EOR */ + dev_disc (ch, dev); /* disconnect */ } else if (ion) /* no TOP, EOW intr */ int_req = int_req | int_zc[ch]; @@ -902,7 +907,7 @@ return SCPE_OK; /* Channel assignment routines */ -t_stat set_chan (UNIT *uptr, int32 val, char *sptr, void *desc) +t_stat set_chan (UNIT *uptr, int32 val, CONST char *sptr, void *desc) { DEVICE *dptr; DIB *dibp; @@ -929,7 +934,7 @@ for (i = 0; i < NUM_CHAN; i++) { /* match input */ return SCPE_ARG; } -t_stat show_chan (FILE *st, UNIT *uptr, int32 val, void *desc) +t_stat show_chan (FILE *st, UNIT *uptr, int32 val, CONST void *desc) { DEVICE *dptr; DIB *dibp; @@ -997,7 +1002,7 @@ return FALSE; /* Display channel state */ -t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc) +t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, CONST void *desc) { if ((val < 0) || (val >= NUM_CHAN)) return SCPE_IERR; fprintf (st, "UAR: %02o\n", chan_uar[val]); diff --git a/SDS/sds_lp.c b/SDS/sds_lp.c index 1462bd88..b06bdca9 100644 --- a/SDS/sds_lp.c +++ b/SDS/sds_lp.c @@ -58,10 +58,9 @@ DSPT lpt_tplt[] = { /* template */ { 0, 0 } }; -DEVICE lpt_dev; t_stat lpt_svc (UNIT *uptr); t_stat lpt_reset (DEVICE *dptr); -t_stat lpt_attach (UNIT *uptr, char *cptr); +t_stat lpt_attach (UNIT *uptr, CONST char *cptr); t_stat lpt_crctl (UNIT *uptr, int32 ch); t_stat lpt_space (UNIT *uptr, int32 cnt); t_stat lpt_status (UNIT *uptr); @@ -245,7 +244,7 @@ if (uptr->flags & UNIT_ATT) { /* attached? */ uptr->pos = ftell (uptr->fileref); /* update position */ if (ferror (uptr->fileref)) { /* I/O error? */ lpt_end_op (CHF_EOR | CHF_ERR); /* set err, disc */ - perror ("LPT I/O error"); /* print msg */ + sim_perror ("LPT I/O error"); /* print msg */ clearerr (uptr->fileref); return SCPE_IOERR; /* ret error */ } @@ -324,7 +323,7 @@ return SCPE_OK; /* Attach routine */ -t_stat lpt_attach (UNIT *uptr, char *cptr) +t_stat lpt_attach (UNIT *uptr, CONST char *cptr) { lpt_ccp = 0; /* top of form */ return attach_unit (uptr, cptr); diff --git a/SDS/sds_mt.c b/SDS/sds_mt.c index f03384f8..6887323b 100644 --- a/SDS/sds_mt.c +++ b/SDS/sds_mt.c @@ -78,11 +78,10 @@ DSPT mt_tplt[] = { /* template */ { 0, 0 } }; -DEVICE mt_dev; t_stat mt_svc (UNIT *uptr); t_stat mt_reset (DEVICE *dptr); t_stat mt_boot (int32 unitno, DEVICE *dptr); -t_stat mt_attach (UNIT *uptr, char *cptr); +t_stat mt_attach (UNIT *uptr, CONST char *cptr); t_stat mt_detach (UNIT *uptr); t_stat mt_readrec (UNIT *uptr); t_mtrlnt mt_readbc (UNIT *uptr); @@ -478,7 +477,7 @@ return SCPE_OK; /* Attach and detach routines */ -t_stat mt_attach (UNIT *uptr, char *cptr) +t_stat mt_attach (UNIT *uptr, CONST char *cptr) { t_stat r; diff --git a/SDS/sds_mux.c b/SDS/sds_mux.c index 64e22794..88e590c1 100644 --- a/SDS/sds_mux.c +++ b/SDS/sds_mux.c @@ -120,11 +120,11 @@ t_stat mux (uint32 fnc, uint32 inst, uint32 *dat); t_stat muxi_svc (UNIT *uptr); t_stat muxo_svc (UNIT *uptr); t_stat mux_reset (DEVICE *dptr); -t_stat mux_attach (UNIT *uptr, char *cptr); +t_stat mux_attach (UNIT *uptr, CONST char *cptr); t_stat mux_detach (UNIT *uptr); -t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat mux_show (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat mux_vlines (UNIT *uptr, int32 val, char *cptr, void *desc); +t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat mux_show (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat mux_vlines (UNIT *uptr, int32 val, CONST char *cptr, void *desc); void mux_reset_ln (int32 ln); void mux_scan_next (void); @@ -479,7 +479,7 @@ return SCPE_OK; /* Attach master unit */ -t_stat mux_attach (UNIT *uptr, char *cptr) +t_stat mux_attach (UNIT *uptr, CONST char *cptr) { t_stat r; int32 t; @@ -508,7 +508,7 @@ return r; /* Change number of lines */ -t_stat mux_vlines (UNIT *uptr, int32 val, char *cptr, void *desc) +t_stat mux_vlines (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { int32 newln, i, t; t_stat r; diff --git a/SDS/sds_rad.c b/SDS/sds_rad.c index b8d4e228..b393ae44 100644 --- a/SDS/sds_rad.c +++ b/SDS/sds_rad.c @@ -67,7 +67,6 @@ DSPT rad_tplt[] = { /* template */ { 0, 0 } }; -DEVICE rad_dev; t_stat rad_svc (UNIT *uptr); t_stat rad_reset (DEVICE *dptr); t_stat rad_boot (int32 unitno, DEVICE *dptr); @@ -133,7 +132,7 @@ t_stat rad (uint32 fnc, uint32 inst, uint32 *dat) { int32 t, lun, new_ch; uint32 p; -uint32 *fbuf = rad_unit.filebuf; +uint32 *fbuf = (uint32 *)rad_unit.filebuf; switch (fnc) { /* case function */ @@ -267,7 +266,7 @@ return SCPE_OK; t_stat rad_fill (int32 sba) { uint32 p = rad_da * RAD_NUMWD; -uint32 *fbuf = rad_unit.filebuf; +uint32 *fbuf = (uint32 *)rad_unit.filebuf; int32 wa = (sba + 1) >> 1; /* whole words */ if (sba && (p < rad_unit.capac)) { /* fill needed? */ diff --git a/SDS/sds_stddev.c b/SDS/sds_stddev.c index bb563e73..2d153dc8 100644 --- a/SDS/sds_stddev.c +++ b/SDS/sds_stddev.c @@ -1,6 +1,6 @@ /* sds_stddev.c: SDS 940 standard devices - Copyright (c) 2001-2008, Robert M. Supnik + Copyright (c) 2001-2020, 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"), @@ -28,11 +28,13 @@ tti keyboard tto teleprinter + 23-Oct-20 RMS TTO recognizes no leader flag (Ken Rector) 29-Dec-03 RMS Added console backpressure support 25-Apr-03 RMS Revised for extended file support */ #include "sds_defs.h" +#include "sim_tmxr.h" #define TT_CR 052 /* typewriter */ #define TT_TB 072 @@ -44,9 +46,10 @@ int32 ptr_sor = 0; /* start of rec */ int32 ptr_stopioe = 0; /* no stop on err */ int32 ptp_ldr = 0; /* no leader */ int32 ptp_stopioe = 1; +int32 tto_ldr = 0; /* no leader */ +int32 tto_retry = 0; /* retry due to stall */ DSPT std_tplt[] = { { 1, 0 }, { 0, 0 } }; /* template */ -DEVICE ptr_dev, ptp_dev; t_stat ptr (uint32 fnc, uint32 inst, uint32 *dat); t_stat ptr_svc (UNIT *uptr); t_stat ptr_reset (DEVICE *dptr); @@ -63,9 +66,9 @@ t_stat tti_reset (DEVICE *dptr); t_stat tto (uint32 fnc, uint32 inst, uint32 *dat); t_stat tto_svc (UNIT *uptr); t_stat tto_reset (DEVICE *dptr); +t_stat tto_out (int32 dat); int8 ascii_to_sds(int8 ch); int8 sds_to_ascii(int8 ch); -extern const int8 odd_par[64]; /* PTR data structures @@ -189,6 +192,8 @@ UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT }; REG tto_reg[] = { { ORDATA (BUF, tto_unit.buf, 6) }, { FLDATA (XFR, xfr_req, XFR_V_TTO) }, + { FLDATA (LDR, tto_ldr, 0) }, + { FLDATA (RETRY, tto_retry, 0), REG_HRO }, { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } @@ -279,7 +284,7 @@ if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */ sim_printf ("PTR end of file\n"); else return SCPE_OK; } - else perror ("PTR I/O error"); /* I/O error */ + else sim_perror ("PTR I/O error"); /* I/O error */ clearerr (ptr_unit.fileref); return SCPE_IOERR; } @@ -413,7 +418,7 @@ if ((ptp_unit.flags & UNIT_ATT) == 0) { /* attached? */ } if (putc (dat, ptp_unit.fileref) == EOF) { /* I/O error? */ ptp_set_err (); /* yes, disc, err */ - perror ("PTP I/O error"); /* print msg */ + sim_perror ("PTP I/O error"); /* print msg */ clearerr (ptp_unit.fileref); return SCPE_IOERR; } @@ -504,7 +509,7 @@ if (temp & SCPE_BREAK) /* ignore break */ return SCPE_OK; temp = temp & 0177; tti_unit.pos = tti_unit.pos + 1; -if (ascii_to_sds(temp) >= 0) { +if (ascii_to_sds (temp) >= 0) { tti_unit.buf = ascii_to_sds(temp); /* internal rep */ sim_putchar (temp); /* echo */ if (temp == '\r') /* lf after cr */ @@ -517,6 +522,7 @@ return SCPE_OK; t_stat tti_reset (DEVICE *dptr) { +tmxr_set_console_units (&tti_unit, &tto_unit); chan_disc (tti_dib.chan); /* disconnect */ tti_unit.buf = 0; /* clear state */ xfr_req = xfr_req & ~XFR_TTI; /* clr xfr flag */ @@ -536,6 +542,9 @@ return SCPE_OK; The typewriter output is an asynchronous streaming output device. That is, it can never cause a channel rate error; if no data is available, it waits. + + Typewriter output may be stalled, if the device is connected to a Telnet + connection, so the output routine must be able to try output repeatedly. */ t_stat tto (uint32 fnc, uint32 inst, uint32 *dat) @@ -548,11 +557,15 @@ switch (fnc) { /* case function */ new_ch = I_GETEOCH (inst); /* get new chan */ if (new_ch != tto_dib.chan) /* inv conn? err */ return SCPE_IERR; + tto_ldr = (inst & CHC_NLDR)? 0: 1; /* leader? */ + tto_retry = 0; /* no retry */ xfr_req = xfr_req & ~XFR_TTO; /* clr xfr flag */ sim_activate (&tto_unit, tto_unit.wait); /* activate */ break; case IO_DISC: /* disconnect */ + tto_ldr = 0; /* clr state */ + tto_retry = 0; xfr_req = xfr_req & ~XFR_TTO; /* clr xfr flag */ sim_cancel (&tto_unit); /* deactivate unit */ break; @@ -561,7 +574,7 @@ switch (fnc) { /* case function */ xfr_req = xfr_req & ~XFR_TTO; /* clr xfr flag */ tto_unit.buf = (*dat) & 077; /* save data */ sim_activate (&tto_unit, tto_unit.wait); /* activate */ - break; + return tto_out (tto_unit.buf); /* write the data */ case IO_WREOR: /* write eor */ break; @@ -574,29 +587,47 @@ switch (fnc) { /* case function */ return SCPE_OK; } -/* Unit service */ +/* Unit service - handle leader, retry */ t_stat tto_svc (UNIT *uptr) { +if (tto_ldr != 0) { /* need leader? */ + sim_putchar (0); /* output, no stall */ + tto_ldr = 0; /* no more leader */ + } +if (tto_retry != 0) /* retry? */ + tto_out (uptr->buf); /* try again, could stall */ +if (tto_retry == 0) /* now no retry? */ + chan_set_ordy (tto_dib.chan); /* tto ready */ +return SCPE_OK; +} + +t_stat tto_out (int32 dat) +{ int32 asc; t_stat r; -if (uptr->buf == TT_CR) /* control chars? */ +tto_retry = 0; /* assume no retry */ +if (dat == TT_CR) /* control chars? */ asc = '\r'; -else if (uptr->buf == TT_BS) +else if (dat == TT_BS) asc = '\b'; -else if (uptr->buf == TT_TB) +else if (dat == TT_TB) asc = '\t'; -else asc = sds_to_ascii(uptr->buf); /* translate */ -if ((r = sim_putchar_s (asc)) != SCPE_OK) { /* output; error? */ - sim_activate (uptr, uptr->wait); /* retry */ - return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */ +else asc = sds_to_ascii (dat); /* translate */ +r = sim_putchar_s (asc); /* output */ +if (r == SCPE_STALL) { /* stall? */ + tto_retry = 1; + sim_activate (&tto_unit, tto_unit.wait); /* retry */ + return SCPE_OK; } -uptr->pos = uptr->pos + 1; /* inc position */ +if (r != SCPE_OK) /* error? */ + return r; +tto_unit.pos = tto_unit.pos + 1; /* inc position */ chan_set_ordy (tto_dib.chan); /* tto rdy */ if (asc == '\r') { /* CR? */ - sim_putchar ('\n'); /* add lf */ - uptr->pos = uptr->pos + 1; /* inc position */ + sim_putchar ('\n'); /* add lf, no stall */ + tto_unit.pos = tto_unit.pos + 1; /* inc position */ } return SCPE_OK; } @@ -607,6 +638,8 @@ t_stat tto_reset (DEVICE *dptr) { chan_disc (tto_dib.chan); /* disconnect */ tto_unit.buf = 0; /* clear state */ +tto_ldr = 0; +tto_retry = 0; xfr_req = xfr_req & ~XFR_TTO; /* clr xfr flag */ sim_cancel (&tto_unit); /* deactivate unit */ return SCPE_OK; diff --git a/SDS/sds_sys.c b/SDS/sds_sys.c index 66307893..89288985 100644 --- a/SDS/sds_sys.c +++ b/SDS/sds_sys.c @@ -1,6 +1,6 @@ /* sds_sys.c: SDS 940 simulator interface - Copyright (c) 2001-2016, Robert M Supnik + Copyright (c) 2001-2020, 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. + 01-Nov-20 RMS Fixed sds930-to-ascii entry 060 (Ken Rector) 05-May-16 RMS Fixed ascii-to-sds940 data (Mark Pizzolato) 19-Mar-12 RMS Fixed declarations of CCT arrays (Mark Pizzolato) */ @@ -35,6 +36,8 @@ extern DEVICE cpu_dev; extern DEVICE chan_dev; extern DEVICE ptr_dev; extern DEVICE ptp_dev; +extern DEVICE cr_dev; +extern DEVICE cp_dev; extern DEVICE tti_dev; extern DEVICE tto_dev; extern DEVICE lpt_dev; @@ -73,6 +76,8 @@ DEVICE *sim_devices[] = { &tti_dev, &tto_dev, &lpt_dev, + &cr_dev, + &cp_dev, &rtc_dev, &drm_dev, &rad_dev, @@ -83,7 +88,7 @@ DEVICE *sim_devices[] = { NULL }; -const char *sim_stop_messages[] = { +const char *sim_stop_messages[SCPE_BASE] = { "Unknown error", "IO device not ready", "HALT instruction", @@ -114,7 +119,7 @@ const int8 sds930_to_ascii[64] = { 'H', 'I', '?', '.', ')', '[', '<', '@', /* 37 = stop code */ '-', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', '!', '$', '*', ']', ';', '^', /* 57 = triangle */ - '_', '/', 'S', 'T', 'U', 'V', 'W', 'X', + ' ', '/', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '?', ',', '(', '~', '\\', '#' /* 72 = rec mark */ }; /* 75 = squiggle, 77 = del */ @@ -196,7 +201,8 @@ int32 col, rpt, ptr, mask, cctbuf[CCT_LNT]; t_stat r; extern int32 lpt_ccl, lpt_ccp; extern uint8 lpt_cct[CCT_LNT]; -char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE]; +CONST char *cptr; +char cbuf[CBUFSIZE], gbuf[CBUFSIZE]; ptr = 0; for ( ; (cptr = fgets (cbuf, CBUFSIZE, fileref)) != NULL; ) { /* until eof */ @@ -251,7 +257,7 @@ for (i = wd = 0; i < 4; ) { return wd; } -t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) +t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) { int32 i, wd, buf[8]; int32 ldr = 1; @@ -491,7 +497,8 @@ return; } /* Convert from SDS internal character code to ASCII depending upon cpu mode. */ -int8 sds_to_ascii(int8 ch) + +int8 sds_to_ascii (int8 ch) { ch &= 077; if (cpu_mode == NML_MODE) @@ -501,7 +508,8 @@ int8 sds_to_ascii(int8 ch) } /* Convert from ASCII to SDS internal character code depending upon cpu mode. */ -int8 ascii_to_sds(int8 ch) + +int8 ascii_to_sds (int8 ch) { ch &= 0177; if (cpu_mode == NML_MODE) @@ -632,9 +640,10 @@ return SCPE_ARG; cptr = updated pointer to input string */ -char *get_tag (char *cptr, t_value *tag) +CONST char *get_tag (CONST char *cptr, t_value *tag) { -char *tptr, gbuf[CBUFSIZE]; +CONST char *tptr; +char gbuf[CBUFSIZE]; t_stat r; tptr = get_glyph (cptr, gbuf, 0); /* get next field */ @@ -657,20 +666,17 @@ return cptr; /* no change */ status = error status */ -t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) +t_stat parse_sym (CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) { int32 i, j, k, ch; t_value d, tag; t_stat r; -char gbuf[CBUFSIZE]; +char gbuf[CBUFSIZE], cbuf[2*CBUFSIZE]; while (isspace (*cptr)) cptr++; -for (i = 1; (i < 4) && (cptr[i] != 0); i++) { - if (cptr[i] == 0) { - for (j = i + 1; j <= 4; j++) - cptr[j] = 0; - } - } +memset (cbuf, '\0', sizeof(cbuf)); +strncpy (cbuf, cptr, sizeof(cbuf)-5); +cptr = cbuf; if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ if (cptr[0] == 0) /* must have 1 char */ return SCPE_ARG; diff --git a/Visual Studio Projects/SDS.vcproj b/Visual Studio Projects/SDS.vcproj index 6041dfcb..318af5d5 100644 --- a/Visual Studio Projects/SDS.vcproj +++ b/Visual Studio Projects/SDS.vcproj @@ -33,6 +33,9 @@ + @@ -40,7 +43,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="./;../;../SDS/" - PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS" + PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;USE_SIM_CARD" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" @@ -109,6 +112,9 @@ + @@ -118,7 +124,7 @@ InlineFunctionExpansion="1" OmitFramePointers="true" AdditionalIncludeDirectories="./;../;../SDS/" - PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS" + PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;USE_SIM_CARD" StringPooling="true" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -183,10 +189,18 @@ RelativePath="..\scp.c" > + + + + @@ -223,6 +237,10 @@ RelativePath="..\SDS\sds_sys.c" > + + @@ -264,6 +282,10 @@ RelativePath="..\SDS\sds_defs.h" > + + diff --git a/descrip.mms b/descrip.mms index c6177322..f90e3568 100644 --- a/descrip.mms +++ b/descrip.mms @@ -33,7 +33,6 @@ # PDP10 Just Build The DEC PDP-10. # PDP11 Just Build The DEC PDP-11. # PDP15 Just Build The DEC PDP-15. -# S3 Just Build The IBM System 3. # SDS Just Build The SDS 940. # VAX Just Build The DEC VAX. # VAX780 Just Build The DEC VAX780. @@ -470,15 +469,6 @@ PDP10_SOURCE = $(PDP10_DIR)PDP10_FE.C,\ PDP10_OPTIONS = /INCL=($(SIMH_DIR),$(PDP10_DIR),$(PDP11_DIR))\ /DEF=($(CC_DEFS),"USE_INT64=1","VM_PDP10=1"$(PCAP_DEFS)) -# -# IBM System 3 Simulator Definitions. -# -S3_DIR = SYS$DISK:[.S3] -S3_LIB = $(LIB_DIR)S3-$(ARCH).OLB -S3_SOURCE = $(S3_DIR)S3_CD.C,$(S3_DIR)S3_CPU.C,$(S3_DIR)S3_DISK.C,\ - $(S3_DIR)S3_LP.C,$(S3_DIR)S3_PKB.C,$(S3_DIR)S3_SYS.C -S3_OPTIONS = /INCL=($(SIMH_DIR),$(S3_DIR))/DEF=($(CC_DEFS)) - # # SDS 940 # @@ -565,7 +555,7 @@ I7094_OPTIONS = /INCL=($(SIMH_DIR),$(I7094_DIR))/DEF=($(CC_DEFS)) # .IFDEF ALPHA_OR_IA64 ALL : ALTAIR ECLIPSE GRI LGP H316 I1401 I1620 ID16 \ - ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 \ + ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 \ VAX VAX780 SDS I7094 $! No further actions necessary .ELSE @@ -573,7 +563,7 @@ ALL : ALTAIR ECLIPSE GRI LGP H316 I1401 I1620 ID16 \ # Else We Are On VAX And Build Everything EXCEPT the 64b simulators # ALL : ALTAIR GRI H316 I1401 I1620 ID16 ID32 \ - NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 S3 VAX VAX780 \ + NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 VAX VAX780 \ SDS $! No further actions necessary .ENDIF @@ -875,17 +865,6 @@ $(PDP15_LIB) : $(PDP18B_SOURCE) $ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ $ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;* -$(S3_LIB) : $(S3_SOURCE) - $! - $! Building The $(S3_LIB) Library. - $! - $ $(CC)$(S3_OPTIONS) - - /OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST) - $ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN - - LIBRARY/CREATE $(MMS$TARGET) - $ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ - $ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;* - $(SDS_LIB) : $(SDS_SOURCE) $! $! Building The $(SDS_LIB) Library. @@ -1235,18 +1214,6 @@ $(BIN_DIR)PDP15-$(ARCH).EXE : $(SIMH_MAIN) $(SIMH_LIB) $(PDP15_LIB) $(BLD_DIR)SCP.OBJ,$(PDP15_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY $ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;* -S3 : $(BIN_DIR)S3-$(ARCH).EXE - $! S3 done - -$(BIN_DIR)S3-$(ARCH).EXE : $(SIMH_MAIN) $(SIMH_LIB) $(S3_LIB) - $! - $! Building The $(BIN_DIR)S3-$(ARCH).EXE Simulator. - $! - $ $(CC)$(S3_OPTIONS)/OBJ=$(BLD_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)S3-$(ARCH).EXE - - $(BLD_DIR)SCP.OBJ,$(S3_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;* - SDS : $(BIN_DIR)SDS-$(ARCH).EXE $! SDS done diff --git a/makefile b/makefile index 35909971..c40c57b0 100644 --- a/makefile +++ b/makefile @@ -570,7 +570,7 @@ LDFLAGS = $(OS_LDFLAGS) $(NETWORK_LDFLAGS) $(LDFLAGS_O) # BIN = BIN/ SIM = scp.c sim_console.c sim_fio.c sim_timer.c sim_sock.c \ - sim_tmxr.c sim_ether.c sim_tape.c sim_shmem.c + sim_tmxr.c sim_ether.c sim_tape.c sim_shmem.c sim_card.c # @@ -730,12 +730,6 @@ ID32 = ${ID32D}/id32_cpu.c ${ID32D}/id32_sys.c ${ID32D}/id_dp.c \ ID32_OPT = -I ${ID32D} -S3D = S3 -S3 = ${S3D}/s3_cd.c ${S3D}/s3_cpu.c ${S3D}/s3_disk.c ${S3D}/s3_lp.c \ - ${S3D}/s3_pkb.c ${S3D}/s3_sys.c -S3_OPT = -I ${S3D} - - ALTAIRD = ALTAIR ALTAIR = ${ALTAIRD}/altair_sio.c ${ALTAIRD}/altair_cpu.c ${ALTAIRD}/altair_dsk.c \ ${ALTAIRD}/altair_sys.c @@ -755,8 +749,8 @@ LGP_OPT = -I ${LGPD} SDSD = SDS SDS = ${SDSD}/sds_cpu.c ${SDSD}/sds_drm.c ${SDSD}/sds_dsk.c ${SDSD}/sds_io.c \ ${SDSD}/sds_lp.c ${SDSD}/sds_mt.c ${SDSD}/sds_mux.c ${SDSD}/sds_rad.c \ - ${SDSD}/sds_stddev.c ${SDSD}/sds_sys.c -SDS_OPT = -I ${SDSD} + ${SDSD}/sds_stddev.c ${SDSD}/sds_sys.c ${SDSD}/sds_cp.c ${SDSD}/sds_cr.c +SDS_OPT = -I ${SDSD} -DUSE_SIM_CARD SIGMAD = sigma SIGMA = ${SIGMAD}/sigma_cpu.c ${SIGMAD}/sigma_sys.c ${SIGMAD}/sigma_cis.c \ @@ -782,7 +776,7 @@ ALPHA_OPT = -I ${ALPHAD} -DUSE_ADDR64 -DUSE_INT64 # Build everything # ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \ - vax vax780 nova eclipse i1401 i1620 s3 \ + vax vax780 nova eclipse i1401 i1620 \ altair gri i7094 id16 uc15 \ id32 sds lgp h316 sigma @@ -901,12 +895,6 @@ ${BIN}i7094${EXE} : ${I7094} ${SIM} ${MKDIRBIN} ${CC} ${I7094} ${SIM} ${I7094_OPT} $(CC_OUTSPEC) ${LDFLAGS} -s3 : ${BIN}s3${EXE} - -${BIN}s3${EXE} : ${S3} ${SIM} - ${MKDIRBIN} - ${CC} ${S3} ${SIM} ${S3_OPT} $(CC_OUTSPEC) ${LDFLAGS} - altair : ${BIN}altair${EXE} ${BIN}altair${EXE} : ${ALTAIR} ${SIM}