From 098200a126d6ff323c80ca7e883d59d0cd8e3219 Mon Sep 17 00:00:00 2001 From: Bob Supnik Date: Wed, 9 Mar 2005 19:33:00 -0800 Subject: [PATCH] Notes For V3.3-2 1. New Features in 3.3-2 1.1 SCP and Libraries - Added ASSERT command (from Dave Bryan) 1.2 PDP-11, VAX - Added RA60, RA71, RA81 disks 2. Bugs Fixed in 3.3-2 2.1 H316 - Fixed IORETURN macro - PT: fixed bug in OCP '0001 (found by Philipp Hachtmann) - MT: fixed error reporting from OCP (found by Philipp Hachtmann) 2.2 Interdata 32b - Fixed branches to mask new PC (from Greg Johnson) 2.3 PDP-11 - Fixed bugs in RESET for 11/70 (reported by Tim Chapman) - Fixed bug in SHOW MODEL (from Sergey Okhapkin) - Made SYSID variable for 11/70 (from Tim Chapman) - Fixed MBRK write case for 11/70 (from Tim Chapman) - RY: fixed bug in boot code (reported by Graham Toal) 2.4 VAX - Fixed initial state of cpu_extmem 2.5 HP2100 (from Dave Bryan) - Fixed missing MPCK on JRS target - Removed EXECUTE instruction (is NOP in actual microcode) - Fixed missing negative overflow renorm in StoreFP 2.6 I1401 - Fixed bug in line printer write line (reported by Van Snyder) --- 0readme_33.txt | 80 ++-- H316/h316_cpu.c | 9 +- H316/h316_defs.h | 10 +- H316/h316_mt.c | 11 +- H316/h316_stddev.c | 27 +- HP2100/hp2100_cpu.c | 1031 ++--------------------------------------- HP2100/hp2100_cpu.h | 73 +++ HP2100/hp2100_cpu1.c | 982 +++++++++++++++++++++++++++++++++++++++ HP2100/hp2100_doc.txt | 10 +- HP2100/hp2100_fp.c | 6 +- I1401/i1401_lp.c | 5 +- Interdata/id32_cpu.c | 13 +- PDP11/pdp11_cpu.c | 10 +- PDP11/pdp11_cpumod.c | 20 +- PDP11/pdp11_doc.txt | 13 +- PDP11/pdp11_rq.c | 113 ++++- PDP11/pdp11_ry.c | 8 +- PDP8/pdp8_doc.txt | 15 +- VAX/vax780_doc.txt | 4 +- VAX/vax_cpu.c | 5 +- VAX/vax_doc.txt | 4 +- descrip.mms | 2 +- makefile | 2 +- scp.c | 69 ++- scp.h | 4 +- sim_defs.h | 6 +- sim_rev.h | 36 +- simh_doc.txt | 8 +- 28 files changed, 1438 insertions(+), 1138 deletions(-) create mode 100644 HP2100/hp2100_cpu.h create mode 100644 HP2100/hp2100_cpu1.c diff --git a/0readme_33.txt b/0readme_33.txt index 9393ec85..f91abb1f 100644 --- a/0readme_33.txt +++ b/0readme_33.txt @@ -1,63 +1,47 @@ -Notes For V3.3-1 +Notes For V3.3-2 -1. New Features in 3.3-1 +1. New Features in 3.3-2 -1.1 H316 +1.1 SCP and Libraries -TTY - implemented paper-tape reader and punch - - added ASCII file support +- Added ASSERT command (from Dave Bryan) -PTR,PTP - added ASCII file support +1.2 PDP-11, VAX -1.2 HP2100 +- Added RA60, RA71, RA81 disks -CPU - added SET CPU 21MX-M, 21MX-E (from Dave Brian) - - disabled TIMER/EXECUTE/DIAG instructions for 21MX-M (from Dave Bryan) - - added post-processor to maintain T/M consistency (from Dave Bryan) - -DS - released 13037 disk controller - -1.3 Interdata - -MT - added read-only file support - -1.4 SDS - -MT - added read-only file support - -1.5 PDP-11 - -TM,TS - added read-only file support - -2. Bugs Fixed in 3.3 +2. Bugs Fixed in 3.3-2 2.1 H316 -CPU - fixed bug in divide +- Fixed IORETURN macro +- PT: fixed bug in OCP '0001 (found by Philipp Hachtmann) +- MT: fixed error reporting from OCP (found by Philipp Hachtmann) -LPT - fixed bug in DMA/DMC support - -MT - fixed bug in DMA/DMC support - -DP - fixed bug in skip on not seeking - -TTY - fixed bugs in SKS '104, '504 - -2.2 HP2100 - -CPU - fixed DMA reset to clear alternate CTL flop (from Dave Bryan) - - fixed bug in JPY (from Dave Bryan) - - fixed bugs in CBS, SBS, TBS - - separate A/B from M[0/1] for DMA (found by Dave Bryan) - - -LPS - added restart when set online, etc. (from Dave Bryan) - - fixed col count for non-printing chars (from Dave Bryan) - -LPT - added restart when set online, etc. (from Dave Bryan) +2.2 Interdata 32b +- Fixed branches to mask new PC (from Greg Johnson) 2.3 PDP-11 -CPU - fixed WAIT to work in all modes (from John Dundas) +- Fixed bugs in RESET for 11/70 (reported by Tim Chapman) +- Fixed bug in SHOW MODEL (from Sergey Okhapkin) +- Made SYSID variable for 11/70 (from Tim Chapman) +- Fixed MBRK write case for 11/70 (from Tim Chapman) +- RY: fixed bug in boot code (reported by Graham Toal) + +2.4 VAX + +- Fixed initial state of cpu_extmem + +2.5 HP2100 (from Dave Bryan) + +- Fixed missing MPCK on JRS target +- Removed EXECUTE instruction (is NOP in actual microcode) +- Fixed missing negative overflow renorm in StoreFP + +2.6 I1401 + +- Fixed bug in line printer write line (reported by Van Snyder) + diff --git a/H316/h316_cpu.c b/H316/h316_cpu.c index f3efe3cc..a41f6de2 100644 --- a/H316/h316_cpu.c +++ b/H316/h316_cpu.c @@ -1,6 +1,6 @@ /* h316_cpu.c: Honeywell 316/516 CPU simulator - Copyright (c) 1999-2004, Robert M. Supnik + Copyright (c) 1999-2005, 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,7 @@ cpu H316/H516 CPU + 15-Feb-05 RMS Added start button interrupt 01-Dec-04 RMS Fixed bug in DIV 06-Nov-04 RMS Added =n to SHOW HISTORY 04-Jan-04 RMS Removed unnecessary compare @@ -308,6 +309,7 @@ REG cpu_reg[] = { { FLDATA (SS4, ss[3], 0) }, { FLDATA (ION, dev_int, INT_V_ON) }, { FLDATA (INODEF, dev_int, INT_V_NODEF) }, + { FLDATA (START, dev_int, INT_V_START) }, { ORDATA (DEVINT, dev_int, 16), REG_RO }, { ORDATA (DEVENB, dev_enb, 16), REG_RO }, { ORDATA (CHREQ, chan_req, DMA_MAX + DMC_MAX) }, @@ -443,7 +445,7 @@ if (chan_req) { /* channel request? */ /* Interrupts */ -if ((dev_int & (INT_PENDING | dev_enb)) > INT_PENDING) { /* int req? */ +if ((dev_int & (INT_PEND|INT_NMI|dev_enb)) > INT_PEND) {/* int req? */ pme = ext; /* save extend */ if (cpu_unit.flags & UNIT_EXT) ext = 1; /* ext opt? extend on */ dev_int = dev_int & ~INT_ON; /* intr off */ @@ -460,6 +462,7 @@ else { if (sim_brk_summ && PC = NEWA (Y, Y + 1); /* incr PC */ dev_int = dev_int | INT_NODEF; } +dev_int = dev_int & ~INT_START; /* clr start button int */ sim_interval = sim_interval - 1; if (hst_lnt) { /* instr hist? */ hst_p = (hst_p + 1); /* next entry */ @@ -1129,7 +1132,7 @@ saved_AR = saved_BR = saved_XR = 0; C = 0; dp = 0; ext = pme = extoff_pending = 0; -dev_int = dev_int & ~INT_PENDING; +dev_int = dev_int & ~(INT_PEND|INT_NMI); dev_enb = 0; for (i = 0; i < DMA_MAX; i++) dma_ad[i] = dma_wc[i] = dma_eor[i] = 0; chan_req = 0; diff --git a/H316/h316_defs.h b/H316/h316_defs.h index 8fa17e67..63939ca7 100644 --- a/H316/h316_defs.h +++ b/H316/h316_defs.h @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 15-Feb-05 RMS Added start button interrupt 01-Dec-04 RMS Added double precision constants 24-Oct-03 RMS Added DMA/DMC support 25-Apr-03 RMS Revised for extended file support @@ -159,8 +160,9 @@ typedef struct h316_dib DIB; #define INT_V_FHD 8 /* fixed head disk */ #define INT_V_DP 12 /* moving head disk */ #define INT_V_MT 15 /* mag tape */ -#define INT_V_NODEF 16 /* int not deferred */ -#define INT_V_ON 17 /* int on */ +#define INT_V_START 16 /* start button */ +#define INT_V_NODEF 17 /* int not deferred */ +#define INT_V_ON 18 /* int on */ /* I/O macros */ @@ -181,9 +183,11 @@ typedef struct h316_dib DIB; #define INT_FHD (1u << INT_V_FHD) #define INT_DP (1u << INT_V_DP) #define INT_MT (1u << INT_V_MT) +#define INT_START (1u << INT_V_START) #define INT_NODEF (1u << INT_V_NODEF) #define INT_ON (1u << INT_V_ON) -#define INT_PENDING (INT_ON | INT_NODEF) +#define INT_NMI (INT_START) +#define INT_PEND (INT_ON | INT_NODEF) #define SET_INT(x) dev_int = dev_int | (x) #define CLR_INT(x) dev_int = dev_int & ~(x) diff --git a/H316/h316_mt.c b/H316/h316_mt.c index e5d66d72..1249a338 100644 --- a/H316/h316_mt.c +++ b/H316/h316_mt.c @@ -1,6 +1,6 @@ /* h316_mt.c: H316/516 magnetic tape simulator - Copyright (c) 2003-2004, Robert M. Supnik + Copyright (c) 2003-2005, 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,7 @@ mt 516-4100 seven track magnetic tape + 08-Feb-05 RMS Fixed error reporting from OCP (found by Philipp Hachtmann) 01-Dec-04 RMS Fixed bug in DMA/DMC support Magnetic tapes are represented as a series of variable records @@ -203,11 +204,11 @@ case ioOCP: mt_eor = 0; /* clr transfer done */ mt_err = 0; /* clr error */ mt_usel = u; /* save unit select */ - if (((uptr->flags & UNIT_ATT) == 0) || /* nop if not att */ - sim_is_active (uptr)) /* or busy */ - (IORETURN (mt_stopioe, SCPE_UNATT) | dat); + if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ + return (((mt_stopioe? SCPE_UNATT: SCPE_OK) << IOT_V_REASON) | dat); + if (sim_is_active (uptr)) return dat; /* nop if busy */ if (wrt_fnc[fnc] && (uptr->flags & UNIT_WPRT)) - return (STOP_MTWRP << IOT_V_REASON); + return ((STOP_MTWRP << IOT_V_REASON) | dat); uptr->FNC = fnc; uptr->UST = 0; mt_busy = 1; diff --git a/H316/h316_stddev.c b/H316/h316_stddev.c index d991f8a0..30419fac 100644 --- a/H316/h316_stddev.c +++ b/H316/h316_stddev.c @@ -1,6 +1,6 @@ /* h316_stddev.c: Honeywell 316/516 standard devices - Copyright (c) 1999-2004, Robert M. Supnik + Copyright (c) 1999-2005, 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,6 +28,8 @@ tty 316/516-33 teleprinter clk/options 316/516-12 real time clocks/internal options + 05-Feb-05 RMS Fixed bug in OCP '0001 (found by Philipp Hachtmann) + 31-Jan-05 RMS Fixed bug in TTY print (found by Philipp Hachtmann) 01-Dec-04 RMS Fixed problem in SKS '104 (reported by Philipp Hachtmann) Fixed bug in SKS '504 Added PTR detach routine, stops motion @@ -98,6 +100,7 @@ extern int32 dev_int, dev_enb; extern int32 sim_switches; extern UNIT cpu_unit; +uint32 ptr_motion = 0; /* read motion */ uint32 ptr_stopioe = 0; /* stop on error */ uint32 ptp_stopioe = 0; uint32 ptp_power = 0; /* punch power, time */ @@ -152,6 +155,7 @@ REG ptr_reg[] = { { ORDATA (BUF, ptr_unit.buf, 8) }, { FLDATA (READY, dev_int, INT_V_PTR) }, { FLDATA (ENABLE, dev_enb, INT_V_PTR) }, + { FLDATA (MOTION, ptr_motion, 0) }, { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { ORDATA (RSTATE, ptr_unit.STA, 2), REG_HIDDEN }, @@ -306,6 +310,7 @@ int32 ptrio (int32 inst, int32 fnc, int32 dat, int32 dev) switch (inst) { /* case on opcode */ case ioOCP: /* OCP */ if (fnc & 016) return IOBADFNC (dat); /* only fnc 0,1 */ + ptr_motion = fnc ^ 1; if (fnc) sim_cancel (&ptr_unit); /* fnc 1? stop */ else sim_activate (&ptr_unit, ptr_unit.wait); /* fnc 0? start */ break; @@ -319,6 +324,8 @@ case ioINA: /* INA */ if (fnc) return IOBADFNC (dat); /* only fnc 0 */ if (TST_INT (INT_PTR)) { /* ready? */ CLR_INT (INT_PTR); /* clear ready */ + if (ptr_motion) /* if motion, restart */ + sim_activate (&ptr_unit, ptr_unit.wait); return IOSKIP (ptr_unit.buf | dat); } /* ret buf, skip */ break; } /* end case op */ return dat; @@ -352,7 +359,6 @@ else { if ((c = getc (uptr->fileref)) == EOF) { /* read byte */ } SET_INT (INT_PTR); /* set ready flag */ uptr->buf = c & 0377; /* get byte */ -sim_activate (uptr, uptr->wait); /* reactivate */ return SCPE_OK; } @@ -391,6 +397,7 @@ CLR_INT (INT_PTR); /* clear ready, enb */ CLR_ENB (INT_PTR); ptr_unit.buf = 0; /* clear buffer */ ptr_unit.STA = 0; +ptr_motion = 0; /* unit stopped */ sim_cancel (&ptr_unit); /* deactivate unit */ return SCPE_OK; } @@ -637,17 +644,17 @@ return SCPE_OK; t_stat tto_write (int32 c) { -uint32 c7b; UNIT *tuptr = &tty_unit[TTO]; -c7b = c & 0177; -if (!(tuptr->flags & UNIT_8B)) { /* 7b or KSR? */ - if (c7b == 0) return SCPE_OK; /* supress NUL */ +if (tuptr->flags & UNIT_8B) c = c & 0377; /* 8b? */ +else { c = c & 0177; /* 7b, KSR: mask */ + if (c) return SCPE_OK; /* supress NUL */ if (tuptr->flags & UNIT_KSR) { /* KSR? */ - if ((c7b < 040) && /* not in ctrl set? */ - !(CNTL_SET & CHAR_FLAG (c7b))) return SCPE_OK; - if (islower (c7b)) c = toupper (c7b); } /* cvt to UC */ - else c = c7b; } /* full 7b */ + if ((c < 040) && /* not in ctrl set? */ + !(CNTL_SET & CHAR_FLAG (c))) return SCPE_OK; + if (islower (c)) c = toupper (c); /* cvt to UC */ + } + } tuptr->pos = tuptr->pos + 1; return sim_putchar_s (c); } diff --git a/HP2100/hp2100_cpu.c b/HP2100/hp2100_cpu.c index a872e9c0..43630b91 100644 --- a/HP2100/hp2100_cpu.c +++ b/HP2100/hp2100_cpu.c @@ -1,6 +1,6 @@ /* hp2100_cpu.c: HP 2100 CPU simulator - Copyright (c) 1993-2004, Robert M. Supnik + Copyright (c) 1993-2005, 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"), @@ -27,6 +27,7 @@ MP 12892B memory protect DMA0,DMA1 12895A/12897B direct memory access/dual channel port controller + 15-Jan-05 RMS Split out EAU and MAC instructions 26-Dec-04 RMS DMA reset doesn't clear alternate CTL flop (from Dave Bryan) DMA reset shouldn't clear control words (from Dave Bryan) Alternate CTL flop not visible as register (from Dave Bryan) @@ -330,30 +331,7 @@ #include "hp2100_defs.h" #include - -#define PCQ_SIZE 64 /* must be 2**n */ -#define PCQ_MASK (PCQ_SIZE - 1) -#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = err_PC - -#define UNIT_V_2100 (UNIT_V_UF + 0) /* 2100 */ -#define UNIT_V_21MX (UNIT_V_UF + 1) /* 21MX-E or 21MX-M */ -#define UNIT_V_EAU (UNIT_V_UF + 2) /* EAU */ -#define UNIT_V_FP (UNIT_V_UF + 3) /* FP */ -#define UNIT_V_DMS (UNIT_V_UF + 4) /* DMS */ -#define UNIT_V_IOP (UNIT_V_UF + 5) /* 2100 IOP */ -#define UNIT_V_IOPX (UNIT_V_UF + 6) /* 21MX IOP */ -#define UNIT_V_MSIZE (UNIT_V_UF + 7) /* dummy mask */ -#define UNIT_V_MXM (UNIT_V_UF + 8) /* 21MX is M-series */ -#define UNIT_2116 (0) -#define UNIT_2100 (1 << UNIT_V_2100) -#define UNIT_21MX (1 << UNIT_V_21MX) -#define UNIT_EAU (1 << UNIT_V_EAU) -#define UNIT_FP (1 << UNIT_V_FP) -#define UNIT_DMS (1 << UNIT_V_DMS) -#define UNIT_IOP (1 << UNIT_V_IOP) -#define UNIT_IOPX (1 << UNIT_V_IOPX) -#define UNIT_MSIZE (1 << UNIT_V_MSIZE) -#define UNIT_MXM (1 << UNIT_V_MXM) +#include "hp2100_cpu.h" #define UNIT_V_MP_JSB (UNIT_V_UF + 0) /* MP jumper W5 out */ #define UNIT_V_MP_INT (UNIT_V_UF + 1) /* MP jumper W6 out */ @@ -437,34 +415,18 @@ extern DEVICE *sim_devices[]; extern int32 sim_switches; extern char halt_msg[]; -t_stat Ea (uint32 IR, uint32 *addr, uint32 irq); t_stat Ea1 (uint32 *addr, uint32 irq); -uint8 ReadB (uint32 addr); -uint8 ReadBA (uint32 addr); -uint16 ReadW (uint32 addr); -uint16 ReadWA (uint32 addr); -uint32 ReadF (uint32 addr); uint16 ReadIO (uint32 addr, uint32 map); uint16 ReadPW (uint32 addr); uint16 ReadTAB (uint32 addr); -void WriteB (uint32 addr, uint32 dat); -void WriteBA (uint32 addr, uint32 dat); -void WriteW (uint32 addr, uint32 dat); -void WriteWA (uint32 addr, uint32 dat); void WriteIO (uint32 addr, uint32 dat, uint32 map); void WritePW (uint32 addr, uint32 dat); -t_stat iogrp (uint32 ir, uint32 iotrap); uint32 dms (uint32 va, uint32 map, uint32 prot); uint32 dms_io (uint32 va, uint32 map); -void mp_dms_jmp (uint32 va); -uint16 dms_rmap (uint32 mapi); -void dms_wmap (uint32 mapi, uint32 dat); -void dms_viol (uint32 va, uint32 st); -uint32 dms_upd_sr (void); uint32 shift (uint32 inval, uint32 flag, uint32 oper); +void dma_cycle (uint32 chan, uint32 map); uint32 calc_dma (void); uint32 calc_int (void); -void dma_cycle (uint32 chan, uint32 map); 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); @@ -477,11 +439,8 @@ t_stat cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc); t_bool dev_conflict (void); void hp_post_cmd (t_bool from_scp); -extern uint32 f_as (uint32 op, t_bool sub); -extern uint32 f_mul (uint32 op); -extern uint32 f_div (uint32 op); -extern uint32 f_fix (void); -extern uint32 f_flt (void); +extern t_stat cpu_eau (uint32 IR, uint32 intrq); +extern t_stat cpu_mac (uint32 IR, uint32 intrq); extern int32 clk_delay (int32 flg); extern void (*sim_vm_post) (t_bool from_scp); @@ -552,23 +511,23 @@ MTAB cpu_mod[] = { { UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_2100, "2100", NULL, NULL }, { UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM, UNIT_21MX, "21MX-E", NULL, NULL }, { UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM, UNIT_21MX+UNIT_MXM, "21MX-M", NULL, NULL }, - { UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt, + { UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt, NULL, (void *) UNIT_EAU }, { UNIT_EAU, 0, "no EAU", "NOEAU", &cpu_set_opt, NULL, (void *) UNIT_EAU }, - { UNIT_FP, UNIT_FP, "FP", "FP", &cpu_set_opt, + { UNIT_FP, UNIT_FP, "FP", "FP", &cpu_set_opt, NULL, (void *) UNIT_FP }, { UNIT_FP, 0, "no FP", "NOFP", &cpu_set_opt, NULL, (void *) UNIT_FP }, - { UNIT_DMS, UNIT_DMS, "DMS", "DMS", &cpu_set_opt, + { UNIT_DMS, UNIT_DMS, "DMS", "DMS", &cpu_set_opt, NULL, (void *) UNIT_DMS }, { UNIT_DMS, 0, "no DMS", "NODMS", &cpu_set_opt, NULL, (void *) UNIT_DMS }, - { UNIT_MSIZE, 2, NULL, "IOP", &cpu_set_opt, + { UNIT_MSIZE, 2, NULL, "IOP", &cpu_set_opt, NULL, (void *) UNIT_IOP }, - { UNIT_IOP+UNIT_IOPX, UNIT_IOP, "IOP", NULL, NULL }, - { UNIT_IOP+UNIT_IOPX, UNIT_IOPX, "IOP", NULL, NULL }, - { UNIT_IOP+UNIT_IOPX, 0, "no IOP", "NOIOP", &cpu_set_opt, + { UNIT_IOP+UNIT_IOPX, UNIT_IOP, "IOP", NULL, NULL }, + { UNIT_IOP+UNIT_IOPX, UNIT_IOPX,"IOP", NULL, NULL }, + { UNIT_IOP+UNIT_IOPX, 0, "no IOP", "NOIOP", &cpu_set_opt, NULL, (void *) UNIT_IOP }, { UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size }, { UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size }, @@ -670,96 +629,6 @@ DEVICE dma1_dev = { NULL, NULL, NULL, NULL, DEV_DISABLE }; -/* Extended instruction decode tables */ - -#define E_V_FL 0 /* flags */ -#define E_M_FL 0xFF -#define E_FP (UNIT_FP >> (UNIT_V_UF - E_V_FL)) -#define E_21MX (UNIT_21MX >> (UNIT_V_UF - E_V_FL)) -#define E_DMS (UNIT_DMS >> (UNIT_V_UF - E_V_FL)) -#define E_IOP (UNIT_IOP >> (UNIT_V_UF - E_V_FL)) -#define E_IOPX (UNIT_IOPX >> (UNIT_V_UF - E_V_FL)) -#define E_V_TY 8 /* type */ -#define E_M_TY 0xF -#define E_NO 0 /* no operands */ -#define E_CN 1 /* PC+1: count */ -#define E_AD 2 /* PC+1: addr */ -#define E_AA 3 /* PC+1,2: addr */ -#define E_AC 4 /* PC+1: addr, +2: count */ -#define E_AZ 5 /* PC+1: addr, +2: zero */ -#define ET_NO (E_NO << E_V_TY) -#define ET_AD (E_AD << E_V_TY) -#define ET_AA (E_AA << E_V_TY) -#define ET_CN (E_CN << E_V_TY) -#define ET_AC (E_AC << E_V_TY) -#define ET_AZ (E_AZ << E_V_TY) -#define E_V_TYI 12 /* type if 2100 IOP */ -#define E_GETFL(x) (((x) >> E_V_FL) & E_M_FL) -#define E_GETTY(f,x) (((x) >> \ - ((((f) & E_IOP) && (cpu_unit.flags & UNIT_IOP))? \ - E_V_TYI: E_V_TY)) & E_M_TY) -#define F_NO E_FP | ET_NO -#define F_MR E_FP | ET_AD -#define X_NO E_21MX | ET_NO -#define X_MR E_21MX | ET_AD -#define X_AA E_21MX | ET_AA -#define X_AZ E_21MX | ET_AZ -#define D_NO E_DMS | ET_NO -#define D_MR E_DMS | ET_AD -#define D_AA E_DMS | ET_AA -#define M_NO E_IOPX | ET_NO -#define M_CN E_IOPX | ET_CN -#define M_AC E_IOPX | ET_AC -#define I_NO E_IOP | (ET_NO << (E_V_TYI - E_V_TY)) -#define I_CN E_IOP | (ET_CN << (E_V_TYI - E_V_TY)) -#define I_AC E_IOP | (ET_AC << (E_V_TYI - E_V_TY)) -#define I_AZ E_IOP | (ET_AZ << (E_V_TYI - E_V_TY)) - -static const uint32 e_inst[512] = { - F_MR | I_AC,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* FAD/ILIST */ - F_MR | I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, /* FSB/LAI- */ - I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, - F_MR | I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, /* FMP/LAI+ */ - I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, - F_MR | I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, /* FDV/SAI- */ - I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, - F_NO | I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, /* FIX/SAI+ */ - I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, - F_NO | I_AZ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* FLT/MBYTE */ - 0,0,0,0,0,0,0,0,I_CN,0,0,0,0,0,0,0, /* CRC */ - I_CN,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* TRSLT */ - I_AZ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* WMOVE */ - I_NO,I_NO,I_NO,I_NO,0,0,0,0,0,0,0,0,0,0,0,0, /* READF,PFRIO,PFREI,PFREX */ - I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,I_NO, /* ENQ,PENQ */ - I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* DEQ */ - I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* SBYTE */ - I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* LBYTE */ - I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* REST */ - 0,0,I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0, /* SAVE */ - M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO, /* LAI-/SAI- */ - M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO, - M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO, /* LAI+/SAI+ */ - M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0440 */ - M_CN,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_CN, /* CRC,REST,READF,INS,ENQ,PENQ,DEQ,TR */ - M_AC,M_NO,M_NO,M_NO,M_NO,0,0,0, /* ILIST,PFREI,PFREX,PFRIO,SAVE */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0500 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0520 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0540 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0560 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0600 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0620 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0640 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0660 */ - D_NO,D_NO,D_NO,D_NO,D_NO,D_NO,D_NO,D_NO, /* XMM,test,MBI,MBF,MBW,MWI,MWF,MWW */ - D_NO,D_NO,D_NO,D_NO,D_MR,D_AA,D_NO,D_NO, /* SY*,US*,PA*,PB*,SSM,JRS,nop,nop */ - D_NO,D_NO,D_NO,D_NO,D_MR,D_MR,D_MR,D_NO, /* XMM,XMS,XM*,nop,XL*,XS*,XC*,LF* */ - D_NO,D_NO,D_MR,D_MR,D_MR,D_MR,D_MR,D_MR, /* RS*,RV*,DJP,DJS,SJP,SJS,UJP,UJS */ - X_MR,X_NO,X_MR,X_MR,X_NO,X_MR,X_MR,X_NO, /* S*X,C*X,L*X,STX,CX*,LDX,ADX,X*X */ - X_MR,X_NO,X_MR,X_MR,X_NO,X_MR,X_MR,X_NO, /* S*Y,C*Y,L*Y,STY,CY*,LDY,ADY,X*Y */ - X_NO,X_NO,X_MR,X_NO,X_NO,X_AZ,X_AZ,X_NO, /* ISX,DSX,JLY,LBT,SBT,MBT,CBT,SFB */ - X_NO,X_NO,X_NO,X_AA,X_AA,X_AA,X_AZ,X_AZ }; /* ISY,DSY,JPY,SBS,CBS,TBS,CMW,MVW */ - /* Interrupt defer table */ static const int32 defer_tab[] = { 0, 1, 1, 1, 0, 0, 0, 1 }; @@ -808,12 +677,10 @@ reason = 0; if (mp_dev.flags & DEV_DIS) dtab[PRO] = NULL; else dtab[PRO] = &proio; /* set up MP dispatch */ if (dma0_dev.flags & DEV_DIS) dtab[DMA0] = dtab[DMALT0] = NULL; -else { /* set up DMA0 dispatch */ - dtab[DMA0] = &dmpio; +else { dtab[DMA0] = &dmpio; /* set up DMA0 dispatch */ dtab[DMALT0] = &dmsio; } if (dma1_dev.flags & DEV_DIS) dtab[DMA1] = dtab[DMALT1] = NULL; -else { /* set up DMA1 dispatch */ - dtab[DMA1] = &dmpio; +else { dtab[DMA1] = &dmpio; /* set up DMA1 dispatch */ dtab[DMALT1] = &dmsio; } for (i = VARDEV; i <= I_DEVMASK; i++) dtab[i] = NULL; /* clr disp table */ @@ -855,11 +722,7 @@ intrq = calc_int (); /* recalc interrupts */ /* Main instruction fetch/decode loop */ while (reason == 0) { /* loop until halted */ -uint32 IR, MA, M1, absel, v1, v2, t; -uint32 fop, eop, etype, eflag; -uint32 skip, mapi, mapj, qs, rs; -uint32 awc, sc, wc, hp, tp; -int32 sop1, sop2; +uint32 IR, MA, absel, v1, t, skip; if (sim_interval <= 0) { /* check clock queue */ if (reason = sim_process_event ()) break; @@ -886,7 +749,7 @@ if (dmarq) { if (intrq && ((intrq <= PRO) || !ion_defer)) { /* interrupt request? */ iotrap = 1; /* I/O trap cell instr */ clrFBF (intrq); /* clear flag buffer */ - if (intrq == PRO) clrFLG (PRO); /* MP flag follows flag buffer */ + if (intrq == PRO) clrFLG (PRO); /* MP flag follows fbuf */ intaddr = intrq; /* save int addr */ if (dms_enb) dms_sr = dms_sr | MST_ENBI; /* dms enabled? */ else dms_sr = dms_sr & ~MST_ENBI; @@ -942,18 +805,21 @@ case 0224:case 0225:case 0226:case 0227: if (reason = Ea (IR, &MA, intrq)) break; /* AND */ AR = AR & ReadW (MA); break; + case 0030:case 0031:case 0032:case 0033: case 0034:case 0035:case 0036:case 0037: case 0230:case 0231:case 0232:case 0233: case 0234:case 0235:case 0236:case 0237: if (reason = Ea (IR, &MA, intrq)) break; /* JSB */ - if ((mp_unit.flags & UNIT_MP_JSB) && CTL (PRO) && (MA < mp_fence)) - ABORT (ABORT_PRO); /* MP if W7 (JSB) out */ + if ((mp_unit.flags & UNIT_MP_JSB) && /* MP if W7 (JSB) out */ + CTL (PRO) && (MA < mp_fence)) + ABORT (ABORT_PRO); WriteW (MA, PC); /* store PC */ PCQ_ENTRY; PC = (MA + 1) & VAMASK; /* jump */ if (IR & I_IA) ion_defer = 1; /* ind? defer intr */ break; + case 0040:case 0041:case 0042:case 0043: case 0044:case 0045:case 0046:case 0047: case 0240:case 0241:case 0242:case 0243: @@ -961,6 +827,7 @@ case 0244:case 0245:case 0246:case 0247: if (reason = Ea (IR, &MA, intrq)) break; /* XOR */ AR = AR ^ ReadW (MA); break; + case 0050:case 0051:case 0052:case 0053: case 0054:case 0055:case 0056:case 0057: case 0250:case 0251:case 0252:case 0253: @@ -971,6 +838,7 @@ case 0254:case 0255:case 0256:case 0257: PC = MA; /* jump */ if (IR & I_IA) ion_defer = 1; /* ind? defer int */ break; + case 0060:case 0061:case 0062:case 0063: case 0064:case 0065:case 0066:case 0067: case 0260:case 0261:case 0262:case 0263: @@ -978,6 +846,7 @@ case 0264:case 0265:case 0266:case 0267: if (reason = Ea (IR, &MA, intrq)) break; /* IOR */ AR = AR | ReadW (MA); break; + case 0070:case 0071:case 0072:case 0073: case 0074:case 0075:case 0076:case 0077: case 0270:case 0271:case 0272:case 0273: @@ -1001,6 +870,7 @@ case 0304:case 0305:case 0306:case 0307: if (((~AR ^ v1) & (AR ^ t)) & SIGN) O = 1; AR = t & DMASK; break; + case 0110:case 0111:case 0112:case 0113: case 0114:case 0115:case 0116:case 0117: case 0310:case 0311:case 0312:case 0313: @@ -1012,6 +882,7 @@ case 0314:case 0315:case 0316:case 0317: if (((~BR ^ v1) & (BR ^ t)) & SIGN) O = 1; BR = t & DMASK; break; + case 0120:case 0121:case 0122:case 0123: case 0124:case 0125:case 0126:case 0127: case 0320:case 0321:case 0322:case 0323: @@ -1019,6 +890,7 @@ case 0324:case 0325:case 0326:case 0327: if (reason = Ea (IR, &MA, intrq)) break; /* CPA */ if (AR != ReadW (MA)) PC = (PC + 1) & VAMASK; break; + case 0130:case 0131:case 0132:case 0133: case 0134:case 0135:case 0136:case 0137: case 0330:case 0331:case 0332:case 0333: @@ -1026,6 +898,7 @@ case 0334:case 0335:case 0336:case 0337: if (reason = Ea (IR, &MA, intrq)) break; /* CPB */ if (BR != ReadW (MA)) PC = (PC + 1) & VAMASK; break; + case 0140:case 0141:case 0142:case 0143: case 0144:case 0145:case 0146:case 0147: case 0340:case 0341:case 0342:case 0343: @@ -1033,6 +906,7 @@ case 0344:case 0345:case 0346:case 0347: if (reason = Ea (IR, &MA, intrq)) break; /* LDA */ AR = ReadW (MA); break; + case 0150:case 0151:case 0152:case 0153: case 0154:case 0155:case 0156:case 0157: case 0350:case 0351:case 0352:case 0353: @@ -1040,6 +914,7 @@ case 0354:case 0355:case 0356:case 0357: if (reason = Ea (IR, &MA, intrq)) break; /* LDB */ BR = ReadW (MA); break; + case 0160:case 0161:case 0162:case 0163: case 0164:case 0165:case 0166:case 0167: case 0360:case 0361:case 0362:case 0363: @@ -1047,6 +922,7 @@ case 0364:case 0365:case 0366:case 0367: if (reason = Ea (IR, &MA, intrq)) break; /* STA */ WriteW (MA, AR); break; + case 0170:case 0171:case 0172:case 0173: case 0174:case 0175:case 0176:case 0177: case 0370:case 0371:case 0372:case 0373: @@ -1097,7 +973,7 @@ case 0014:case 0015:case 0016:case 0017: ABREG[absel] = t; /* store result */ PC = (PC + skip) & VAMASK; /* add in skip */ break; /* end if alter/skip */ - + /* Shift instructions */ case 0000:case 0001:case 0002:case 0003: @@ -1118,832 +994,24 @@ case 0214:case 0215:case 0216:case 0217: intrq = calc_int (); /* recalc interrupts */ break; /* end if I/O */ -/* Extended arithmetic - - The 21MX-E adds three "special instructions" that do not exist in earlier - CPUs, including the 21MX-M. They are: TIMER (100060), EXECUTE (100120), and - DIAG (100000). On the 21MX-M, these instruction codes map to the - microroutines for MPY, ASL, and RRL, respectively. - - Under simulation, these cause undefined instruction stops if the CPU is set - to 2100 or 2116. They do not cause stops on the 21MX-M, as TIMER in - particular is used by several HP programs to differentiate between M- and - E-series machines. */ +/* Extended arithmetic */ case 0200: /* EAU group 0 */ - if ((cpu_unit.flags & UNIT_EAU) == 0) { /* implemented? */ - reason = stop_inst; - break; } - switch ((IR >> 4) & 017) { /* decode IR<7:4> */ - case 005: /* EXECUTE */ - if (!(cpu_unit.flags & UNIT_21MX)) { /* must be 21MX */ - reason = stop_inst; /* trap if not */ - break; } - else if (!(cpu_unit.flags & UNIT_MXM)) { /* E-series? */ - PC = (PC + 1) & VAMASK; /* not simulated */ - break; } - case 001: /* ASL (+ EXECUTE on 21MX-M) */ - sc = (IR & 017)? (IR & 017): 16; /* get sc */ - O = 0; /* clear ovflo */ - while (sc-- != 0) { /* bit by bit */ - t = BR << 1; /* shift B */ - BR = (BR & SIGN) | (t & 077777) | (AR >> 15); - AR = (AR << 1) & DMASK; - if ((BR ^ t) & SIGN) O = 1; } - break; - case 002: /* LSL */ - sc = (IR & 017)? (IR & 017): 16; /* get sc */ - BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK; - AR = (AR << sc) & DMASK; /* BR'AR lsh left */ - break; - case 000: /* DIAG */ - if (!(cpu_unit.flags & UNIT_21MX)) { /* must be 21MX */ - reason = stop_inst; /* trap if not */ - break; } - else if (!(cpu_unit.flags & UNIT_MXM)) /* E-series? */ - break; /* is NOP unless halted */ - case 004: /* RRL (+ DIAG on 21MX-M) */ - sc = (IR & 017)? (IR & 017): 16; /* get sc */ - t = BR; /* BR'AR rot left */ - BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK; - AR = ((AR << sc) | (t >> (16 - sc))) & DMASK; - break; - case 003: /* TIMER */ - if (!(cpu_unit.flags & UNIT_21MX)) { /* must be 21MX */ - reason = stop_inst; /* trap if not */ - break; } - else if (!(cpu_unit.flags & UNIT_MXM)) { /* E-series? */ - BR = (BR + 1) & DMASK; /* increment B */ - if (BR) PC = err_PC; /* if !=0, repeat */ - break; } - case 010: /* MPY (+ TIMER on 21MX-M) */ - if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ - sop1 = SEXT (AR); /* sext AR */ - sop2 = SEXT (ReadW (MA)); /* sext mem */ - sop1 = sop1 * sop2; /* signed mpy */ - BR = (sop1 >> 16) & DMASK; /* to BR'AR */ - AR = sop1 & DMASK; - O = 0; /* no overflow */ - break; - default: - reason = stop_inst; - break; } - break; case 0201: /* divide */ - if ((cpu_unit.flags & UNIT_EAU) == 0) { /* implemented? */ - reason = stop_inst; - break; } - if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ - if (rs = qs = BR & SIGN) { /* save divd sign, neg? */ - AR = (~AR + 1) & DMASK; /* make B'A pos */ - BR = (~BR + (AR == 0)) & DMASK; } /* make divd pos */ - v2 = ReadW (MA); /* divr = mem */ - if (v2 & SIGN) { /* neg? */ - v2 = (~v2 + 1) & DMASK; /* make divr pos */ - qs = qs ^ SIGN; } /* sign of quotient */ - if (BR >= v2) O = 1; /* divide work? */ - else { /* maybe... */ - O = 0; /* assume ok */ - v1 = (BR << 16) | AR; /* 32b divd */ - AR = (v1 / v2) & DMASK; /* quotient */ - BR = (v1 % v2) & DMASK; /* remainder */ - if (AR) { /* quotient > 0? */ - if (qs) AR = (~AR + 1) & DMASK; /* apply quo sign */ - if ((AR ^ qs) & SIGN) O = 1; } /* still wrong? ovflo */ - if (rs) BR = (~BR + 1) & DMASK; } /* apply rem sign */ - break; case 0202: /* EAU group 2 */ - if ((cpu_unit.flags & UNIT_EAU) == 0) { /* implemented? */ - reason = stop_inst; - break; } - switch ((IR >> 4) & 017) { /* decode IR<7:4> */ - case 001: /* ASR */ - sc = (IR & 017)? (IR & 017): 16; /* get sc */ - AR = ((BR << (16 - sc)) | (AR >> sc)) & DMASK; - BR = (SEXT (BR) >> sc) & DMASK; /* BR'AR ash right */ - O = 0; - break; - case 002: /* LSR */ - sc = (IR & 017)? (IR & 017): 16; /* get sc */ - AR = ((BR << (16 - sc)) | (AR >> sc)) & DMASK; - BR = BR >> sc; /* BR'AR log right */ - break; - case 004: /* RRR */ - sc = (IR & 017)? (IR & 017): 16; /* get sc */ - t = AR; /* BR'AR rot right */ - AR = ((AR >> sc) | (BR << (16 - sc))) & DMASK; - BR = ((BR >> sc) | (t << (16 - sc))) & DMASK; - break; - default: - reason = stop_inst; - break; } - break; case 0210: /* DLD */ - if ((cpu_unit.flags & UNIT_EAU) == 0) { /* implemented? */ - reason = stop_inst; - break; } - if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ - AR = ReadW (MA); /* load AR */ - MA = (MA + 1) & VAMASK; - BR = ReadW (MA); /* load BR */ - break; case 0211: /* DST */ - if ((cpu_unit.flags & UNIT_EAU) == 0) { /* get opnd addr */ - reason = stop_inst; - break; } - if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ - WriteW (MA, AR); /* store AR */ - MA = (MA + 1) & VAMASK; - WriteW (MA, BR); /* store BR */ + reason = cpu_eau (IR, intrq); /* extended arith */ break; - + /* Extended instructions */ case 0212: /* MAC0 ext */ -case 0203:case 0213: /* MAC1 ext */ - eop = IR & 0777; /* extended opcode */ - eflag = E_GETFL (e_inst[eop]); /* get flags */ - if ((eflag & (cpu_unit.flags >> UNIT_V_UF)) == 0) { - reason = stop_inst; /* invalid? error */ - break; } - etype = E_GETTY (eflag, e_inst[eop]); /* get format */ - if (etype > E_CN) { /* at least 1 addr? */ - if (reason = Ea1 (&MA, intrq)) break; } /* get first address */ - if ((etype == E_AC) || (etype == E_CN)) { /* addr + cnt, cnt */ - wc = ReadW (PC); /* get count */ - awc = PC; /* addr of count */ - PC = (PC + 1) & VAMASK; } - else if (etype == E_AZ) { /* addr + zero */ - wc = ReadW (MA); /* get wc */ - awc = PC; /* addr of interim */ - if (wc) { /* wc > 0? */ - if (t = ReadW (PC)) wc = t; } /* use interim if nz */ - WriteW (awc, 0); /* clear interim */ - PC = (PC + 1) & VAMASK; } - else if (etype == E_AA) { /* second addr */ - if (reason = Ea1 (&M1, intrq)) break; } /* get second address */ - - switch (eop) { /* decode IR<8:0> */ - -/* Floating point instructions */ - - case 0000: /* IOP ILIST/FAD */ - if (cpu_unit.flags & UNIT_IOP) /* ILIST (E_AC) */ - goto IOP_ILIST; - fop = ReadF (MA); /* get fop */ - O = f_as (fop, 0); /* add, upd ovflo */ - break; - case 0020: /* IOP LAI-/FSB */ - if (cpu_unit.flags & UNIT_IOP) /* LAI -20 (I_NO) */ - goto IOP_LAIM; - fop = ReadF (MA); /* get fop */ - O = f_as (fop, 1); /* sub, upd ovflo */ - break; - case 0040: /* IOP LAI+/FMP */ - if (cpu_unit.flags & UNIT_IOP) /* LAI 0 (I_NO) */ - goto IOP_LAIP; - fop = ReadF (MA); /* get fop */ - O = f_mul (fop); /* mul, upd ovflo */ - break; - case 0060: /* IOP SAI-/FDV */ - if (cpu_unit.flags & UNIT_IOP) /* SAI -20 (I_NO) */ - goto IOP_SAIM; - fop = ReadF (MA); /* get fop */ - O = f_div (fop); /* div, upd ovflo */ - break; - case 0100: /* IOP SAI+/FIX */ - if (cpu_unit.flags & UNIT_IOP) /* SAI 0 (I_NO) */ - goto IOP_SAIP; - O = f_fix (); /* FIX (E_NO) */ - break; - case 0120: /* IOP MBYTE/FLT */ - if (cpu_unit.flags & UNIT_IOP) /* MBYTE (I_AZ) */ - goto IOP_MBYTE; - O = f_flt (); /* FLT (E_NO) */ - break; - -/* 2100 (and 21MX) IOP instructions */ - - IOP_LAIM: case 0021: case 0022: case 0023: /* IOP LAI- (I_NO) */ - case 0024: case 0025: case 0026: case 0027: - case 0030: case 0031: case 0032: case 0033: - case 0034: case 0035: case 0036: case 0037: - MA = ((IR | 0177760) + BR) & VAMASK; /* IR<3:0> = -offset */ - AR = ReadW (MA); /* load AR */ - break; - IOP_LAIP: case 0041: case 0042: case 0043: /* IOP LAI+ (I_NO) */ - case 0044: case 0045: case 0046: case 0047: - case 0050: case 0051: case 0052: case 0053: - case 0054: case 0055: case 0056: case 0057: - MA = ((IR & 017) + BR) & VAMASK; /* IR<3:0> = +offset */ - AR = ReadW (MA); /* load AR */ - break; - IOP_SAIM: case 0061: case 0062: case 0063: /* IOP SAI- (I_NO) */ - case 0064: case 0065: case 0066: case 0067: - case 0070: case 0071: case 0072: case 0073: - case 0074: case 0075: case 0076: case 0077: - MA = ((IR | 0177760) + BR) & VAMASK; /* IR<3:0> = -offset */ - WriteW (MA, AR); /* store AR */ - break; - IOP_SAIP: case 0101: case 0102: case 0103: /* IOP SAI+ (I_NO) */ - case 0104: case 0105: case 0106: case 0107: - case 0110: case 0111: case 0112: case 0113: - case 0114: case 0115: case 0116: case 0117: - MA = ((IR & 017) + BR) & VAMASK; /* IR<3:0> = +offset */ - WriteW (MA, AR); /* store AR */ - break; - case 0150: /* IOP CRC (I_CN) */ - case 0460: /* IOPX CRC (I_CN) */ - t = (AR & 0xFF) ^ wc; /* start CRC */ - for (i = 0; i < 8; i++) { /* apply polynomial */ - t = (t >> 1) | ((t & 1) << 15); /* rotate right */ - if (t & SIGN) t = t ^ 020001; } /* old t<0>? xor */ - WriteW (awc, t); /* rewrite CRC */ - break; - case 0160: /* IOP TRSLT (I_CN) */ - case 0467: /* IOPX TRSLT (I_CN) */ - if (wc & SIGN) break; /* cnt < 0? */ - while (wc != 0) { /* loop */ - MA = (AR + AR + ReadB (BR)) & VAMASK; - t = ReadB (MA); /* xlate */ - WriteB (BR, t); /* store char */ - BR = (BR + 1) & DMASK; /* incr ptr */ - wc = (wc - 1) & DMASK; /* decr cnt */ - WriteW (awc, wc); - if (wc && intrq) { /* more and intr? */ - PC = err_PC; /* stop for now */ - break; } } - break; - case 0220: /* IOP READF (I_NO) */ - case 0462: /* IOPX READF (I_NO) */ - AR = iop_sp; /* copy stk ptr */ - break; - case 0221: /* IOP PRFIO (I_NO) */ - case 0473: /* IOPX PFRIO (I_NO) */ - t = ReadW (PC); /* get IO instr */ - PC = (PC + 1) & VAMASK; - WriteW (PC, 1); /* set flag */ - PC = (PC + 1) & VAMASK; - reason = iogrp (t, 0); /* execute instr */ - dmarq = calc_dma (); /* recalc DMA */ - intrq = calc_int (); /* recalc interrupts */ - break; - case 0222: /* IOP PRFEI (I_NO) */ - case 0471: /* IOPX PFREI (I_NO) */ - t = ReadW (PC); /* get IO instr */ - PC = (PC + 1) & VAMASK; - WriteW (PC, 1); /* set flag */ - PC = (PC + 1) & VAMASK; - reason = iogrp (t, 0); /* execute instr */ - dmarq = calc_dma (); /* recalc DMA */ - intrq = calc_int (); /* recalc interrupts */ - /* fall through */ - case 0223: /* IOP PRFEX (I_NO) */ - case 0472: /* IOPX PFREX (I_NO) */ - MA = ReadW (PC); /* exit addr */ - PCQ_ENTRY; - PC = ReadW (MA) & VAMASK; /* jump indirect */ - WriteW (MA, 0); /* clear exit */ - break; - case 0240: /* IOP ENQ (I_NO) */ - case 0464: /* IOPX ENQ (I_NO) */ - hp = ReadW (AR & VAMASK); /* addr of head */ - tp = ReadW ((AR + 1) & VAMASK); /* addr of tail */ - WriteW ((BR - 1) & VAMASK, 0); /* entry link */ - WriteW ((tp - 1) & VAMASK, BR); /* tail link */ - WriteW ((AR + 1) & VAMASK, BR); /* queue tail */ - if (hp != 0) PC = (PC + 1) & VAMASK; /* q not empty? skip */ - break; - case 0257: /* IOP PENQ (I_NO) */ - case 0465: /* IOPX PENQ (I_NO) */ - hp = ReadW (AR & VAMASK); /* addr of head */ - WriteW ((BR - 1) & VAMASK, hp); /* becomes entry link */ - WriteW (AR & VAMASK, BR); /* queue head */ - if (hp == 0) /* q empty? */ - WriteW ((AR + 1) & VAMASK, BR); /* queue tail */ - else PC = (PC + 1) & VAMASK; /* skip */ - break; - case 0260: /* IOP DEQ (I_NO) */ - case 0466: /* IOPX DEQ (I_NO) */ - BR = ReadW (AR & VAMASK); /* addr of head */ - if (BR) { /* queue not empty? */ - hp = ReadW ((BR - 1) & VAMASK); /* read hd entry link */ - WriteW (AR & VAMASK, hp); /* becomes queue head */ - if (hp == 0) /* q now empty? */ - WriteW ((AR + 1) & VAMASK, (AR + 1) & DMASK); - PC = (PC + 1) & VAMASK; } /* skip */ - break; - case 0300: /* IOP SBYTE (I_NO) */ - WriteB (BR, AR); /* store byte */ - BR = (BR + 1) & DMASK; /* incr ptr */ - break; - case 0320: /* IOP LBYTE (I_NO) */ - AR = ReadB (BR); /* load byte */ - BR = (BR + 1) & DMASK; /* incr ptr */ - break; - case 0340: /* IOP REST (I_NO) */ - case 0461: /* IOPX REST (I_NO) */ - iop_sp = (iop_sp - 1) & VAMASK; /* pop E/~O,BR,AR */ - t = ReadW (iop_sp); - O = ((t >> 1) ^ 1) & 1; - E = t & 1; - iop_sp = (iop_sp - 1) & VAMASK; - BR = ReadW (iop_sp); - iop_sp = (iop_sp - 1) & VAMASK; - AR = ReadW (iop_sp); - if (cpu_unit.flags & UNIT_2100) mp_fence = iop_sp; - break; - case 0362: /* IOP SAVE (I_NO) */ - case 0474: /* IOPX SAVE (I_NO) */ - WriteW (iop_sp, AR); /* push AR,BR,E/~O */ - iop_sp = (iop_sp + 1) & VAMASK; - WriteW (iop_sp, BR); - iop_sp = (iop_sp + 1) & VAMASK; - t = ((O ^ 1) << 1) | E; - WriteW (iop_sp, t); - iop_sp = (iop_sp + 1) & VAMASK; - if (cpu_unit.flags & UNIT_2100) mp_fence = iop_sp; - break; - - case 0400: case 0401: case 0402: case 0403: /* IOPX LAI-/SAI- (I_NO) */ - case 0404: case 0405: case 0406: case 0407: - case 0410: case 0411: case 0412: case 0413: - case 0414: case 0415: case 0416: case 0417: - MA = ((IR | 0177760) + BR) & VAMASK; /* IR<3:0> = -offset */ - if (IR & I_AB) AR = ReadW (MA); /* AB = 1? LAI */ - else WriteW (MA, AR); /* AB = 0? SAI */ - break; - case 0420: case 0421: case 0422: case 0423: /* IOPX LAI+/SAI+ (I_NO) */ - case 0424: case 0425: case 0426: case 0427: - case 0430: case 0431: case 0432: case 0433: - case 0434: case 0435: case 0436: case 0437: - MA = ((IR & 017) + BR) & VAMASK; /* IR<3:0> = +offset */ - if (IR & I_AB) AR = ReadW (MA); /* AB = 1? LAI */ - else WriteW (MA, AR); /* AB = 0? SAI */ - break; - case 0463: /* IOPX INS (I_NO) */ - iop_sp = AR; /* init stk ptr */ - break; - case 0470: /* IOPX ILIST (I_CN) */ - IOP_ILIST: - do { /* for count */ - WriteW (MA, AR); /* write AR to mem */ - AR = (AR + 1) & DMASK; /* incr AR */ - MA = (MA + 1) & VAMASK; /* incr MA */ - wc = (wc - 1) & DMASK; } /* decr count */ - while (wc != 0); - break; - -/* DMS instructions, move alternate - interruptible - - DMS privilege violation rules are - - load map and CTL set (XMM, XMS, XM*, SY*, US*, PA*, PB*) - - load state or fence and UMAP set (JRS, DJP, DJS, SJP, SJS, UJP, UJS, LF*) - - The 21MX manual is incorrect in stating that M*I, M*W, XS* are privileged */ - - case 0701: /* self test */ - ABREG[absel] = ABREG[absel] ^ DMASK; /* CMA or CMB */ - break; - case 0702: /* MBI (E_NO) */ - AR = AR & ~1; /* force A, B even */ - BR = BR & ~1; - while (XR != 0) { /* loop */ - t = ReadB (AR); /* read curr */ - WriteBA (BR, t); /* write alt */ - AR = (AR + 1) & DMASK; /* incr ptrs */ - BR = (BR + 1) & DMASK; - XR = (XR - 1) & DMASK; - if (XR && intrq && !(AR & 1)) { /* more, int, even? */ - PC = err_PC; /* stop for now */ - break; } } - break; - case 0703: /* MBF (E_NO) */ - AR = AR & ~1; /* force A, B even */ - BR = BR & ~1; - while (XR != 0) { /* loop */ - t = ReadBA (AR); /* read alt */ - WriteB (BR, t); /* write curr */ - AR = (AR + 1) & DMASK; /* incr ptrs */ - BR = (BR + 1) & DMASK; - XR = (XR - 1) & DMASK; - if (XR && intrq && !(AR & 1)) { /* more, int, even? */ - PC = err_PC; /* stop for now */ - break; } } - break; - case 0704: /* MBW (E_NO) */ - AR = AR & ~1; /* force A, B even */ - BR = BR & ~1; - while (XR != 0) { /* loop */ - t = ReadBA (AR); /* read alt */ - WriteBA (BR, t); /* write alt */ - AR = (AR + 1) & DMASK; /* incr ptrs */ - BR = (BR + 1) & DMASK; - XR = (XR - 1) & DMASK; - if (XR && intrq && !(AR & 1)) { /* more, int, even? */ - PC = err_PC; /* stop for now */ - break; } } - break; - case 0705: /* MWI (E_NO) */ - while (XR != 0) { /* loop */ - t = ReadW (AR & VAMASK); /* read curr */ - WriteWA (BR & VAMASK, t); /* write alt */ - AR = (AR + 1) & DMASK; /* incr ptrs */ - BR = (BR + 1) & DMASK; - XR = (XR - 1) & DMASK; - if (XR && intrq) { /* more and intr? */ - PC = err_PC; /* stop for now */ - break; } } - break; - case 0706: /* MWF (E_NO) */ - while (XR != 0) { /* loop */ - t = ReadWA (AR & VAMASK); /* read alt */ - WriteW (BR & VAMASK, t); /* write curr */ - AR = (AR + 1) & DMASK; /* incr ptrs */ - BR = (BR + 1) & DMASK; - XR = (XR - 1) & DMASK; - if (XR && intrq) { /* more and intr? */ - PC = err_PC; /* stop for now */ - break; } } - break; - case 0707: /* MWW (E_NO) */ - while (XR != 0) { /* loop */ - t = ReadWA (AR & VAMASK); /* read alt */ - WriteWA (BR & VAMASK, t); /* write alt */ - AR = (AR + 1) & DMASK; /* incr ptrs */ - BR = (BR + 1) & DMASK; - XR = (XR - 1) & DMASK; - if (XR && intrq) { /* more and intr? */ - PC = err_PC; /* stop for now */ - break; } } - break; - -/* DMS, continued */ - - case 0710: /* SYA, SYB (E_NO) */ - case 0711: /* USA, USB (E_NO) */ - case 0712: /* PAA, PAB (E_NO) */ - case 0713: /* PBA, PBB (E_NO) */ - mapi = (IR & 03) << VA_N_PAG; /* map base */ - if (ABREG[absel] & SIGN) { /* store? */ - for (i = 0; i < MAP_LNT; i++) { - t = dms_rmap (mapi + i); /* map to memory */ - WriteW ((ABREG[absel] + i) & VAMASK, t); } } - else { /* load */ - dms_viol (err_PC, MVI_PRV); /* priv if PRO */ - for (i = 0; i < MAP_LNT; i++) { - t = ReadW ((ABREG[absel] + i) & VAMASK); - dms_wmap (mapi + i, t); } } /* mem to map */ - ABREG[absel] = (ABREG[absel] + MAP_LNT) & DMASK; - break; - case 0714: /* SSM (E_AD) */ - WriteW (MA, dms_upd_sr ()); /* store stat */ - break; - case 0715: /* JRS (E_AA) */ - if (dms_ump) dms_viol (err_PC, MVI_PRV); - t = ReadW (MA); /* get status */ - dms_enb = 0; /* assume off */ - dms_ump = SMAP; - if (t & 0100000) { /* set enable? */ - dms_enb = 1; - if (t & 0040000) dms_ump = UMAP; } /* set/clr usr */ - PCQ_ENTRY; /* save old PC */ - PC = M1; /* jump */ - ion_defer = 1; /* defer intr */ - break; - -/* DMS, continued */ - - case 0700: case 0720: /* XMM (E_NO) */ - if (XR == 0) break; /* nop? */ - while (XR != 0) { /* loop */ - if (XR & SIGN) { /* store? */ - t = dms_rmap (AR); /* map to mem */ - WriteW (BR & VAMASK, t); - XR = (XR + 1) & DMASK; } - else { /* load */ - dms_viol (err_PC, MVI_PRV); /* priv if PRO */ - t = ReadW (BR & VAMASK); /* mem to map */ - dms_wmap (AR, t); - XR = (XR - 1) & DMASK; } - AR = (AR + 1) & DMASK; - BR = (BR + 1) & DMASK; - if (intrq && ((XR & 0xF) == 0xF)) { /* intr, cnt4 = F? */ - PC = err_PC; /* stop for now */ - break; } } - break; - case 0721: /* XMS (E_NO) */ - if ((XR & SIGN) || (XR == 0)) break; /* nop? */ - dms_viol (err_PC, MVI_PRV); /* priv if PRO */ - while (XR != 0) { - dms_wmap (AR, BR); /* AR to map */ - XR = (XR - 1) & DMASK; - AR = (AR + 1) & DMASK; - BR = (BR + 1) & DMASK; - if (intrq && ((XR & 0xF) == 0xF)) { /* intr, cnt4 = F? */ - PC = err_PC; - break; } } - break; - case 0722: /* XMA, XMB (E_NO) */ - dms_viol (err_PC, MVI_PRV); /* priv if PRO */ - if (ABREG[absel] & 0100000) mapi = UMAP; - else mapi = SMAP; - if (ABREG[absel] & 0000001) mapj = PBMAP; - else mapj = PAMAP; - for (i = 0; i < MAP_LNT; i++) { - t = dms_rmap (mapi + i); /* read map */ - dms_wmap (mapj + i, t); } /* write map */ - break; - case 0724: /* XLA, XLB (E_AD) */ - ABREG[absel] = ReadWA (MA); /* load alt */ - break; - case 0725: /* XSA, XSB (E_AD) */ - WriteWA (MA, ABREG[absel]); /* store alt */ - break; - case 0726: /* XCA, XCB (E_AD) */ - if (ABREG[absel] != ReadWA (MA)) /* compare alt */ - PC = (PC + 1) & VAMASK; - break; - case 0727: /* LFA, LFB (E_NO) */ - if (dms_ump) dms_viol (err_PC, MVI_PRV); - dms_sr = (dms_sr & ~(MST_FLT | MST_FENCE)) | - (ABREG[absel] & (MST_FLT | MST_FENCE)); - break; - -/* DMS, continued */ - - case 0730: /* RSA, RSB (E_NO) */ - ABREG[absel] = dms_upd_sr (); /* save stat */ - break; - case 0731: /* RVA, RVB (E_NO) */ - ABREG[absel] = dms_vr; /* save viol */ - break; - case 0732: /* DJP (E_AD) */ - if (dms_ump) dms_viol (err_PC, MVI_PRV); - mp_dms_jmp (MA); /* validate jump addr */ - PCQ_ENTRY; /* save curr PC */ - PC = MA; /* new PC */ - dms_enb = 0; /* disable map */ - dms_ump = SMAP; - ion_defer = 1; - break; - case 0733: /* DJS (E_AD) */ - if (dms_ump) dms_viol (err_PC, MVI_PRV); - WriteW (MA, PC); /* store ret addr */ - PCQ_ENTRY; /* save curr PC */ - PC = (MA + 1) & VAMASK; /* new PC */ - dms_enb = 0; /* disable map */ - dms_ump = SMAP; - ion_defer = 1; /* defer intr */ - break; - case 0734: /* SJP (E_AD) */ - if (dms_ump) dms_viol (err_PC, MVI_PRV); - mp_dms_jmp (MA); /* validate jump addr */ - PCQ_ENTRY; /* save curr PC */ - PC = MA; /* jump */ - dms_enb = 1; /* enable system */ - dms_ump = SMAP; - ion_defer = 1; /* defer intr */ - break; - case 0735: /* SJS (E_AD) */ - if (dms_ump) dms_viol (err_PC, MVI_PRV); - t = PC; /* save retn addr */ - PCQ_ENTRY; /* save curr PC */ - PC = (MA + 1) & VAMASK; /* new PC */ - dms_enb = 1; /* enable system */ - dms_ump = SMAP; - WriteW (MA, t); /* store ret addr */ - ion_defer = 1; /* defer intr */ - break; - case 0736: /* UJP (E_AD) */ - if (dms_ump) dms_viol (err_PC, MVI_PRV); - mp_dms_jmp (MA); /* validate jump addr */ - PCQ_ENTRY; /* save curr PC */ - PC = MA; /* jump */ - dms_enb = 1; /* enable user */ - dms_ump = UMAP; - ion_defer = 1; /* defer intr */ - break; - case 0737: /* UJS (E_AD) */ - if (dms_ump) dms_viol (err_PC, MVI_PRV); - t = PC; /* save retn addr */ - PCQ_ENTRY; /* save curr PC */ - PC = (MA + 1) & VAMASK; /* new PC */ - dms_enb = 1; /* enable user */ - dms_ump = UMAP; - WriteW (MA, t); /* store ret addr */ - ion_defer = 1; /* defer intr */ - break; - -/* Index register instructions */ - - case 0740: /* SAX, SBX (E_AD) */ - MA = (MA + XR) & VAMASK; /* indexed addr */ - WriteW (MA, ABREG[absel]); /* store */ - break; - case 0741: /* CAX, CBX (E_NO) */ - XR = ABREG[absel]; /* copy to XR */ - break; - case 0742: /* LAX, LBX (E_AD) */ - MA = (MA + XR) & VAMASK; /* indexed addr */ - ABREG[absel] = ReadW (MA); /* load */ - break; - case 0743: /* STX (E_AD) */ - WriteW (MA, XR); /* store XR */ - break; - case 0744: /* CXA, CXB (E_NO) */ - ABREG[absel] = XR; /* copy from XR */ - break; - case 0745: /* LDX (E_AD)*/ - XR = ReadW (MA); /* load XR */ - break; - case 0746: /* ADX (E_AD) */ - v1 = ReadW (MA); /* add to XR */ - t = XR + v1; - if (t > DMASK) E = 1; /* set E, O */ - if (((~XR ^ v1) & (XR ^ t)) & SIGN) O = 1; - XR = t & DMASK; - break; - case 0747: /* XAX, XBX (E_NO) */ - t = XR; /* exchange XR */ - XR = ABREG[absel]; - ABREG[absel] = t; - break; - case 0750: /* SAY, SBY (E_AD) */ - MA = (MA + YR) & VAMASK; /* indexed addr */ - WriteW (MA, ABREG[absel]); /* store */ - break; - case 0751: /* CAY, CBY (E_NO) */ - YR = ABREG[absel]; /* copy to YR */ - break; - case 0752: /* LAY, LBY (E_AD) */ - MA = (MA + YR) & VAMASK; /* indexed addr */ - ABREG[absel] = ReadW (MA); /* load */ - break; - case 0753: /* STY (E_AD) */ - WriteW (MA, YR); /* store YR */ - break; - case 0754: /* CYA, CYB (E_NO) */ - ABREG[absel] = YR; /* copy from YR */ - break; - case 0755: /* LDY (E_AD) */ - YR = ReadW (MA); /* load YR */ - break; - case 0756: /* ADY (E_AD) */ - v1 = ReadW (MA); /* add to YR */ - t = YR + v1; - if (t > DMASK) E = 1; /* set E, O */ - if (((~YR ^ v1) & (YR ^ t)) & SIGN) O = 1; - YR = t & DMASK; - break; - case 0757: /* XAY, XBY (E_NO) */ - t = YR; /* exchange YR */ - YR = ABREG[absel]; - ABREG[absel] = t; - break; - case 0760: /* ISX (E_NO) */ - XR = (XR + 1) & DMASK; /* incr XR */ - if (XR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ - break; - case 0761: /* DSX (E_NO) */ - XR = (XR - 1) & DMASK; /* decr XR */ - if (XR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ - break; - case 0762: /* JLY (E_AD) */ - mp_dms_jmp (MA); /* validate jump addr */ - PCQ_ENTRY; - YR = PC; /* ret addr to YR */ - PC = MA; /* jump */ - break; - case 0770: /* ISY (E_NO) */ - YR = (YR + 1) & DMASK; /* incr YR */ - if (YR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ - break; - case 0771: /* DSY (E_NO) */ - YR = (YR - 1) & DMASK; /* decr YR */ - if (YR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ - break; - case 0772: /* JPY (E_NO) */ - MA = (ReadW (PC) + YR) & VAMASK; /* index, no indir */ - PC = (PC + 1) & VAMASK; - mp_dms_jmp (MA); /* validate jump addr */ - PCQ_ENTRY; - PC = MA; /* jump */ - break; - -/* Byte instructions */ - - case 0763: /* LBT (E_NO) */ - AR = ReadB (BR); /* load byte */ - BR = (BR + 1) & DMASK; /* incr ptr */ - break; - case 0764: /* SBT (E_NO) */ - WriteB (BR, AR); /* store byte */ - BR = (BR + 1) & DMASK; /* incr ptr */ - break; - IOP_MBYTE: /* IOP MBYTE (I_AZ) */ - if (wc & SIGN) break; /* must be positive */ - case 0765: /* MBT (E_AZ) */ - while (wc != 0) { /* while count */ - WriteW (awc, wc); /* for abort */ - t = ReadB (AR); /* move byte */ - WriteB (BR, t); - AR = (AR + 1) & DMASK; /* incr src */ - BR = (BR + 1) & DMASK; /* incr dst */ - wc = (wc - 1) & DMASK; /* decr cnt */ - if (intrq && wc) { /* intr, more to do? */ - PC = err_PC; /* back up PC */ - break; } } /* take intr */ - WriteW (awc, wc); /* clean up inline */ - break; - case 0766: /* CBT (E_AZ) */ - while (wc != 0) { /* while count */ - WriteW (awc, wc); /* for abort */ - v1 = ReadB (AR); /* get src1 */ - v2 = ReadB (BR); /* get src2 */ - if (v1 != v2) { /* compare */ - PC = (PC + 1 + (v1 > v2)) & VAMASK; - BR = (BR + wc) & DMASK; /* update BR */ - wc = 0; /* clr interim */ - break; } - AR = (AR + 1) & DMASK; /* incr src1 */ - BR = (BR + 1) & DMASK; /* incr src2 */ - wc = (wc - 1) & DMASK; /* decr cnt */ - if (intrq && wc) { /* intr, more to do? */ - PC = err_PC; /* back up PC */ - break; } } /* take intr */ - WriteW (awc, wc); /* clean up inline */ - break; - case 0767: /* SFB (E_NO) */ - v1 = AR & 0377; /* test byte */ - v2 = (AR >> 8) & 0377; /* term byte */ - for (;;) { /* scan */ - t = ReadB (BR); /* read byte */ - if (t == v1) break; /* test match? */ - BR = (BR + 1) & DMASK; - if (t == v2) { /* term match? */ - PC = (PC + 1) & VAMASK; - break; } - if (intrq) { /* int pending? */ - PC = err_PC; /* back up PC */ - break; } } /* take intr */ - break; - -/* Bit, word instructions */ - - case 0773: /* SBS (E_AA) */ - v1 = ReadW (MA); - v2 = ReadW (M1); - WriteW (M1, v2 | v1); /* set bit */ - break; - case 0774: /* CBS (E_AA) */ - v1 = ReadW (MA); - v2 = ReadW (M1); - WriteW (M1, v2 & ~v1); /* clear bit */ - break; - case 0775: /* TBS (E_AA) */ - v1 = ReadW (MA); - v2 = ReadW (M1); - if ((v2 & v1) != v1) /* test bits */ - PC = (PC + 1) & VAMASK; - break; - case 0776: /* CMW (E_AZ) */ - while (wc != 0) { /* while count */ - WriteW (awc, wc); /* for abort */ - v1 = ReadW (AR & VAMASK); /* first op */ - v2 = ReadW (BR & VAMASK); /* second op */ - sop1 = (int32) SEXT (v1); /* signed */ - sop2 = (int32) SEXT (v2); - if (sop1 != sop2) { /* compare */ - PC = (PC + 1 + (sop1 > sop2)) & VAMASK; - BR = (BR + wc) & DMASK; /* update BR */ - wc = 0; /* clr interim */ - break; } - AR = (AR + 1) & DMASK; /* incr src1 */ - BR = (BR + 1) & DMASK; /* incr src2 */ - wc = (wc - 1) & DMASK; /* decr cnt */ - if (intrq && wc) { /* intr, more to do? */ - PC = err_PC; /* back up PC */ - break; } } /* take intr */ - WriteW (awc, wc); /* clean up inline */ - break; - case 0200: /* IOP WMOVE (I_AZ) */ - if (wc & SIGN) break; /* must be positive */ - case 0777: /* MVW (E_AZ) */ - while (wc != 0) { /* while count */ - WriteW (awc, wc); /* for abort */ - t = ReadW (AR & VAMASK); /* move word */ - WriteW (BR & VAMASK, t); - AR = (AR + 1) & DMASK; /* incr src */ - BR = (BR + 1) & DMASK; /* incr dst */ - wc = (wc - 1) & DMASK; /* decr cnt */ - if (intrq && wc) { /* intr, more to do? */ - PC = err_PC; /* back up PC */ - break; } } /* take intr */ - WriteW (awc, wc); /* clean up inline */ - break; - default: /* all others NOP */ - break; } /* end case ext */ +case 0203: /* MAC1 ext */ +case 0213: + reason = cpu_mac (IR, intrq); /* extended opcode */ + dmarq = calc_dma (); /* recalc DMA masks */ + intrq = calc_int (); /* recalc interrupts */ break; } /* end case IR */ if (reason == STOP_INDINT) { /* indirect intr? */ @@ -2059,7 +1127,8 @@ ab = (ir & I_AB)? 1: 0; /* get A/B select */ dev = ir & I_DEVMASK; /* get device */ sop = I_GETIOOP (ir); /* get subopcode */ if (!iotrap && CTL (PRO) && /* protected? */ - ((sop == ioHLT) || ((dev != OVF) && (mp_unit.flags & UNIT_MP_SEL1)))) { + ((sop == ioHLT) || /* halt or !ovf? */ + ((dev != OVF) && (mp_unit.flags & UNIT_MP_SEL1)))) { if (sop == ioLIX) ABREG[ab] = 0; /* A/B writes anyway */ ABORT (ABORT_PRO); } iodata = devdisp (dev, sop, ir, ABREG[ab]); /* process I/O */ @@ -2785,7 +1854,7 @@ int32 mc = 0; uint32 i; if ((val <= 0) || (val > PASIZE) || ((val & 07777) != 0) || - (!(uptr->flags & UNIT_21MX) && (val > 32768))) + (!(uptr->flags & UNIT_21MX) && (val > VASIZE))) return SCPE_ARG; if (!(sim_switches & SWMASK ('F'))) { /* force truncation? */ for (i = val; i < MEMSIZE; i++) mc = mc | M[i]; @@ -2904,8 +1973,8 @@ for (i = 0; opt_val[i].cpuf != 0; i++) { if ((opt == UNIT_2116) || (opt == UNIT_2100) || (opt == UNIT_21MX)) { dma0_dev.flags = dma0_dev.flags & ~DEV_DIS; dma1_dev.flags = dma1_dev.flags & ~DEV_DIS; } - if (((opt == UNIT_2116) || (opt == UNIT_2100)) && (MEMSIZE > 32768)) - return cpu_set_size (uptr, 32768, cptr, desc); + if (((opt == UNIT_2116) || (opt == UNIT_2100)) && (MEMSIZE > VASIZE)) + return cpu_set_size (uptr, VASIZE, cptr, desc); return SCPE_OK; } } return SCPE_NOFNC; } @@ -2914,7 +1983,8 @@ return SCPE_NOFNC; t_stat cpu_boot (int32 unitno, DEVICE *dptr) { -extern const uint16 ptr_rom[IBL_LNT], dq_rom[IBL_LNT], ms_rom[IBL_LNT]; +extern const uint16 ptr_rom[IBL_LNT], dq_rom[IBL_LNT]; +extern const uint16 ms_rom[IBL_LNT], ds_rom[IBL_LNT]; int32 dev = (SR >> IBL_V_DEV) & I_DEVMASK; int32 sel = (SR >> IBL_V_SEL) & IBL_M_SEL; @@ -2929,8 +1999,9 @@ case 1: /* DP/DQ boot */ case 2: /* MS boot */ ibl_copy (ms_rom, dev); break; -default: - return SCPE_NOFNC; } +case 3: /* DS boot */ + ibl_copy (ds_rom,dev); + break; } return SCPE_OK; } diff --git a/HP2100/hp2100_cpu.h b/HP2100/hp2100_cpu.h new file mode 100644 index 00000000..ff734158 --- /dev/null +++ b/HP2100/hp2100_cpu.h @@ -0,0 +1,73 @@ +/* hp2100_cpu.h: HP 2100 CPU definitions + + Copyright (c) 2005, 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"), + 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 + ROBERT M SUPNIK 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 Robert M Supnik shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Robert M Supnik. + + 14-Jan-05 RMS Cloned from hp2100_cpu.c +*/ + +#ifndef _HP2100_CPU_H_ +#define _HP2100_CPU_H_ 0 + +#define PCQ_SIZE 64 /* must be 2**n */ +#define PCQ_MASK (PCQ_SIZE - 1) +#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = err_PC + +#define UNIT_V_2100 (UNIT_V_UF + 0) /* 2100 */ +#define UNIT_V_21MX (UNIT_V_UF + 1) /* 21MX-E or 21MX-M */ +#define UNIT_V_EAU (UNIT_V_UF + 2) /* EAU */ +#define UNIT_V_FP (UNIT_V_UF + 3) /* FP */ +#define UNIT_V_DMS (UNIT_V_UF + 4) /* DMS */ +#define UNIT_V_IOP (UNIT_V_UF + 5) /* 2100 IOP */ +#define UNIT_V_IOPX (UNIT_V_UF + 6) /* 21MX IOP */ +#define UNIT_V_MSIZE (UNIT_V_UF + 7) /* dummy mask */ +#define UNIT_V_MXM (UNIT_V_UF + 8) /* 21MX is M-series */ +#define UNIT_2116 (0) +#define UNIT_2100 (1 << UNIT_V_2100) +#define UNIT_21MX (1 << UNIT_V_21MX) +#define UNIT_EAU (1 << UNIT_V_EAU) +#define UNIT_FP (1 << UNIT_V_FP) +#define UNIT_DMS (1 << UNIT_V_DMS) +#define UNIT_IOP (1 << UNIT_V_IOP) +#define UNIT_IOPX (1 << UNIT_V_IOPX) +#define UNIT_MSIZE (1 << UNIT_V_MSIZE) +#define UNIT_MXM (1 << UNIT_V_MXM) + +t_stat Ea (uint32 IR, uint32 *addr, uint32 irq); +uint8 ReadB (uint32 addr); +uint8 ReadBA (uint32 addr); +uint16 ReadW (uint32 addr); +uint16 ReadWA (uint32 addr); +uint32 ReadF (uint32 addr); +void WriteB (uint32 addr, uint32 dat); +void WriteBA (uint32 addr, uint32 dat); +void WriteW (uint32 addr, uint32 dat); +void WriteWA (uint32 addr, uint32 dat); +t_stat iogrp (uint32 ir, uint32 iotrap); +void mp_dms_jmp (uint32 va); +uint16 dms_rmap (uint32 mapi); +void dms_wmap (uint32 mapi, uint32 dat); +void dms_viol (uint32 va, uint32 st); +uint32 dms_upd_sr (void); + +#endif diff --git a/HP2100/hp2100_cpu1.c b/HP2100/hp2100_cpu1.c new file mode 100644 index 00000000..6300159c --- /dev/null +++ b/HP2100/hp2100_cpu1.c @@ -0,0 +1,982 @@ +/* hp2100_cpu.c: HP 2100 EAU and MAC simulator + + Copyright (c) 2005, 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"), + 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 + ROBERT M SUPNIK 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 Robert M Supnik shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Robert M Supnik. + + CPU extended arithmetic and microcode instructions + + 22-Feb-05 JDB Fixed missing MPCK on JRS target + Removed EXECUTE instruction (is NOP in actual microcode) + 15-Jan-05 RMS Cloned from hp2100_cpu.c +*/ + +#include "hp2100_defs.h" +#include +#include "hp2100_cpu.h" + +extern uint16 ABREG[2]; +extern uint32 PC; +extern uint32 err_PC; +extern uint32 XR; +extern uint32 YR; +extern uint32 E; +extern uint32 O; +extern uint32 dms_enb; +extern uint32 dms_ump; +extern uint32 dms_sr; +extern uint32 dms_vr; +extern uint32 mp_fence; +extern uint32 iop_sp; +extern uint32 ion_defer; +extern uint16 pcq[PCQ_SIZE]; +extern uint32 pcq_p; +extern uint32 stop_inst; +extern jmp_buf save_env; +extern UNIT cpu_unit; + +extern t_stat Ea1 (uint32 *addr, uint32 irq); +extern uint32 f_as (uint32 op, t_bool sub); +extern uint32 f_mul (uint32 op); +extern uint32 f_div (uint32 op); +extern uint32 f_fix (void); +extern uint32 f_flt (void); + +/* Extended instruction decode tables */ + +#define E_V_FL 0 /* flags */ +#define E_M_FL 0xFF +#define E_FP (UNIT_FP >> (UNIT_V_UF - E_V_FL)) +#define E_21MX (UNIT_21MX >> (UNIT_V_UF - E_V_FL)) +#define E_DMS (UNIT_DMS >> (UNIT_V_UF - E_V_FL)) +#define E_IOP (UNIT_IOP >> (UNIT_V_UF - E_V_FL)) +#define E_IOPX (UNIT_IOPX >> (UNIT_V_UF - E_V_FL)) +#define E_V_TY 8 /* type */ +#define E_M_TY 0xF +#define E_NO 0 /* no operands */ +#define E_CN 1 /* PC+1: count */ +#define E_AD 2 /* PC+1: addr */ +#define E_AA 3 /* PC+1,2: addr */ +#define E_AC 4 /* PC+1: addr, +2: count */ +#define E_AZ 5 /* PC+1: addr, +2: zero */ +#define ET_NO (E_NO << E_V_TY) +#define ET_AD (E_AD << E_V_TY) +#define ET_AA (E_AA << E_V_TY) +#define ET_CN (E_CN << E_V_TY) +#define ET_AC (E_AC << E_V_TY) +#define ET_AZ (E_AZ << E_V_TY) +#define E_V_TYI 12 /* type if 2100 IOP */ +#define E_GETFL(x) (((x) >> E_V_FL) & E_M_FL) +#define E_GETTY(f,x) (((x) >> \ + ((((f) & E_IOP) && (cpu_unit.flags & UNIT_IOP))? \ + E_V_TYI: E_V_TY)) & E_M_TY) +#define F_NO E_FP | ET_NO +#define F_MR E_FP | ET_AD +#define X_NO E_21MX | ET_NO +#define X_MR E_21MX | ET_AD +#define X_AA E_21MX | ET_AA +#define X_AZ E_21MX | ET_AZ +#define D_NO E_DMS | ET_NO +#define D_MR E_DMS | ET_AD +#define D_AA E_DMS | ET_AA +#define M_NO E_IOPX | ET_NO +#define M_CN E_IOPX | ET_CN +#define M_AC E_IOPX | ET_AC +#define I_NO E_IOP | (ET_NO << (E_V_TYI - E_V_TY)) +#define I_CN E_IOP | (ET_CN << (E_V_TYI - E_V_TY)) +#define I_AC E_IOP | (ET_AC << (E_V_TYI - E_V_TY)) +#define I_AZ E_IOP | (ET_AZ << (E_V_TYI - E_V_TY)) + +static const uint32 e_inst[512] = { + F_MR | I_AC,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* FAD/ILIST */ + F_MR | I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, /* FSB/LAI- */ + I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, + F_MR | I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, /* FMP/LAI+ */ + I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, + F_MR | I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, /* FDV/SAI- */ + I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, + F_NO | I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, /* FIX/SAI+ */ + I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO,I_NO, + F_NO | I_AZ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* FLT/MBYTE */ + 0,0,0,0,0,0,0,0,I_CN,0,0,0,0,0,0,0, /* CRC */ + I_CN,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* TRSLT */ + I_AZ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* WMOVE */ + I_NO,I_NO,I_NO,I_NO,0,0,0,0,0,0,0,0,0,0,0,0, /* READF,PFRIO,PFREI,PFREX */ + I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,I_NO, /* ENQ,PENQ */ + I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* DEQ */ + I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* SBYTE */ + I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* LBYTE */ + I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* REST */ + 0,0,I_NO,0,0,0,0,0,0,0,0,0,0,0,0,0, /* SAVE */ + M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO, /* LAI-/SAI- */ + M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO, + M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO, /* LAI+/SAI+ */ + M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0440 */ + M_CN,M_NO,M_NO,M_NO,M_NO,M_NO,M_NO,M_CN, /* CRC,REST,READF,INS,ENQ,PENQ,DEQ,TR */ + M_AC,M_NO,M_NO,M_NO,M_NO,0,0,0, /* ILIST,PFREI,PFREX,PFRIO,SAVE */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0500 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0520 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0540 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0560 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0600 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0620 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0640 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0660 */ + D_NO,D_NO,D_NO,D_NO,D_NO,D_NO,D_NO,D_NO, /* XMM,test,MBI,MBF,MBW,MWI,MWF,MWW */ + D_NO,D_NO,D_NO,D_NO,D_MR,D_AA,D_NO,D_NO, /* SY*,US*,PA*,PB*,SSM,JRS,nop,nop */ + D_NO,D_NO,D_NO,D_NO,D_MR,D_MR,D_MR,D_NO, /* XMM,XMS,XM*,nop,XL*,XS*,XC*,LF* */ + D_NO,D_NO,D_MR,D_MR,D_MR,D_MR,D_MR,D_MR, /* RS*,RV*,DJP,DJS,SJP,SJS,UJP,UJS */ + X_MR,X_NO,X_MR,X_MR,X_NO,X_MR,X_MR,X_NO, /* S*X,C*X,L*X,STX,CX*,LDX,ADX,X*X */ + X_MR,X_NO,X_MR,X_MR,X_NO,X_MR,X_MR,X_NO, /* S*Y,C*Y,L*Y,STY,CY*,LDY,ADY,X*Y */ + X_NO,X_NO,X_MR,X_NO,X_NO,X_AZ,X_AZ,X_NO, /* ISX,DSX,JLY,LBT,SBT,MBT,CBT,SFB */ + X_NO,X_NO,X_NO,X_AA,X_AA,X_AA,X_AZ,X_AZ }; /* ISY,DSY,JPY,SBS,CBS,TBS,CMW,MVW */ + +/* Extended arithmetic + + The 21MX-E adds three "special instructions" that do not exist in earlier + CPUs, including the 21MX-M. They are: TIMER (100060), EXECUTE (100120), and + DIAG (100000). On the 21MX-M, these instruction codes map to the + microroutines for MPY, ASL, and RRL, respectively. + + Under simulation, these cause undefined instruction stops if the CPU is set + to 2100 or 2116. They do not cause stops on the 21MX-M, as TIMER in + particular is used by several HP programs to differentiate between M- and + E-series machines. */ + +t_stat cpu_eau (uint32 IR, uint32 intrq) +{ +t_stat reason = SCPE_OK; +uint32 MA, v1, v2, t; +uint32 rs, qs, sc; +int32 sop1, sop2; + +if ((cpu_unit.flags & UNIT_EAU) == 0) return stop_inst; /* implemented? */ + +switch ((IR >> 8) & 017) { /* case on IR<11:8> */ + + case 000: /* EAU group 0 */ + switch ((IR >> 4) & 017) { /* decode IR<7:4> */ + case 001: /* ASL */ + sc = (IR & 017)? (IR & 017): 16; /* get sc */ + O = 0; /* clear ovflo */ + while (sc-- != 0) { /* bit by bit */ + t = BR << 1; /* shift B */ + BR = (BR & SIGN) | (t & 077777) | (AR >> 15); + AR = (AR << 1) & DMASK; + if ((BR ^ t) & SIGN) O = 1; } + break; + case 002: /* LSL */ + sc = (IR & 017)? (IR & 017): 16; /* get sc */ + BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK; + AR = (AR << sc) & DMASK; /* BR'AR lsh left */ + break; + case 000: /* DIAG */ + if (!(cpu_unit.flags & UNIT_21MX)) /* must be 21MX */ + return stop_inst; /* trap if not */ + if (!(cpu_unit.flags & UNIT_MXM)) /* E-series? */ + break; /* is NOP unless halted */ + case 004: /* RRL (+ DIAG on 21MX-M) */ + sc = (IR & 017)? (IR & 017): 16; /* get sc */ + t = BR; /* BR'AR rot left */ + BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK; + AR = ((AR << sc) | (t >> (16 - sc))) & DMASK; + break; + case 003: /* TIMER */ + if (!(cpu_unit.flags & UNIT_21MX)) /* must be 21MX */ + return stop_inst; /* trap if not */ + else if (!(cpu_unit.flags & UNIT_MXM)) { /* E-series? */ + BR = (BR + 1) & DMASK; /* increment B */ + if (BR) PC = err_PC; /* if !=0, repeat */ + break; } + case 010: /* MPY (+ TIMER on 21MX-M) */ + if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ + sop1 = SEXT (AR); /* sext AR */ + sop2 = SEXT (ReadW (MA)); /* sext mem */ + sop1 = sop1 * sop2; /* signed mpy */ + BR = (sop1 >> 16) & DMASK; /* to BR'AR */ + AR = sop1 & DMASK; + O = 0; /* no overflow */ + break; + default: + return stop_inst; + } + break; + + case 001: /* divide */ + if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ + if (rs = qs = BR & SIGN) { /* save divd sign, neg? */ + AR = (~AR + 1) & DMASK; /* make B'A pos */ + BR = (~BR + (AR == 0)) & DMASK; } /* make divd pos */ + v2 = ReadW (MA); /* divr = mem */ + if (v2 & SIGN) { /* neg? */ + v2 = (~v2 + 1) & DMASK; /* make divr pos */ + qs = qs ^ SIGN; } /* sign of quotient */ + if (BR >= v2) O = 1; /* divide work? */ + else { /* maybe... */ + O = 0; /* assume ok */ + v1 = (BR << 16) | AR; /* 32b divd */ + AR = (v1 / v2) & DMASK; /* quotient */ + BR = (v1 % v2) & DMASK; /* remainder */ + if (AR) { /* quotient > 0? */ + if (qs) AR = (~AR + 1) & DMASK; /* apply quo sign */ + if ((AR ^ qs) & SIGN) O = 1; } /* still wrong? ovflo */ + if (rs) BR = (~BR + 1) & DMASK; } /* apply rem sign */ + break; + + case 002: /* EAU group 2 */ + switch ((IR >> 4) & 017) { /* decode IR<7:4> */ + case 001: /* ASR */ + sc = (IR & 017)? (IR & 017): 16; /* get sc */ + AR = ((BR << (16 - sc)) | (AR >> sc)) & DMASK; + BR = (SEXT (BR) >> sc) & DMASK; /* BR'AR ash right */ + O = 0; + break; + case 002: /* LSR */ + sc = (IR & 017)? (IR & 017): 16; /* get sc */ + AR = ((BR << (16 - sc)) | (AR >> sc)) & DMASK; + BR = BR >> sc; /* BR'AR log right */ + break; + case 004: /* RRR */ + sc = (IR & 017)? (IR & 017): 16; /* get sc */ + t = AR; /* BR'AR rot right */ + AR = ((AR >> sc) | (BR << (16 - sc))) & DMASK; + BR = ((BR >> sc) | (t << (16 - sc))) & DMASK; + break; + default: + return stop_inst; + } + break; + + case 010: /* DLD */ + if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ + AR = ReadW (MA); /* load AR */ + MA = (MA + 1) & VAMASK; + BR = ReadW (MA); /* load BR */ + break; + + case 011: /* DST */ + if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ + WriteW (MA, AR); /* store AR */ + MA = (MA + 1) & VAMASK; + WriteW (MA, BR); /* store BR */ + break; + + default: /* should never get here */ + return SCPE_IERR; + } +return reason; +} + +t_stat cpu_mac (uint32 IR, uint32 intrq) +{ +t_stat reason; +uint32 MA, M1, absel, v1, v2, t; +uint32 fop, eop, etype, eflag; +uint32 mapi, mapj; +uint32 awc, wc, hp, tp; +int32 i, sop1, sop2; + +absel = (IR & I_AB)? 1: 0; /* get A/B select */ +eop = IR & 0777; /* extended opcode */ +eflag = E_GETFL (e_inst[eop]); /* get flags */ +if ((eflag & (cpu_unit.flags >> UNIT_V_UF)) == 0) /* invalid? error */ + return stop_inst; +etype = E_GETTY (eflag, e_inst[eop]); /* get format */ +if (etype > E_CN) { /* at least 1 addr? */ + if (reason = Ea1 (&MA, intrq)) /* get first address */ + return reason; } +if ((etype == E_AC) || (etype == E_CN)) { /* addr + cnt, cnt */ + wc = ReadW (PC); /* get count */ + awc = PC; /* addr of count */ + PC = (PC + 1) & VAMASK; } +else if (etype == E_AZ) { /* addr + zero */ + wc = ReadW (MA); /* get wc */ + awc = PC; /* addr of interim */ + if (wc) { /* wc > 0? */ + if (t = ReadW (PC)) wc = t; } /* use interim if nz */ + WriteW (awc, 0); /* clear interim */ + PC = (PC + 1) & VAMASK; } +else if (etype == E_AA) { /* second addr */ + if (reason = Ea1 (&M1, intrq)) /* get second address */ + return reason; } + +switch (eop) { /* decode IR<8:0> */ + +/* Floating point instructions */ + + case 0000: /* IOP ILIST/FAD */ + if (cpu_unit.flags & UNIT_IOP) /* ILIST (E_AC) */ + goto IOP_ILIST; + fop = ReadF (MA); /* get fop */ + O = f_as (fop, 0); /* add, upd ovflo */ + break; + case 0020: /* IOP LAI-/FSB */ + if (cpu_unit.flags & UNIT_IOP) /* LAI -20 (I_NO) */ + goto IOP_LAIM; + fop = ReadF (MA); /* get fop */ + O = f_as (fop, 1); /* sub, upd ovflo */ + break; + case 0040: /* IOP LAI+/FMP */ + if (cpu_unit.flags & UNIT_IOP) /* LAI 0 (I_NO) */ + goto IOP_LAIP; + fop = ReadF (MA); /* get fop */ + O = f_mul (fop); /* mul, upd ovflo */ + break; + case 0060: /* IOP SAI-/FDV */ + if (cpu_unit.flags & UNIT_IOP) /* SAI -20 (I_NO) */ + goto IOP_SAIM; + fop = ReadF (MA); /* get fop */ + O = f_div (fop); /* div, upd ovflo */ + break; + case 0100: /* IOP SAI+/FIX */ + if (cpu_unit.flags & UNIT_IOP) /* SAI 0 (I_NO) */ + goto IOP_SAIP; + O = f_fix (); /* FIX (E_NO) */ + break; + case 0120: /* IOP MBYTE/FLT */ + if (cpu_unit.flags & UNIT_IOP) /* MBYTE (I_AZ) */ + goto IOP_MBYTE; + O = f_flt (); /* FLT (E_NO) */ + break; + +/* 2100 (and 21MX) IOP instructions */ + + IOP_LAIM: case 0021: case 0022: case 0023: /* IOP LAI- (I_NO) */ + case 0024: case 0025: case 0026: case 0027: + case 0030: case 0031: case 0032: case 0033: + case 0034: case 0035: case 0036: case 0037: + MA = ((IR | 0177760) + BR) & VAMASK; /* IR<3:0> = -offset */ + AR = ReadW (MA); /* load AR */ + break; + IOP_LAIP: case 0041: case 0042: case 0043: /* IOP LAI+ (I_NO) */ + case 0044: case 0045: case 0046: case 0047: + case 0050: case 0051: case 0052: case 0053: + case 0054: case 0055: case 0056: case 0057: + MA = ((IR & 017) + BR) & VAMASK; /* IR<3:0> = +offset */ + AR = ReadW (MA); /* load AR */ + break; + IOP_SAIM: case 0061: case 0062: case 0063: /* IOP SAI- (I_NO) */ + case 0064: case 0065: case 0066: case 0067: + case 0070: case 0071: case 0072: case 0073: + case 0074: case 0075: case 0076: case 0077: + MA = ((IR | 0177760) + BR) & VAMASK; /* IR<3:0> = -offset */ + WriteW (MA, AR); /* store AR */ + break; + IOP_SAIP: case 0101: case 0102: case 0103: /* IOP SAI+ (I_NO) */ + case 0104: case 0105: case 0106: case 0107: + case 0110: case 0111: case 0112: case 0113: + case 0114: case 0115: case 0116: case 0117: + MA = ((IR & 017) + BR) & VAMASK; /* IR<3:0> = +offset */ + WriteW (MA, AR); /* store AR */ + break; + case 0150: /* IOP CRC (I_CN) */ + case 0460: /* IOPX CRC (I_CN) */ + t = (AR & 0xFF) ^ wc; /* start CRC */ + for (i = 0; i < 8; i++) { /* apply polynomial */ + t = (t >> 1) | ((t & 1) << 15); /* rotate right */ + if (t & SIGN) t = t ^ 020001; } /* old t<0>? xor */ + WriteW (awc, t); /* rewrite CRC */ + break; + case 0160: /* IOP TRSLT (I_CN) */ + case 0467: /* IOPX TRSLT (I_CN) */ + if (wc & SIGN) break; /* cnt < 0? */ + while (wc != 0) { /* loop */ + MA = (AR + AR + ReadB (BR)) & VAMASK; + t = ReadB (MA); /* xlate */ + WriteB (BR, t); /* store char */ + BR = (BR + 1) & DMASK; /* incr ptr */ + wc = (wc - 1) & DMASK; /* decr cnt */ + if (wc && intrq) { /* more and intr? */ + WriteW (awc, wc); /* rewrite wc */ + PC = err_PC; /* stop for now */ + break; } } + break; + case 0220: /* IOP READF (I_NO) */ + case 0462: /* IOPX READF (I_NO) */ + AR = iop_sp; /* copy stk ptr */ + break; + case 0221: /* IOP PRFIO (I_NO) */ + case 0473: /* IOPX PFRIO (I_NO) */ + t = ReadW (PC); /* get IO instr */ + PC = (PC + 1) & VAMASK; + WriteW (PC, 1); /* set flag */ + PC = (PC + 1) & VAMASK; + reason = iogrp (t, 0); /* execute instr */ + break; + case 0222: /* IOP PRFEI (I_NO) */ + case 0471: /* IOPX PFREI (I_NO) */ + t = ReadW (PC); /* get IO instr */ + PC = (PC + 1) & VAMASK; + WriteW (PC, 1); /* set flag */ + PC = (PC + 1) & VAMASK; + reason = iogrp (t, 0); /* execute instr */ + /* fall through */ + case 0223: /* IOP PRFEX (I_NO) */ + case 0472: /* IOPX PFREX (I_NO) */ + MA = ReadW (PC); /* exit addr */ + PCQ_ENTRY; + PC = ReadW (MA) & VAMASK; /* jump indirect */ + WriteW (MA, 0); /* clear exit */ + break; + case 0240: /* IOP ENQ (I_NO) */ + case 0464: /* IOPX ENQ (I_NO) */ + hp = ReadW (AR & VAMASK); /* addr of head */ + tp = ReadW ((AR + 1) & VAMASK); /* addr of tail */ + WriteW ((BR - 1) & VAMASK, 0); /* entry link */ + WriteW ((tp - 1) & VAMASK, BR); /* tail link */ + WriteW ((AR + 1) & VAMASK, BR); /* queue tail */ + if (hp != 0) PC = (PC + 1) & VAMASK; /* q not empty? skip */ + break; + case 0257: /* IOP PENQ (I_NO) */ + case 0465: /* IOPX PENQ (I_NO) */ + hp = ReadW (AR & VAMASK); /* addr of head */ + WriteW ((BR - 1) & VAMASK, hp); /* becomes entry link */ + WriteW (AR & VAMASK, BR); /* queue head */ + if (hp == 0) /* q empty? */ + WriteW ((AR + 1) & VAMASK, BR); /* queue tail */ + else PC = (PC + 1) & VAMASK; /* skip */ + break; + case 0260: /* IOP DEQ (I_NO) */ + case 0466: /* IOPX DEQ (I_NO) */ + BR = ReadW (AR & VAMASK); /* addr of head */ + if (BR) { /* queue not empty? */ + hp = ReadW ((BR - 1) & VAMASK); /* read hd entry link */ + WriteW (AR & VAMASK, hp); /* becomes queue head */ + if (hp == 0) /* q now empty? */ + WriteW ((AR + 1) & VAMASK, (AR + 1) & DMASK); + PC = (PC + 1) & VAMASK; } /* skip */ + break; + case 0300: /* IOP SBYTE (I_NO) */ + WriteB (BR, AR); /* store byte */ + BR = (BR + 1) & DMASK; /* incr ptr */ + break; + case 0320: /* IOP LBYTE (I_NO) */ + AR = ReadB (BR); /* load byte */ + BR = (BR + 1) & DMASK; /* incr ptr */ + break; + case 0340: /* IOP REST (I_NO) */ + case 0461: /* IOPX REST (I_NO) */ + iop_sp = (iop_sp - 1) & VAMASK; /* pop E/~O,BR,AR */ + t = ReadW (iop_sp); + O = ((t >> 1) ^ 1) & 1; + E = t & 1; + iop_sp = (iop_sp - 1) & VAMASK; + BR = ReadW (iop_sp); + iop_sp = (iop_sp - 1) & VAMASK; + AR = ReadW (iop_sp); + if (cpu_unit.flags & UNIT_2100) mp_fence = iop_sp; + break; + case 0362: /* IOP SAVE (I_NO) */ + case 0474: /* IOPX SAVE (I_NO) */ + WriteW (iop_sp, AR); /* push AR,BR,E/~O */ + iop_sp = (iop_sp + 1) & VAMASK; + WriteW (iop_sp, BR); + iop_sp = (iop_sp + 1) & VAMASK; + t = ((O ^ 1) << 1) | E; + WriteW (iop_sp, t); + iop_sp = (iop_sp + 1) & VAMASK; + if (cpu_unit.flags & UNIT_2100) mp_fence = iop_sp; + break; + + case 0400: case 0401: case 0402: case 0403: /* IOPX LAI-/SAI- (I_NO) */ + case 0404: case 0405: case 0406: case 0407: + case 0410: case 0411: case 0412: case 0413: + case 0414: case 0415: case 0416: case 0417: + MA = ((IR | 0177760) + BR) & VAMASK; /* IR<3:0> = -offset */ + if (IR & I_AB) AR = ReadW (MA); /* AB = 1? LAI */ + else WriteW (MA, AR); /* AB = 0? SAI */ + break; + case 0420: case 0421: case 0422: case 0423: /* IOPX LAI+/SAI+ (I_NO) */ + case 0424: case 0425: case 0426: case 0427: + case 0430: case 0431: case 0432: case 0433: + case 0434: case 0435: case 0436: case 0437: + MA = ((IR & 017) + BR) & VAMASK; /* IR<3:0> = +offset */ + if (IR & I_AB) AR = ReadW (MA); /* AB = 1? LAI */ + else WriteW (MA, AR); /* AB = 0? SAI */ + break; + case 0463: /* IOPX INS (I_NO) */ + iop_sp = AR; /* init stk ptr */ + break; + case 0470: /* IOPX ILIST (I_CN) */ + IOP_ILIST: + do { /* for count */ + WriteW (MA, AR); /* write AR to mem */ + AR = (AR + 1) & DMASK; /* incr AR */ + MA = (MA + 1) & VAMASK; /* incr MA */ + wc = (wc - 1) & DMASK; } /* decr count */ + while (wc != 0); + break; + +/* DMS instructions, move alternate - interruptible + + DMS privilege violation rules are + - load map and CTL set (XMM, XMS, XM*, SY*, US*, PA*, PB*) + - load state or fence and UMAP set (JRS, DJP, DJS, SJP, SJS, UJP, UJS, LF*) + + The 21MX manual is incorrect in stating that M*I, M*W, XS* are privileged */ + + case 0701: /* self test */ + ABREG[absel] = ABREG[absel] ^ DMASK; /* CMA or CMB */ + break; + case 0702: /* MBI (E_NO) */ + AR = AR & ~1; /* force A, B even */ + BR = BR & ~1; + while (XR != 0) { /* loop */ + t = ReadB (AR); /* read curr */ + WriteBA (BR, t); /* write alt */ + AR = (AR + 1) & DMASK; /* incr ptrs */ + BR = (BR + 1) & DMASK; + XR = (XR - 1) & DMASK; + if (XR && intrq && !(AR & 1)) { /* more, int, even? */ + PC = err_PC; /* stop for now */ + break; } } + break; + case 0703: /* MBF (E_NO) */ + AR = AR & ~1; /* force A, B even */ + BR = BR & ~1; + while (XR != 0) { /* loop */ + t = ReadBA (AR); /* read alt */ + WriteB (BR, t); /* write curr */ + AR = (AR + 1) & DMASK; /* incr ptrs */ + BR = (BR + 1) & DMASK; + XR = (XR - 1) & DMASK; + if (XR && intrq && !(AR & 1)) { /* more, int, even? */ + PC = err_PC; /* stop for now */ + break; } } + break; + case 0704: /* MBW (E_NO) */ + AR = AR & ~1; /* force A, B even */ + BR = BR & ~1; + while (XR != 0) { /* loop */ + t = ReadBA (AR); /* read alt */ + WriteBA (BR, t); /* write alt */ + AR = (AR + 1) & DMASK; /* incr ptrs */ + BR = (BR + 1) & DMASK; + XR = (XR - 1) & DMASK; + if (XR && intrq && !(AR & 1)) { /* more, int, even? */ + PC = err_PC; /* stop for now */ + break; } } + break; + case 0705: /* MWI (E_NO) */ + while (XR != 0) { /* loop */ + t = ReadW (AR & VAMASK); /* read curr */ + WriteWA (BR & VAMASK, t); /* write alt */ + AR = (AR + 1) & DMASK; /* incr ptrs */ + BR = (BR + 1) & DMASK; + XR = (XR - 1) & DMASK; + if (XR && intrq) { /* more and intr? */ + PC = err_PC; /* stop for now */ + break; } } + break; + case 0706: /* MWF (E_NO) */ + while (XR != 0) { /* loop */ + t = ReadWA (AR & VAMASK); /* read alt */ + WriteW (BR & VAMASK, t); /* write curr */ + AR = (AR + 1) & DMASK; /* incr ptrs */ + BR = (BR + 1) & DMASK; + XR = (XR - 1) & DMASK; + if (XR && intrq) { /* more and intr? */ + PC = err_PC; /* stop for now */ + break; } } + break; + case 0707: /* MWW (E_NO) */ + while (XR != 0) { /* loop */ + t = ReadWA (AR & VAMASK); /* read alt */ + WriteWA (BR & VAMASK, t); /* write alt */ + AR = (AR + 1) & DMASK; /* incr ptrs */ + BR = (BR + 1) & DMASK; + XR = (XR - 1) & DMASK; + if (XR && intrq) { /* more and intr? */ + PC = err_PC; /* stop for now */ + break; } } + break; + +/* DMS, continued */ + + case 0710: /* SYA, SYB (E_NO) */ + case 0711: /* USA, USB (E_NO) */ + case 0712: /* PAA, PAB (E_NO) */ + case 0713: /* PBA, PBB (E_NO) */ + mapi = (IR & 03) << VA_N_PAG; /* map base */ + if (ABREG[absel] & SIGN) { /* store? */ + for (i = 0; i < MAP_LNT; i++) { + t = dms_rmap (mapi + i); /* map to memory */ + WriteW ((ABREG[absel] + i) & VAMASK, t); } } + else { /* load */ + dms_viol (err_PC, MVI_PRV); /* priv if PRO */ + for (i = 0; i < MAP_LNT; i++) { + t = ReadW ((ABREG[absel] + i) & VAMASK); + dms_wmap (mapi + i, t); } } /* mem to map */ + ABREG[absel] = (ABREG[absel] + MAP_LNT) & DMASK; + break; + case 0714: /* SSM (E_AD) */ + WriteW (MA, dms_upd_sr ()); /* store stat */ + break; + case 0715: /* JRS (E_AA) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); + t = ReadW (MA); /* get status */ + dms_enb = 0; /* assume off */ + dms_ump = SMAP; + if (t & 0100000) { /* set enable? */ + dms_enb = 1; + if (t & 0040000) dms_ump = UMAP; } /* set/clr usr */ + mp_dms_jmp (M1); /* mpck jmp target */ + PCQ_ENTRY; /* save old PC */ + PC = M1; /* jump */ + ion_defer = 1; /* defer intr */ + break; + +/* DMS, continued */ + + case 0700: case 0720: /* XMM (E_NO) */ + if (XR == 0) break; /* nop? */ + while (XR != 0) { /* loop */ + if (XR & SIGN) { /* store? */ + t = dms_rmap (AR); /* map to mem */ + WriteW (BR & VAMASK, t); + XR = (XR + 1) & DMASK; } + else { /* load */ + dms_viol (err_PC, MVI_PRV); /* priv if PRO */ + t = ReadW (BR & VAMASK); /* mem to map */ + dms_wmap (AR, t); + XR = (XR - 1) & DMASK; } + AR = (AR + 1) & DMASK; + BR = (BR + 1) & DMASK; + if (intrq && ((XR & 0xF) == 0xF)) { /* intr, cnt4 = F? */ + PC = err_PC; /* stop for now */ + break; } } + break; + case 0721: /* XMS (E_NO) */ + if ((XR & SIGN) || (XR == 0)) break; /* nop? */ + dms_viol (err_PC, MVI_PRV); /* priv if PRO */ + while (XR != 0) { + dms_wmap (AR, BR); /* AR to map */ + XR = (XR - 1) & DMASK; + AR = (AR + 1) & DMASK; + BR = (BR + 1) & DMASK; + if (intrq && ((XR & 0xF) == 0xF)) { /* intr, cnt4 = F? */ + PC = err_PC; + break; } } + break; + case 0722: /* XMA, XMB (E_NO) */ + dms_viol (err_PC, MVI_PRV); /* priv if PRO */ + if (ABREG[absel] & 0100000) mapi = UMAP; + else mapi = SMAP; + if (ABREG[absel] & 0000001) mapj = PBMAP; + else mapj = PAMAP; + for (i = 0; i < MAP_LNT; i++) { + t = dms_rmap (mapi + i); /* read map */ + dms_wmap (mapj + i, t); } /* write map */ + break; + case 0724: /* XLA, XLB (E_AD) */ + ABREG[absel] = ReadWA (MA); /* load alt */ + break; + case 0725: /* XSA, XSB (E_AD) */ + WriteWA (MA, ABREG[absel]); /* store alt */ + break; + case 0726: /* XCA, XCB (E_AD) */ + if (ABREG[absel] != ReadWA (MA)) /* compare alt */ + PC = (PC + 1) & VAMASK; + break; + case 0727: /* LFA, LFB (E_NO) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); + dms_sr = (dms_sr & ~(MST_FLT | MST_FENCE)) | + (ABREG[absel] & (MST_FLT | MST_FENCE)); + break; + +/* DMS, continued */ + + case 0730: /* RSA, RSB (E_NO) */ + ABREG[absel] = dms_upd_sr (); /* save stat */ + break; + case 0731: /* RVA, RVB (E_NO) */ + ABREG[absel] = dms_vr; /* save viol */ + break; + case 0732: /* DJP (E_AD) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); + mp_dms_jmp (MA); /* validate jump addr */ + PCQ_ENTRY; /* save curr PC */ + PC = MA; /* new PC */ + dms_enb = 0; /* disable map */ + dms_ump = SMAP; + ion_defer = 1; + break; + case 0733: /* DJS (E_AD) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); + WriteW (MA, PC); /* store ret addr */ + PCQ_ENTRY; /* save curr PC */ + PC = (MA + 1) & VAMASK; /* new PC */ + dms_enb = 0; /* disable map */ + dms_ump = SMAP; + ion_defer = 1; /* defer intr */ + break; + case 0734: /* SJP (E_AD) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); + mp_dms_jmp (MA); /* validate jump addr */ + PCQ_ENTRY; /* save curr PC */ + PC = MA; /* jump */ + dms_enb = 1; /* enable system */ + dms_ump = SMAP; + ion_defer = 1; /* defer intr */ + break; + case 0735: /* SJS (E_AD) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); + t = PC; /* save retn addr */ + PCQ_ENTRY; /* save curr PC */ + PC = (MA + 1) & VAMASK; /* new PC */ + dms_enb = 1; /* enable system */ + dms_ump = SMAP; + WriteW (MA, t); /* store ret addr */ + ion_defer = 1; /* defer intr */ + break; + case 0736: /* UJP (E_AD) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); + mp_dms_jmp (MA); /* validate jump addr */ + PCQ_ENTRY; /* save curr PC */ + PC = MA; /* jump */ + dms_enb = 1; /* enable user */ + dms_ump = UMAP; + ion_defer = 1; /* defer intr */ + break; + case 0737: /* UJS (E_AD) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); + t = PC; /* save retn addr */ + PCQ_ENTRY; /* save curr PC */ + PC = (MA + 1) & VAMASK; /* new PC */ + dms_enb = 1; /* enable user */ + dms_ump = UMAP; + WriteW (MA, t); /* store ret addr */ + ion_defer = 1; /* defer intr */ + break; + +/* Index register instructions */ + + case 0740: /* SAX, SBX (E_AD) */ + MA = (MA + XR) & VAMASK; /* indexed addr */ + WriteW (MA, ABREG[absel]); /* store */ + break; + case 0741: /* CAX, CBX (E_NO) */ + XR = ABREG[absel]; /* copy to XR */ + break; + case 0742: /* LAX, LBX (E_AD) */ + MA = (MA + XR) & VAMASK; /* indexed addr */ + ABREG[absel] = ReadW (MA); /* load */ + break; + case 0743: /* STX (E_AD) */ + WriteW (MA, XR); /* store XR */ + break; + case 0744: /* CXA, CXB (E_NO) */ + ABREG[absel] = XR; /* copy from XR */ + break; + case 0745: /* LDX (E_AD)*/ + XR = ReadW (MA); /* load XR */ + break; + case 0746: /* ADX (E_AD) */ + v1 = ReadW (MA); /* add to XR */ + t = XR + v1; + if (t > DMASK) E = 1; /* set E, O */ + if (((~XR ^ v1) & (XR ^ t)) & SIGN) O = 1; + XR = t & DMASK; + break; + case 0747: /* XAX, XBX (E_NO) */ + t = XR; /* exchange XR */ + XR = ABREG[absel]; + ABREG[absel] = t; + break; + case 0750: /* SAY, SBY (E_AD) */ + MA = (MA + YR) & VAMASK; /* indexed addr */ + WriteW (MA, ABREG[absel]); /* store */ + break; + case 0751: /* CAY, CBY (E_NO) */ + YR = ABREG[absel]; /* copy to YR */ + break; + case 0752: /* LAY, LBY (E_AD) */ + MA = (MA + YR) & VAMASK; /* indexed addr */ + ABREG[absel] = ReadW (MA); /* load */ + break; + case 0753: /* STY (E_AD) */ + WriteW (MA, YR); /* store YR */ + break; + case 0754: /* CYA, CYB (E_NO) */ + ABREG[absel] = YR; /* copy from YR */ + break; + case 0755: /* LDY (E_AD) */ + YR = ReadW (MA); /* load YR */ + break; + case 0756: /* ADY (E_AD) */ + v1 = ReadW (MA); /* add to YR */ + t = YR + v1; + if (t > DMASK) E = 1; /* set E, O */ + if (((~YR ^ v1) & (YR ^ t)) & SIGN) O = 1; + YR = t & DMASK; + break; + case 0757: /* XAY, XBY (E_NO) */ + t = YR; /* exchange YR */ + YR = ABREG[absel]; + ABREG[absel] = t; + break; + case 0760: /* ISX (E_NO) */ + XR = (XR + 1) & DMASK; /* incr XR */ + if (XR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ + break; + case 0761: /* DSX (E_NO) */ + XR = (XR - 1) & DMASK; /* decr XR */ + if (XR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ + break; + case 0762: /* JLY (E_AD) */ + mp_dms_jmp (MA); /* validate jump addr */ + PCQ_ENTRY; + YR = PC; /* ret addr to YR */ + PC = MA; /* jump */ + break; + case 0770: /* ISY (E_NO) */ + YR = (YR + 1) & DMASK; /* incr YR */ + if (YR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ + break; + case 0771: /* DSY (E_NO) */ + YR = (YR - 1) & DMASK; /* decr YR */ + if (YR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ + break; + case 0772: /* JPY (E_NO) */ + MA = (ReadW (PC) + YR) & VAMASK; /* index, no indir */ + PC = (PC + 1) & VAMASK; + mp_dms_jmp (MA); /* validate jump addr */ + PCQ_ENTRY; + PC = MA; /* jump */ + break; + +/* Byte instructions */ + + case 0763: /* LBT (E_NO) */ + AR = ReadB (BR); /* load byte */ + BR = (BR + 1) & DMASK; /* incr ptr */ + break; + case 0764: /* SBT (E_NO) */ + WriteB (BR, AR); /* store byte */ + BR = (BR + 1) & DMASK; /* incr ptr */ + break; + IOP_MBYTE: /* IOP MBYTE (I_AZ) */ + if (wc & SIGN) break; /* must be positive */ + case 0765: /* MBT (E_AZ) */ + while (wc != 0) { /* while count */ + WriteW (awc, wc); /* for abort */ + t = ReadB (AR); /* move byte */ + WriteB (BR, t); + AR = (AR + 1) & DMASK; /* incr src */ + BR = (BR + 1) & DMASK; /* incr dst */ + wc = (wc - 1) & DMASK; /* decr cnt */ + if (intrq && wc) { /* intr, more to do? */ + PC = err_PC; /* back up PC */ + break; } } /* take intr */ + WriteW (awc, wc); /* clean up inline */ + break; + case 0766: /* CBT (E_AZ) */ + while (wc != 0) { /* while count */ + WriteW (awc, wc); /* for abort */ + v1 = ReadB (AR); /* get src1 */ + v2 = ReadB (BR); /* get src2 */ + if (v1 != v2) { /* compare */ + PC = (PC + 1 + (v1 > v2)) & VAMASK; + BR = (BR + wc) & DMASK; /* update BR */ + wc = 0; /* clr interim */ + break; } + AR = (AR + 1) & DMASK; /* incr src1 */ + BR = (BR + 1) & DMASK; /* incr src2 */ + wc = (wc - 1) & DMASK; /* decr cnt */ + if (intrq && wc) { /* intr, more to do? */ + PC = err_PC; /* back up PC */ + break; } } /* take intr */ + WriteW (awc, wc); /* clean up inline */ + break; + case 0767: /* SFB (E_NO) */ + v1 = AR & 0377; /* test byte */ + v2 = (AR >> 8) & 0377; /* term byte */ + for (;;) { /* scan */ + t = ReadB (BR); /* read byte */ + if (t == v1) break; /* test match? */ + BR = (BR + 1) & DMASK; + if (t == v2) { /* term match? */ + PC = (PC + 1) & VAMASK; + break; } + if (intrq) { /* int pending? */ + PC = err_PC; /* back up PC */ + break; } } /* take intr */ + break; + +/* Bit, word instructions */ + + case 0773: /* SBS (E_AA) */ + v1 = ReadW (MA); + v2 = ReadW (M1); + WriteW (M1, v2 | v1); /* set bit */ + break; + case 0774: /* CBS (E_AA) */ + v1 = ReadW (MA); + v2 = ReadW (M1); + WriteW (M1, v2 & ~v1); /* clear bit */ + break; + case 0775: /* TBS (E_AA) */ + v1 = ReadW (MA); + v2 = ReadW (M1); + if ((v2 & v1) != v1) /* test bits */ + PC = (PC + 1) & VAMASK; + break; + case 0776: /* CMW (E_AZ) */ + while (wc != 0) { /* while count */ + WriteW (awc, wc); /* for abort */ + v1 = ReadW (AR & VAMASK); /* first op */ + v2 = ReadW (BR & VAMASK); /* second op */ + sop1 = (int32) SEXT (v1); /* signed */ + sop2 = (int32) SEXT (v2); + if (sop1 != sop2) { /* compare */ + PC = (PC + 1 + (sop1 > sop2)) & VAMASK; + BR = (BR + wc) & DMASK; /* update BR */ + wc = 0; /* clr interim */ + break; } + AR = (AR + 1) & DMASK; /* incr src1 */ + BR = (BR + 1) & DMASK; /* incr src2 */ + wc = (wc - 1) & DMASK; /* decr cnt */ + if (intrq && wc) { /* intr, more to do? */ + PC = err_PC; /* back up PC */ + break; } } /* take intr */ + WriteW (awc, wc); /* clean up inline */ + break; + case 0200: /* IOP WMOVE (I_AZ) */ + if (wc & SIGN) break; /* must be positive */ + case 0777: /* MVW (E_AZ) */ + while (wc != 0) { /* while count */ + WriteW (awc, wc); /* for abort */ + t = ReadW (AR & VAMASK); /* move word */ + WriteW (BR & VAMASK, t); + AR = (AR + 1) & DMASK; /* incr src */ + BR = (BR + 1) & DMASK; /* incr dst */ + wc = (wc - 1) & DMASK; /* decr cnt */ + if (intrq && wc) { /* intr, more to do? */ + PC = err_PC; /* back up PC */ + break; } } /* take intr */ + WriteW (awc, wc); /* clean up inline */ + break; + default: /* all others NOP */ + break; } /* end case ext */ +return reason; +} diff --git a/HP2100/hp2100_doc.txt b/HP2100/hp2100_doc.txt index c45dc9db..50f57550 100644 --- a/HP2100/hp2100_doc.txt +++ b/HP2100/hp2100_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: HP2100 Simulator Usage -Date: 22-Dec-2004 +Date: 20-Jan-2005 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2004, written by Robert M Supnik - Copyright (c) 1993-2004, Robert M Supnik + Original code published in 1993-2005, written by Robert M Supnik + Copyright (c) 1993-2005, 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"), @@ -53,8 +53,10 @@ sim/ scp.h sim_timer.c sim_tmxr.c -sim/hp2100/ hp2100_defs.h +sim/hp2100/ hp2100_cpu.h + hp2100_defs.h hp2100_cpu.c + hp2100_cpu1.c hp2100_fp.c hp2100_dp.c hp2100_dq.c diff --git a/HP2100/hp2100_fp.c b/HP2100/hp2100_fp.c index 3ab11978..df927ea8 100644 --- a/HP2100/hp2100_fp.c +++ b/HP2100/hp2100_fp.c @@ -1,6 +1,6 @@ /* hp2100_fp.c: HP 2100 floating point instructions - Copyright (c) 2002-2004, Robert M. Supnik + Copyright (c) 2002-2005, 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 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 11-Feb-05 JDB Fixed missing negative overflow renorm in StoreFP 26-Dec-04 RMS Separated A/B from M[0/1] for DMA IO (from Dave Bryan) 15-Jul-03 RMS Fixed signed/unsigned warning 21-Oct-02 RMS Recoded for compatibility with 21MX microcode algorithms @@ -295,8 +296,9 @@ svfr = fop->fr; /* save fraction */ sign = FP_GETSIGN (fop->fr); /* save sign */ fop->fr = (fop->fr + (sign? FP_RNDM: FP_RNDP)) & FP_FR; /* round */ if ((fop->fr ^ svfr) & FP_SIGN) { /* sign change? */ - fop->fr = (fop->fr >> 1) | (sign? FP_SIGN: 0); /* renormalize */ + fop->fr = fop->fr >> 1; /* renormalize */ fop->exp = fop->exp + 1; } +else NormFP (fop); /* check for norm */ if (fop->fr == 0) hi = 0; /* result 0? */ else if (fop->exp < -(FP_M_EXP + 1)) { /* underflow? */ hi = 0; /* store clean 0 */ diff --git a/I1401/i1401_lp.c b/I1401/i1401_lp.c index 606a3a7e..4aa68b1c 100644 --- a/I1401/i1401_lp.c +++ b/I1401/i1401_lp.c @@ -1,6 +1,6 @@ /* i1401_lp.c: IBM 1403 line printer simulator - Copyright (c) 1993-2004, Robert M. Supnik + Copyright (c) 1993-2005, 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,7 @@ lpt 1403 line printer + 07-Mar-05 RMS Fixed bug in write_line (reported by Van Snyder) 25-Apr-03 RMS Revised for extended file support 30-May-02 RMS Widened POS to 32b 13-Apr-01 RMS Revised for register arrays @@ -129,7 +130,7 @@ for (i = 0; i < LPT_WIDTH; i++) { /* convert print buf */ t = M[LPT_BUF + i]; if (wm) lbuf[i] = (t & WM)? '1': ' '; /* wmarks -> 1 or sp */ else lbuf[i] = pch[t & CHAR]; } /* normal */ -M[LPT_BUF + 1] = 0; /* trailing null */ +lbuf[LPT_WIDTH] = 0; /* trailing null */ for (i = LPT_WIDTH - 1; (i >= 0) && (lbuf[i] == ' '); i--) lbuf[i] = 0; fputs (lbuf, lpt_unit.fileref); /* write line */ if (lines) space (lines, lflag); /* cc action? do it */ diff --git a/Interdata/id32_cpu.c b/Interdata/id32_cpu.c index 85fc1b98..5184a14e 100644 --- a/Interdata/id32_cpu.c +++ b/Interdata/id32_cpu.c @@ -1,6 +1,6 @@ /* id32_cpu.c: Interdata 32b CPU simulator - Copyright (c) 2000-2004, Robert M. Supnik + Copyright (c) 2000-2005, 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,7 @@ cpu Interdata 32b CPU + 18-Feb-05 RMS Fixed branches to mask new PC (from Greg Johnson) 06-Nov-04 RMS Added =n to SHOW HISTORY 25-Jan-04 RMS Revised for device debug support 31-Dec-03 RMS Fixed bug in cpu_set_hist @@ -845,14 +846,14 @@ case 0x01: /* BALR - RR */ case 0x41: /* BAL - RX */ PCQ_ENTRY; /* save old PC */ R[r1] = PC; /* save cur PC */ - PC = opnd; /* branch */ + PC = opnd & VAMASK; /* branch */ break; case 0x02: /* BTCR - RR */ case 0x42: /* BTC - RX */ if (cc & r1) { /* test CC's */ PCQ_ENTRY; /* branch if true */ - PC = opnd; } + PC = opnd & VAMASK; } break; case 0x20: /* BTBS - NO */ @@ -871,7 +872,7 @@ case 0x03: /* BFCR - RR */ case 0x43: /* BFC - RX */ if ((cc & r1) == 0) { /* test CC's */ PCQ_ENTRY; /* branch if false */ - PC = opnd; } + PC = opnd & VAMASK; } break; case 0x22: /* BFBS - NO */ @@ -892,7 +893,7 @@ case 0xC0: /* BXH - RX */ R[r1] = (R[r1] + inc) & DMASK32; /* R1 = R1 + inc */ if (R[r1] > lim) { /* if R1 > lim */ PCQ_ENTRY; /* branch */ - PC = opnd; } + PC = opnd & VAMASK; } break; case 0xC1: /* BXLE - RX */ @@ -901,7 +902,7 @@ case 0xC1: /* BXLE - RX */ R[r1] = (R[r1] + inc) & DMASK32; /* R1 = R1 + inc */ if (R[r1] <= lim) { /* if R1 <= lim */ PCQ_ENTRY; /* branch */ - PC = opnd; } + PC = opnd & VAMASK; } break; /* Logical instructions */ diff --git a/PDP11/pdp11_cpu.c b/PDP11/pdp11_cpu.c index 4f44ee9f..808edf15 100644 --- a/PDP11/pdp11_cpu.c +++ b/PDP11/pdp11_cpu.c @@ -1,6 +1,6 @@ /* pdp11_cpu.c: PDP-11 CPU simulator - Copyright (c) 1993-2004, Robert M Supnik + Copyright (c) 1993-2005, 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,7 @@ cpu PDP-11 CPU + 19-Jan-05 RMS Fixed bug(s) in RESET for 11/70 (reported by Tim Chapman) 22-Dec-04 RMS Fixed WAIT to work in all modes (from John Dundas) 02-Oct-04 RMS Added model emulation 25-Jan-04 RMS Removed local debug logging support @@ -796,11 +797,12 @@ case 000: break; case 5: /* RESET */ if (cm == MD_KER) { - reset_all (1); - PIRQ = 0; + reset_all (2); /* skip CPU, sys reg */ + PIRQ = 0; /* clear PIRQ, STKLIM, */ + STKLIM = 0; /* MMR0<15:12,0>, */ for (i = 0; i < IPL_HLVL; i++) int_req[i] = 0; MMR0 = MMR0 & ~(MMR0_MME | MMR0_FREEZE); - MMR3 = 0; + MMR3 = 0; /* MMR3 */ trap_req = trap_req & ~TRAP_INT; dsenable = calc_ds (cm); } break; diff --git a/PDP11/pdp11_cpumod.c b/PDP11/pdp11_cpumod.c index c00d3b8c..f7923f1e 100644 --- a/PDP11/pdp11_cpumod.c +++ b/PDP11/pdp11_cpumod.c @@ -1,6 +1,6 @@ /* pdp11_cpumod.c: PDP-11 CPU model-specific features - Copyright (c) 2004, Robert M Supnik + Copyright (c) 2004-2005, 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 @@ system PDP-11 model-specific registers + 15-Feb-05 RMS Fixed bug in SHOW MODEL (from Sergey Okhapkin) + 19-Jan-05 RMS Added variable SYSID, MBRK write (from Tim Chapman) + This module includes CPU- and system-specific registers, such as the Unibus map and control registers on 22b Unibus systems, the board registers for the F11- and J11-based systems, and the system registers for the PDP-11/44, @@ -51,6 +54,7 @@ int32 SR = 0; /* switch register */ int32 DR = 0; /* display register */ int32 MBRK = 0; /* 11/70 microbreak */ +int32 SYSID = 0x1234; /* 11/70 system ID */ int32 CPUERR = 0; /* CPU error reg */ int32 MEMERR = 0; /* memory error reg */ int32 CCR = 0; /* cache control reg */ @@ -249,6 +253,7 @@ REG sys_reg[] = { { ORDATA (HITMISS, HITMISS, 16) }, { ORDATA (CPUERR, CPUERR, 16) }, { ORDATA (MBRK, MBRK, 16) }, + { ORDATA (SYSID, SYSID, 16) }, { ORDATA (JCSR, JCSR, 16) }, { ORDATA (JPCR, JPCR, 16) }, { ORDATA (JASR, JASR, 16) }, @@ -477,7 +482,7 @@ case 010: /* lower size */ *data = (MEMSIZE >> 6) - 1; return SCPE_OK; case 012: /* system ID */ - *data = 0x1234; + *data = SYSID; return SCPE_OK; case 013: /* CPUERR */ *data = CPUERR & CPUE_IMP; @@ -513,6 +518,9 @@ case 5: /* Hit/miss */ case 013: /* CPUERR */ CPUERR = 0; return SCPE_OK; +case 014: /* MBRK */ + MBRK = data; + return SCPE_OK; case 015: /* PIRQ */ ODD_WO (data); put_PIRQ (data); @@ -876,12 +884,12 @@ return SCPE_OK; t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc) { -uint32 i, std; +uint32 i, all_opt; fprintf (st, "%s", cpu_tab[cpu_model].name); -std = cpu_tab[cpu_model].opt; -for (i = 0; std && opt_name[i]; i = i++) { - if ((std >> i) & 1) fprintf (st, ", %s", +all_opt = cpu_tab[cpu_model].opt; +for (i = 0; opt_name[2 * i] != NULL; i++) { + if ((all_opt >> i) & 1) fprintf (st, ", %s", ((cpu_opt >> i) & 1)? opt_name[2 * i]: opt_name[(2 * i) + 1]); } return SCPE_OK; diff --git a/PDP11/pdp11_doc.txt b/PDP11/pdp11_doc.txt index 88a2f005..f1e90798 100644 --- a/PDP11/pdp11_doc.txt +++ b/PDP11/pdp11_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: PDP-11 Simulator Usage -Date: 15-Nov-2004 +Date: 20-Jan-2005 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2004, written by Robert M Supnik - Copyright (c) 1993-2004, Robert M Supnik + Original code published in 1993-2005, written by Robert M Supnik + Copyright (c) 1993-2005, 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"), @@ -328,6 +328,7 @@ The SYSTEM device implements registers that vary from system to system: 11/83, 11/84, 11/93, 11/94 MBRK 11/45, 11/70 16 microbreak register + SYSID 11/70 16 system ID (default = 1234 hex) JCSR 11/53, 11/73B, 11/83, 16 board control/status 11/84, 11/93, 11/94 JPCR 11/23+, 11/53, 11/73B, 16 page control register @@ -983,13 +984,15 @@ of many disk types: SET RQn RD53 set type to RD53 SET RQn RD54 set type to RD54 SET RQn RD31 set type to RD31 + SET RQn RA81 set type to RA81 SET RQn RA82 set type to RA82 + set RQn RA71 set type to RA71 SET RQn RA72 set type to RA72 SET RQn RA90 set type to RA90 SET RQn RA92 set type to RA92 SET RQn RRD40 set type to RRD40 (CD ROM) - SET RQn RAUSER{=n} set type to RA81 with n MB's - SET -L RQn RAUSER{=n} set type to RA81 with n LBN's + SET RQn RAUSER{=n} set type to RA82 with n MB's + SET -L RQn RAUSER{=n} set type to RA82 with n LBN's The type options can be used only when a unit is not attached to a file. RAUSER is a "user specified" disk; the user can specify the size of the diff --git a/PDP11/pdp11_rq.c b/PDP11/pdp11_rq.c index b11f2931..eb573689 100644 --- a/PDP11/pdp11_rq.c +++ b/PDP11/pdp11_rq.c @@ -1,6 +1,6 @@ /* pdp11_rq.c: MSCP disk controller simulator - Copyright (c) 2002-2004, Robert M Supnik + Copyright (c) 2002-2005, Robert M Supnik Derived from work by Stephen F. Shirron Permission is hereby granted, free of charge, to any person obtaining a @@ -26,6 +26,7 @@ rq RQDX3 disk controller + 17-Jan-05 RMS Added more RA and RD disks 31-Oct-04 RMS Added -L switch (LBNs) to RAUSER size specification 01-Oct-04 RMS Revised Unibus interface Changed to identify as UDA50 in Unibus configurations @@ -203,7 +204,7 @@ struct rqpkt { #define RCT_ENTB 128 /* entries/blk */ #define RCT_END 0x80000000 /* marks RCT end */ -/* The RQDX3 supports multiple disk drive types: +/* The RQDX3 supports multiple disk drive types (x = not implemented): type sec surf cyl tpg gpc RCT LBNs @@ -212,17 +213,23 @@ struct rqpkt { RD51 18 4 306 4 1 36*4 21600 RD31 17 4 615 4 1 3*8 41560 RD52 17 8 512 8 1 4*8 60480 +x RD32 17 6 820 ? ? ? 83236 +x RD33 17 7 1170 ? ? ? 138565 RD53 17 7 1024 7 1 5*8 138672 RD54 17 15 1225 15 1 7*8 311200 The simulator also supports larger drives that only existed - on SDI controllers. XBN, DBN, RCTS and RCTC are not known - for the SDI drives and are not used by the simulator: + on SDI controllers. - RA82 57 15 1435 15 1 ?*8 1216665 - RA72 51 20 1921? 20 1 ?*8 1953300 - RA90 69 13 2656 13 1 ?*8 2376153 - RA92 73 13 3101 13 1 ?*8 2940951 + RA60 42(+1) 6 1600 6 1 1008 400176 +x RA70 33(+1) 11 1507+ 11 1 ? 547041 + RA81 51(+1) 14 1258 14 1 2856 891072 + RA82 57(+1) 15 1435 15 1 3420 1216665 + RA71 51(+1) 14 1921 14 1 1428 1367310 + RA72 51(+1) 20 1921 20 1 2040 1953300 + RA90 69(+1) 13 2656 13 1 1794 2376153 + RA92 73(+1) 13 3101 13 1 949 2940951 +x RA73 70(+1) 21 2667+ 21 1 ? 3920490 Each drive can be a different type. The drive field in the unit flags specified the drive type and thus, indirectly, @@ -351,11 +358,11 @@ struct rqpkt { #define RA82_CYL 1435 /* 0-1422 user */ #define RA82_TPG RA82_SURF #define RA82_GPC 1 -#define RA82_XBN 3420 /* cyl 1427-1430 */ -#define RA82_DBN 3420 /* cyl 1431-1434 */ +#define RA82_XBN 3480 /* cyl 1427-1430 */ +#define RA82_DBN 3480 /* cyl 1431-1434 */ #define RA82_LBN 1216665 /* 57*15*1423 */ -#define RA82_RCTS 400 /* cyl 1423-1426 */ -#define RA82_RCTC 8 +#define RA82_RCTS 3420 /* cyl 1423-1426 */ +#define RA82_RCTC 1 #define RA82_RBN 21345 /* 1 *15*1423 */ #define RA82_MOD 11 #define RA82_MED 0x25641052 @@ -383,11 +390,11 @@ struct rqpkt { #define RA72_CYL 1921 /* 0-1914 user */ #define RA72_TPG RA72_SURF #define RA72_GPC 1 -#define RA72_XBN 2040 /* cyl 1917-1918? */ -#define RA72_DBN 2040 /* cyl 1920-1921? */ +#define RA72_XBN 2080 /* cyl 1917-1918? */ +#define RA72_DBN 2080 /* cyl 1920-1921? */ #define RA72_LBN 1953300 /* 51*20*1915 */ -#define RA72_RCTS 400 /* cyl 1915-1916? */ -#define RA72_RCTC 5 /* ? */ +#define RA72_RCTS 2040 /* cyl 1915-1916? */ +#define RA72_RCTC 1 #define RA72_RBN 38300 /* 1 *20*1915 */ #define RA72_MOD 37 #define RA72_MED 0x25641048 @@ -399,11 +406,11 @@ struct rqpkt { #define RA90_CYL 2656 /* 0-2648 user */ #define RA90_TPG RA90_SURF #define RA90_GPC 1 -#define RA90_XBN 1794 /* cyl 2651-2652? */ -#define RA90_DBN 1794 /* cyl 2653-2654? */ +#define RA90_XBN 1820 /* cyl 2651-2652? */ +#define RA90_DBN 1820 /* cyl 2653-2654? */ #define RA90_LBN 2376153 /* 69*13*2649 */ -#define RA90_RCTS 400 /* cyl 2649-2650? */ -#define RA90_RCTC 6 /* ? */ +#define RA90_RCTS 1794 /* cyl 2649-2650? */ +#define RA90_RCTC 1 #define RA90_RBN 34437 /* 1 *13*2649 */ #define RA90_MOD 19 #define RA90_MED 0x2564105A @@ -416,10 +423,10 @@ struct rqpkt { #define RA92_TPG RA92_SURF #define RA92_GPC 1 #define RA92_XBN 174 /* cyl 3100? */ -#define RA92_DBN 775 +#define RA92_DBN 788 #define RA92_LBN 2940951 /* 73*13*3099 */ -#define RA92_RCTS 316 /* cyl 3099? */ -#define RA92_RCTC 3 /* ? */ +#define RA92_RCTS 949 /* cyl 3099? */ +#define RA92_RCTC 1 #define RA92_RBN 40287 /* 1 *13*3099 */ #define RA92_MOD 29 #define RA92_MED 0x2564105C @@ -444,6 +451,54 @@ struct rqpkt { #define RA8U_MAXC 4000000 /* max cap LBNs */ #define RA8U_EMAXC 2000000000 /* ext max cap */ +#define RA60_DTYPE 13 /* SDI drive */ +#define RA60_SECT 42 /* +1 spare/track */ +#define RA60_SURF 6 +#define RA60_CYL 1600 /* 0-1587 user */ +#define RA60_TPG RA60_SURF +#define RA60_GPC 1 +#define RA60_XBN 1032 /* cyl 1592-1595 */ +#define RA60_DBN 1032 /* cyl 1596-1599 */ +#define RA60_LBN 400176 /* 42*6*1588 */ +#define RA60_RCTS 1008 /* cyl 1588-1591 */ +#define RA60_RCTC 1 +#define RA60_RBN 9528 /* 1 *6*1588 */ +#define RA60_MOD 4 +#define RA60_MED 0x22A4103C +#define RA60_FLGS (RQDF_RMV | RQDF_SDI) + +#define RA81_DTYPE 14 /* SDI drive */ +#define RA81_SECT 51 /* +1 spare/track */ +#define RA81_SURF 14 +#define RA81_CYL 1258 /* 0-1247 user */ +#define RA81_TPG RA81_SURF +#define RA81_GPC 1 +#define RA81_XBN 2436 /* cyl 1252-1254? */ +#define RA81_DBN 2436 /* cyl 1255-1256? */ +#define RA81_LBN 891072 /* 51*14*1248 */ +#define RA81_RCTS 2856 /* cyl 1248-1251? */ +#define RA81_RCTC 1 +#define RA81_RBN 17472 /* 1 *14*1248 */ +#define RA81_MOD 5 +#define RA81_MED 0x25641051 +#define RA81_FLGS RQDF_SDI + +#define RA71_DTYPE 15 /* SDI drive */ +#define RA71_SECT 51 /* +1 spare/track */ +#define RA71_SURF 14 +#define RA71_CYL 1921 /* 0-1914 user */ +#define RA71_TPG RA71_SURF +#define RA71_GPC 1 +#define RA71_XBN 1456 /* cyl 1917-1918? */ +#define RA71_DBN 1456 /* cyl 1919-1920? */ +#define RA71_LBN 1367310 /* 51*14*1915 */ +#define RA71_RCTS 1428 /* cyl 1915-1916? */ +#define RA71_RCTC 1 +#define RA71_RBN 26810 /* 1 *14*1915 */ +#define RA71_MOD 40 +#define RA71_MED 0x25641047 +#define RA71_FLGS RQDF_SDI + struct drvtyp { int32 sect; /* sectors */ int32 surf; /* surfaces */ @@ -476,7 +531,9 @@ static struct drvtyp drv_tab[] = { { RQ_DRV (RD54), "RD54" }, { RQ_DRV (RA82), "RA82" }, { RQ_DRV (RRD40), "RRD40" }, { RQ_DRV (RA72), "RA72" }, { RQ_DRV (RA90), "RA90" }, { RQ_DRV (RA92), "RA92" }, - { RQ_DRV (RA8U), "RAUSER" }, { 0 } }; + { RQ_DRV (RA8U), "RAUSER" }, { RQ_DRV (RA60), "RA60" }, + { RQ_DRV (RA81), "RA81" }, { RQ_DRV (RA71), "RA71" }, + { 0 } }; extern int32 int_req[IPL_HLVL]; extern int32 tmr_poll, clk_tps; @@ -666,12 +723,18 @@ MTAB rq_mod[] = { &rq_set_type, NULL, NULL }, { MTAB_XTD | MTAB_VUN, RD54_DTYPE, NULL, "RD54", &rq_set_type, NULL, NULL }, + { MTAB_XTD | MTAB_VUN, RA60_DTYPE, NULL, "RA60", + &rq_set_type, NULL, NULL }, + { MTAB_XTD | MTAB_VUN, RA81_DTYPE, NULL, "RA81", + &rq_set_type, NULL, NULL }, { MTAB_XTD | MTAB_VUN, RA82_DTYPE, NULL, "RA82", &rq_set_type, NULL, NULL }, { MTAB_XTD | MTAB_VUN, RRD40_DTYPE, NULL, "RRD40", &rq_set_type, NULL, NULL }, { MTAB_XTD | MTAB_VUN, RRD40_DTYPE, NULL, "CDROM", &rq_set_type, NULL, NULL }, + { MTAB_XTD | MTAB_VUN, RA71_DTYPE, NULL, "RA71", + &rq_set_type, NULL, NULL }, { MTAB_XTD | MTAB_VUN, RA72_DTYPE, NULL, "RA72", &rq_set_type, NULL, NULL }, { MTAB_XTD | MTAB_VUN, RA90_DTYPE, NULL, "RA90", @@ -2028,7 +2091,7 @@ uint32 cap; uint32 max = sim_taddr_64? RA8U_EMAXC: RA8U_MAXC; t_stat r; -if ((val < 0) || (val > RA8U_DTYPE) || ((val != RA8U_DTYPE) && cptr)) +if ((val < 0) || ((val != RA8U_DTYPE) && cptr)) return SCPE_ARG; if (uptr->flags & UNIT_ATT) return SCPE_ALATT; if (cptr) { diff --git a/PDP11/pdp11_ry.c b/PDP11/pdp11_ry.c index f71994da..897f5927 100644 --- a/PDP11/pdp11_ry.c +++ b/PDP11/pdp11_ry.c @@ -1,6 +1,6 @@ /* pdp11_ry.c: RX211/RXV21/RX02 floppy disk simulator - Copyright (c) 1993-2004, Robert M Supnik + Copyright (c) 1993-2005, 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,7 @@ ry RX211/RXV21/RX02 floppy disk + 18-Feb-05 RMS Fixed bug in boot code (reported by Graham Toal) 30-Sep-04 RMS Revised Unibus interface 21-Mar-04 RMS Added VAX support 29-Dec-03 RMS Added RXV21 support @@ -575,6 +576,7 @@ static const uint16 boot_rom[] = { 0032711, 0000040, /* RD: BIT #40, (R1) ; ready? */ 0001775, /* BEQ .-4 */ 0012746, 0000007, /* MOV #READ+GO, -(SP) */ + 0050316, /* BIS R3, (SP) ; or unit */ 0050416, /* BIS R4, (SP) ; or density */ 0012611, /* MOV (SP)+, (R1) ; read & go */ 0105711, /* TSTB (R1) ; xfr ready? */ @@ -588,7 +590,7 @@ static const uint16 boot_rom[] = { 0005711, /* TST (R1) ; error? */ 0100003, /* BEQ OK */ 0005704, /* TST R4 ; single? */ - 0001346, /* BNE DN ; no, try again */ + 0001345, /* BNE DN ; no, try again */ 0000000, /* HALT ; dead */ 0012746, 0000003, /* OK: MOV #EMPTY+GO, -(SP); empty & go */ 0050416, /* BIS R4, (SP) ; or density */ @@ -609,7 +611,7 @@ static const uint16 boot_rom[] = { 0062602, /* ADD (SP)+, R2 ; adv buf addr */ 0122525, /* CMPB (R5)+, (R5)+ ; sect += 2 */ 0020527, 0000007, /* CMP R5, #7 ; end? */ - 0101716, /* BLOS RD ; read next */ + 0101715, /* BLOS RD ; read next */ 0005002, /* CLR R2 */ 0005003, /* CLR R3 */ 0012704, BOOT_START+020, /* MOV #START+20, R4 */ diff --git a/PDP8/pdp8_doc.txt b/PDP8/pdp8_doc.txt index 66c3684d..276af796 100644 --- a/PDP8/pdp8_doc.txt +++ b/PDP8/pdp8_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: PDP-8 Simulator Usage -Date: 15-Nov-2004 +Date: 15-Feb-2005 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2004, written by Robert M Supnik - Copyright (c) 1993-2004, Robert M Supnik + Original code published in 1993-2005, written by Robert M Supnik + Copyright (c) 1993-2005, 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"), @@ -443,7 +443,8 @@ locked. SET DTn LOCKED set unit n write locked SET DTn WRITEENABLED set unit n write enabled -Units can also be set ENABLED or DISABLED. The TD8E supports the BOOT command. +Units can also be set ENABLED or DISABLED. The TD8E supports the BOOT +command, but only for unit 0. The TD8E supports supports PDP-8 format, PDP-11 format, and 18b format DECtape images. ATTACH tries to determine the tape format from the DECtape @@ -522,7 +523,8 @@ RL8A options include the ability to make units write enabled or write locked: SET RLn LOCKED set unit n write locked SET RLn WRITEENABLED set unit n write enabled -Units can also be set ONLINE or OFFILE. The RL8A supports the BOOT command. +Units can also be set ENABLED or DISABLED. The RL8A supports the BOOT command, +but only for unit 0. The RL8A implements these registers: @@ -720,7 +722,8 @@ locked. SET DTn LOCKED set unit n write locked SET DTn WRITEENABLED set unit n write enabled -Units can also be set ENABLED or DISABLED. The TC08 supports the BOOT command. +Units can also be set ENABLED or DISABLED. The TC08 supports the BOOT +command, but only for unit 0. The TC08 supports supports PDP-8 format, PDP-11 format, and 18b format DECtape images. ATTACH tries to determine the tape format from the DECtape diff --git a/VAX/vax780_doc.txt b/VAX/vax780_doc.txt index 8b896266..303099ec 100644 --- a/VAX/vax780_doc.txt +++ b/VAX/vax780_doc.txt @@ -1,7 +1,7 @@ To: Users From: Bob Supnik Subj: VAX780 Simulator Usage -Date: 24-Oct-2004 +Date: 20-Jan-2005 COPYRIGHT NOTICE @@ -714,7 +714,9 @@ of many disk types: SET RQn RD53 set type to RD53 SET RQn RD54 set type to RD54 SET RQn RD31 set type to RD31 + SET RQn RA81 set type to RA81 SET RQn RA82 set type to RA82 + set RQn RA71 set type to RA71 SET RQn RA72 set type to RA72 SET RQn RA90 set type to RA90 SET RQn RA92 set type to RA92 diff --git a/VAX/vax_cpu.c b/VAX/vax_cpu.c index deb83f1c..e1286e02 100644 --- a/VAX/vax_cpu.c +++ b/VAX/vax_cpu.c @@ -1,6 +1,6 @@ /* vax_cpu.c: VAX CPU - Copyright (c) 1998-2004, Robert M Supnik + Copyright (c) 1998-2005, 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,7 @@ cpu VAX central processor + 13-Jan-05 RMS Fixed initial state of cpu_extmem 06-Nov-04 RMS Added =n to SHOW HISTORY 30-Sep-04 RMS Added octaword specifier decodes and instructions Moved model-specific routines to system module @@ -226,7 +227,7 @@ int32 cpu_astop = 0; int32 mchk_va, mchk_ref; /* mem ref param */ int32 ibufl, ibufh; /* prefetch buf */ int32 ibcnt, ppc; /* prefetch ctl */ -int32 cpu_extmem = 0; /* extended memory */ +int32 cpu_extmem = 1; /* extended memory */ jmp_buf save_env; REG *pcq_r = NULL; /* PC queue reg ptr */ int32 pcq[PCQ_SIZE] = { 0 }; /* PC queue */ diff --git a/VAX/vax_doc.txt b/VAX/vax_doc.txt index 54a3b774..9e13d324 100644 --- a/VAX/vax_doc.txt +++ b/VAX/vax_doc.txt @@ -7,8 +7,8 @@ Date: 15-Nov-2004 The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2004, written by Robert M Supnik - Copyright (c) 1993-2004, Robert M Supnik + Original code published in 1993-2005, written by Robert M Supnik + Copyright (c) 1993-2005, 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"), diff --git a/descrip.mms b/descrip.mms index 94fe108e..dd182488 100644 --- a/descrip.mms +++ b/descrip.mms @@ -246,7 +246,7 @@ HP2100_SOURCE = $(HP2100_DIR)HP2100_STDDEV.C,$(HP2100_DIR)HP2100_DP.C,\ $(HP2100_DIR)HP2100_MT.C,$(HP2100_DIR)HP2100_MUX.C,\ $(HP2100_DIR)HP2100_CPU.C,$(HP2100_DIR)HP2100_FP.C,\ $(HP2100_DIR)HP2100_SYS.C,$(HP2100_DIR)HP2100_LPT.C,\ - $(HP2100_DIR)HP2100_IPL.C + $(HP2100_DIR)HP2100_IPL.C,$(HP2100_DIR)HP2100_CPU1.C HP2100_OPTIONS = /INCLUDE=($(SIMH_DIR),$(HP2100_DIR))/DEFINE=($(CC_DEFS)) # diff --git a/makefile b/makefile index d691627c..4160136d 100644 --- a/makefile +++ b/makefile @@ -147,7 +147,7 @@ HP2100 = ${HP2100D}hp2100_stddev.c ${HP2100D}hp2100_dp.c ${HP2100D}hp2100_dq.c \ ${HP2100D}hp2100_dr.c ${HP2100D}hp2100_lps.c ${HP2100D}hp2100_ms.c \ ${HP2100D}hp2100_mt.c ${HP2100D}hp2100_mux.c ${HP2100D}hp2100_cpu.c \ ${HP2100D}hp2100_fp.c ${HP2100D}hp2100_sys.c ${HP2100D}hp2100_lpt.c \ - ${HP2100D}hp2100_ipl.c ${HP2100D}hp2100_ds.c + ${HP2100D}hp2100_ipl.c ${HP2100D}hp2100_ds.c ${HP2100D}hp2100_cpu1.c HP2100_OPT = -I ${HP2100D} diff --git a/scp.c b/scp.c index 6b59ea07..9f2a54c0 100644 --- a/scp.c +++ b/scp.c @@ -1,6 +1,6 @@ /* scp.c: simulator control program - Copyright (c) 1993-2004, Robert M Supnik + Copyright (c) 1993-2005, 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 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 07-Feb-05 RMS Added ASSERT command (from Dave Bryan) + 02-Feb-05 RMS Fixed bug in global register search 26-Dec-04 RMS Qualified SAVE examine, RESTORE deposit with SIM_SW_REST 10-Nov-04 JDB Fixed logging of errors from cmds in "do" file 05-Nov-04 RMS Moved SET/SHOW DEBUG under CONSOLE hierarchy @@ -274,7 +276,7 @@ BRKTAB *sim_brk_new (t_addr loc); /* Commands support routines */ -SCHTAB *get_search (char *cptr, DEVICE *dptr, SCHTAB *schptr); +SCHTAB *get_search (char *cptr, int32 radix, SCHTAB *schptr); int32 test_search (t_value val, SCHTAB *schptr); char *get_glyph_gen (char *iptr, char *optr, char mchar, t_bool uc); int32 get_switches (char *cptr); @@ -391,8 +393,9 @@ const char *scp_error_messages[] = { "Invalid magtape record length", "Console Telnet connection lost", "Console Telnet connection timed out", - "Console Telnet output stall" -}; + "Console Telnet output stall", + "" /* printed by assert */ + }; const size_t size_map[] = { sizeof (int8), sizeof (int8), sizeof (int16), sizeof (int32), sizeof (int32) @@ -422,7 +425,7 @@ const t_value width_mask[] = { 0, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF #endif -}; + }; static CTAB cmd_table[] = { { "RESET", &reset_cmd, 0, @@ -504,6 +507,8 @@ static CTAB cmd_table[] = { "do {arg,arg...} process command file\n" }, { "ECHO", &echo_cmd, 0, "echo display \n" }, + { "ASSERT", &assert_cmd, 0, + "assert {} test simulator state against condition\n" }, { "HELP", &help_cmd, 0, "h{elp} type this message\n" "h{elp} type help for command\n" }, @@ -741,7 +746,7 @@ do { cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */ if (sim_log) fprintf (sim_log, "%s\n", scp_error_messages[stat - SCPE_BASE]); } if (sim_vm_post != NULL) (*sim_vm_post) (TRUE); -} while (stat != SCPE_EXIT); +} while ((stat != SCPE_EXIT) && (stat != SCPE_AFAIL)); fclose (fpin); /* close file */ return (stat == SCPE_EXIT)? SCPE_EXIT: SCPE_OK; @@ -775,6 +780,47 @@ for (ip = instr, op = tmpbuf; *ip && (op < oend); ) { strcpy (instr, tmpbuf); return; } + +/* Assert command + + Syntax: ASSERT {} {} + + If is not specified, CPU is assumed. is expressed in the radix + specified for . and are the same as that + allowed for examine and deposit search specifications. */ + +t_stat assert_cmd (int32 flag, char *cptr) +{ +char gbuf[CBUFSIZE], *gptr, *aptr; +REG *rptr; +uint32 idx; +t_value val; +t_stat r; + +aptr = cptr; /* save assertion */ +cptr = get_sim_opt (CMD_OPT_SW|CMD_OPT_DFT, cptr, &r); /* get sw, default */ +if (*cptr == 0) return SCPE_2FARG; /* must be more */ +cptr = get_glyph (cptr, gbuf, 0); /* get register */ +rptr = find_reg (gbuf, &gptr, sim_dfdev); /* parse register */ +if (!rptr) return SCPE_NXREG; /* not there */ +if (*gptr == '[') { /* subscript? */ + if (rptr->depth <= 1) return SCPE_ARG; /* array register? */ + idx = (uint32) strtotv (++gptr, &cptr, 10); /* convert index */ + if ((gptr == cptr) || (*cptr++ != ']')) return SCPE_ARG; + } +else idx = 0; /* not array */ +if (idx >= rptr->depth) return SCPE_SUB; /* validate subscript */ +if (*cptr == 0) return SCPE_2FARG; /* must be more */ +cptr = get_glyph (cptr, gbuf, 0); /* get search cond */ +if (*cptr != 0) return SCPE_2MARG; /* must be done */ +if (!get_search (gbuf, rptr->radix, &sim_stab)) /* parse condition */ + return SCPE_MISVAL; +val = get_rval (rptr, idx); /* get register value */ +if (test_search (val, &sim_stab)) return SCPE_OK; /* test condition */ +printf ("Assertion failed (%s)", aptr); /* report failing assertion */ +if (sim_log) fprintf (sim_log, "Assertion failed (%s)", aptr); +return SCPE_AFAIL; /* condition fails */ +} /* Set command */ @@ -2950,6 +2996,7 @@ DEVICE *dptr; REG *rptr, *srptr = NULL; for (i = 0; (dptr = sim_devices[i]) != 0; i++) { /* all dev */ + if (dptr->flags & DEV_DIS) continue; /* skip disabled */ if (rptr = find_reg (cptr, optr, dptr)) { /* found? */ if (srptr) return NULL; /* ambig? err */ srptr = rptr; /* save reg */ @@ -3077,7 +3124,7 @@ while (*cptr) { /* loop through modifiers */ return NULL; } sim_switches = sim_switches | t; } /* or in new switches */ else if ((opt & CMD_OPT_SCH) && /* if allowed, */ - get_search (gbuf, sim_dfdev, &sim_stab)) /* try for search */ + get_search (gbuf, sim_dfdev->dradix, &sim_stab)) /* try for search */ sim_schptr = &sim_stab; /* set search */ else if ((opt & CMD_OPT_DFT) && /* if allowed, */ (tdptr = find_unit (gbuf, &tuptr)) && /* try for default */ @@ -3115,14 +3162,14 @@ return pptr; Inputs: cptr = pointer to input string - dptr = pointer to device + radix = radix for numbers schptr = pointer to search table Outputs: return = NULL if error schptr if valid search specification */ -SCHTAB *get_search (char *cptr, DEVICE *dptr, SCHTAB *schptr) +SCHTAB *get_search (char *cptr, int32 radix, SCHTAB *schptr) { int32 c, logop, cmpop; t_value logval, cmpval; @@ -3133,7 +3180,7 @@ if (*cptr == 0) return NULL; /* check for clause */ for (logop = cmpop = -1; c = *cptr++; ) { /* loop thru clauses */ if (sptr = strchr (logstr, c)) { /* check for mask */ logop = sptr - logstr; - logval = strtotv (cptr, &tptr, dptr->dradix); + logval = strtotv (cptr, &tptr, radix); if (cptr == tptr) return NULL; cptr = tptr; } else if (sptr = strchr (cmpstr, c)) { /* check for bool */ @@ -3141,7 +3188,7 @@ for (logop = cmpop = -1; c = *cptr++; ) { /* loop thru clauses */ if (*cptr == '=') { cmpop = cmpop + strlen (cmpstr); cptr++; } - cmpval = strtotv (cptr, &tptr, dptr->dradix); + cmpval = strtotv (cptr, &tptr, radix); if (cptr == tptr) return NULL; cptr = tptr; } else return NULL; } /* end while */ diff --git a/scp.h b/scp.h index b467502f..6ebeac75 100644 --- a/scp.h +++ b/scp.h @@ -1,6 +1,6 @@ /* scp.h: simulator control program headers - Copyright (c) 1993-2004, Robert M Supnik + Copyright (c) 1993-2005, 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 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 07-Feb-05 RMS Added ASSERT command 09-Sep-04 RMS Added reset_all_p 14-Feb-04 RMS Added debug prototypes (from Dave Hittner) 02-Jan-04 RMS Split out from SCP @@ -64,6 +65,7 @@ t_stat set_cmd (int32 flag, char *ptr); t_stat show_cmd (int32 flag, char *ptr); t_stat brk_cmd (int32 flag, char *ptr); t_stat do_cmd (int32 flag, char *ptr); +t_stat assert_cmd (int32 flag, char *ptr); t_stat help_cmd (int32 flag, char *ptr); t_stat spawn_cmd (int32 flag, char *ptr); t_stat echo_cmd (int32 flag, char *ptr); diff --git a/sim_defs.h b/sim_defs.h index 21d7a376..8d01653e 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -1,6 +1,6 @@ /* sim_defs.h: simulator definitions - Copyright (c) 1993-2004, Robert M Supnik + Copyright (c) 1993-2005, 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 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 07-Feb-05 RMS Added assertion fail stop 05-Nov-04 RMS Added support for SHOW opt=val 20-Oct-04 RMS Converted all base types to typedefs 21-Sep-04 RMS Added switch to flag stop message printout @@ -209,6 +210,7 @@ typedef uint32 t_addr; #define SCPE_LOST (SCPE_BASE + 39) /* Telnet conn lost */ #define SCPE_TTMO (SCPE_BASE + 40) /* Telnet conn timeout */ #define SCPE_STALL (SCPE_BASE + 41) /* Telnet conn stall */ +#define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */ #define SCPE_KFLAG 0010000 /* tti data flag */ #define SCPE_BREAK 0020000 /* tti break flag */ @@ -267,7 +269,7 @@ struct sim_device { /* Device flags */ -#define DEV_V_DIS 0 /* dev enabled */ +#define DEV_V_DIS 0 /* dev disabled */ #define DEV_V_DISABLE 1 /* dev disable-able */ #define DEV_V_DYNM 2 /* mem size dynamic */ #define DEV_V_NET 3 /* network attach */ diff --git a/sim_rev.h b/sim_rev.h index 697c2965..f5e2b04d 100644 --- a/sim_rev.h +++ b/sim_rev.h @@ -29,12 +29,46 @@ #define SIM_MAJOR 3 #define SIM_MINOR 3 -#define SIM_PATCH 1 +#define SIM_PATCH 2 /* V3.3 revision history patch date module(s) and fix(es) + 2 08-Mar-05 scp.c: added ASSERT command (from Dave Bryan) + + h316_defs.h: fixed IORETURN macro + + h316_mt.c: fixed error reporting from OCP (found by Philipp Hachtmann) + + h316_stddev.c: fixed bug in OCP '0001 (found by Philipp Hachtmann) + + hp2100_cpu.c: split out EAU and MAC instructions + + hp2100_cpu1.c: (from Dave Bryan) + - fixed missing MPCK on JRS target + - removed EXECUTE instruction (is NOP in actual microcode) + + hp2100_fp: (from Dave Bryan) + - fixed missing negative overflow renorm in StoreFP + + i1401_lp.c: fixed bug in write_line (reported by Van Snyder) + + id32_cpu.c: fixed branches to mask new PC (from Greg Johnson) + + pdp11_cpu.c: fixed bugs in RESET for 11/70 (reported by Tim Chapman) + + pdp11_cpumod.c: + - fixed bug in SHOW MODEL (from Sergey Okhapkin) + - made SYSID variable for 11/70 (from Tim Chapman) + - added MBRK write case for 11/70 (from Tim Chapman) + + pdp11_rq: added RA60, RA71, RA81 disks + + pdp11_ry: fixed bug in boot code (reported by Graham Toal) + + vax_cpu.c: fixed initial state of cpu_extmem + 1 05-Jan-05 h316_cpu.c: fixed bug in DIV h316_stddev.c: diff --git a/simh_doc.txt b/simh_doc.txt index 2a573e80..efaf9a2d 100644 --- a/simh_doc.txt +++ b/simh_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: Simulator Usage, V3.3 -Date: 15-Nov-2004 +Date: 25-Jan-2005 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2004, written by Robert M Supnik - Copyright (c) 1993-2004, Robert M Supnik + Original code published in 1993-2005, written by Robert M Supnik + Copyright (c) 1993-2005, 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"), @@ -426,7 +426,7 @@ the console. An output file modifier consists of @ followed by a valid file name. Modifiers may be specified in any order. If multiple modifiers of the -same time are specified, later modifiers override earlier modifiers. +same type are specified, later modifiers override earlier modifiers. Note that if the device/unit name comes after the search specifier, the values will interpreted in the radix of the CPU, rather than of the device/unit.