From ec60bbf3295c5390e42c12b99db19aa9e86c3f16 Mon Sep 17 00:00:00 2001 From: Bob Supnik Date: Tue, 3 May 2005 04:10:00 -0700 Subject: [PATCH] Notes For V3.4-0 The memory layout for the Interdata simulators has been changed. Do not use Interdata SAVE files from prior revisions with V3.4. 1. New Features in 3.4 1.1 SCP and Libraries - Revised interpretation of fprint_sym, fparse_sym returns - Revised syntax for SET DEBUG - DO command nesting allowed to ten levels 1.2 Interdata - Revised memory model to be 16b instead of 8b 1.3 HP2100 - Added Fast FORTRAN Processor instructions - Added SET OFFLINE/ONLINE and SET UNLOAD/LOAD commands to tapes and disks 2. Bugs Fixed in 3.4-0 2.1 Interdata - Fixed bug in show history routine (from Mark Hittinger) - Fixed bug in initial memory allocation 2.2 PDP-10 - Fixed TU bug, ERASE and WREOF should not clear done (reported by Rich Alderson) - Fixed TU error reporting 2.3 PDP-11 - Fixed TU error reporting --- 0readme_33.txt | 47 - 0readme_34.txt | 38 + AltairZ80/altairZ80_cpu.c | 1380 ++++++++----------- AltairZ80/altairZ80_defs.h | 8 +- AltairZ80/altairZ80_dsk.c | 4 +- AltairZ80/altairZ80_sio.c | 10 +- AltairZ80/altairZ80_sys.c | 6 +- AltairZ80/altairz80_doc.txt | 113 +- AltairZ80/altairz80_hdsk.c | 2 +- HP2100/hp2100_cpu.c | 201 +-- HP2100/hp2100_cpu.h | 72 +- HP2100/hp2100_cpu1.c | 2550 ++++++++++++++++++++++++----------- HP2100/hp2100_defs.h | 2 +- HP2100/hp2100_diag.txt | 240 +++- HP2100/hp2100_doc.txt | 72 +- HP2100/hp2100_dp.c | 68 +- HP2100/hp2100_dq.c | 50 +- HP2100/hp2100_ds.c | 75 +- HP2100/hp2100_fp.c | 42 + HP2100/hp2100_fp1.c | 508 +++++++ HP2100/hp2100_fp1.h | 52 + HP2100/hp2100_ms.c | 41 +- Interdata/id16_cpu.c | 32 +- Interdata/id16_sys.c | 170 ++- Interdata/id32_cpu.c | 41 +- Interdata/id32_sys.c | 214 ++- Interdata/id_defs.h | 2 + Interdata/id_doc.txt | 33 +- Interdata/id_dp.c | 4 +- Interdata/id_mt.c | 4 +- NOVA/nova_mta.c | 4 +- PDP10/pdp10_lp20.c | 4 +- PDP10/pdp10_rp.c | 4 +- PDP10/pdp10_tu.c | 52 +- PDP11/pdp11_hk.c | 4 +- PDP11/pdp11_rp.c | 4 +- PDP11/pdp11_sys.c | 115 +- PDP11/pdp11_tm.c | 4 +- PDP11/pdp11_tq.c | 3 +- PDP11/pdp11_ts.c | 4 +- PDP11/pdp11_tu.c | 30 +- PDP11/pdp11_xu.c | 5 +- PDP18B/pdp18b_mt.c | 4 +- PDP8/pdp8_mt.c | 4 +- VAX/vax780_defs.h | 403 ------ VAX/vax780_doc.txt | 1079 --------------- VAX/vax780_mba.c | 696 ---------- VAX/vax780_sbimem.c | 901 ------------- VAX/vax780_stddev.c | 851 ------------ VAX/vax780_syslist.c | 130 -- VAX/vax780_uba.c | 1104 --------------- VAX/vax_cis.c | 56 +- VAX/vax_octa.c | 88 +- VAX/vax_sysdev.c | 5 +- descrip.mms | 8 +- makefile | 5 +- scp.c | 166 ++- sim_defs.h | 19 +- sim_rev.h | 44 +- sim_sock.c | 7 +- sim_sock.h | 4 +- simh_doc.txt | 76 +- 62 files changed, 4332 insertions(+), 7632 deletions(-) delete mode 100644 0readme_33.txt create mode 100644 0readme_34.txt create mode 100644 HP2100/hp2100_fp1.c create mode 100644 HP2100/hp2100_fp1.h delete mode 100644 VAX/vax780_defs.h delete mode 100644 VAX/vax780_doc.txt delete mode 100644 VAX/vax780_mba.c delete mode 100644 VAX/vax780_sbimem.c delete mode 100644 VAX/vax780_stddev.c delete mode 100644 VAX/vax780_syslist.c delete mode 100644 VAX/vax780_uba.c diff --git a/0readme_33.txt b/0readme_33.txt deleted file mode 100644 index f91abb1f..00000000 --- a/0readme_33.txt +++ /dev/null @@ -1,47 +0,0 @@ -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) - - diff --git a/0readme_34.txt b/0readme_34.txt new file mode 100644 index 00000000..0c13058c --- /dev/null +++ b/0readme_34.txt @@ -0,0 +1,38 @@ +Notes For V3.4-0 + +The memory layout for the Interdata simulators has been changed. +Do not use Interdata SAVE files from prior revisions with V3.4. + +1. New Features in 3.4 + +1.1 SCP and Libraries + +- Revised interpretation of fprint_sym, fparse_sym returns +- Revised syntax for SET DEBUG +- DO command nesting allowed to ten levels + +1.2 Interdata + +- Revised memory model to be 16b instead of 8b + +1.3 HP2100 + +- Added Fast FORTRAN Processor instructions +- Added SET OFFLINE/ONLINE and SET UNLOAD/LOAD commands to tapes and disks + +2. Bugs Fixed in 3.4-0 + +2.1 Interdata + +- Fixed bug in show history routine (from Mark Hittinger) +- Fixed bug in initial memory allocation + +2.2 PDP-10 + +- Fixed TU bug, ERASE and WREOF should not clear done (reported by + Rich Alderson) +- Fixed TU error reporting + +2.3 PDP-11 + +- Fixed TU error reporting diff --git a/AltairZ80/altairZ80_cpu.c b/AltairZ80/altairZ80_cpu.c index 559e7741..5fe951ee 100644 --- a/AltairZ80/altairZ80_cpu.c +++ b/AltairZ80/altairZ80_cpu.c @@ -1,6 +1,6 @@ /* altairz80_cpu.c: MITS Altair CPU (8080 and Z80) - Copyright (c) 2002-2004, Peter Schorn + Copyright (c) 2002-2005, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -44,25 +44,6 @@ #define STOP_MEM 2 /* breakpoint (memory access) */ #define STOP_OPCODE 3 /* unknown 8080 or Z80 instruction */ -/* two sets of accumulator / flags */ -static uint16 af[2]; -static int af_sel; - -/* two sets of 16-bit registers */ -static struct ddregs { - uint16 bc; - uint16 de; - uint16 hl; -} regs[2]; -static int regs_sel; - -static uint16 ir; -static uint16 ix; -static uint16 iy; -static uint16 sp; -static uint16 pc; -static uint16 IFF; - #define FLAG_C 1 #define FLAG_N 2 #define FLAG_P 4 @@ -89,15 +70,6 @@ static uint16 IFF; #define SetPV (SetPVS(sum)) #define SetPV2(x) ((cpu_unit.flags & UNIT_CHIP) ? (((temp == (x)) << 2)) : (parity(temp))) -/* checkCPU8080 must be invoked whenever a Z80 only instruction is executed */ -/* -#define checkCPU8080 \ - if (((cpu_unit.flags & UNIT_CHIP) == 0) && (cpu_unit.flags & UNIT_OPSTOP)) {\ - reason = STOP_OPCODE; \ - goto end_decode; \ - } -*/ - /* checkCPU8080 must be invoked whenever a Z80 only instruction is executed In case a Z80 instruction is executed on an 8080 the following two cases exist: 1) Trapping is enabled: execution stops @@ -128,7 +100,7 @@ static uint16 IFF; } #define JPC(cond) { \ - updateTStates(10); \ + tStates += 10; \ if (cond) { \ PCQ_ENTRY(PC - 1); \ PC = GetWORD(PC); \ @@ -145,12 +117,12 @@ static uint16 IFF; PUSH(PC + 2); \ PCQ_ENTRY(PC - 1); \ PC = adrr; \ - updateTStates(17); \ + tStates += 17; \ } \ else { \ sim_brk_pend = FALSE; \ PC += 2; \ - updateTStates(10); \ + tStates += 10; \ } \ } @@ -173,13 +145,13 @@ extern void printMessage(void); 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); -int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag); +t_stat sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag); void PutBYTEBasic(const uint32 Addr, const uint32 Bank, const uint32 Value); void PutBYTEForced(register uint32 Addr, register uint32 Value); int32 addressIsInROM(const uint32 Addr); int32 addressExists(const uint32 Addr); -int32 sim_instr(void); +t_stat sim_instr(void); int32 install_bootrom(void); void protect(const int32 l, const int32 h); void printROMMessage(const uint32 cntROM); @@ -189,8 +161,6 @@ int32 getBankSelect(void); void setBankSelect(int32 b); uint32 getCommon(void); void setCommon(uint32 c); - -#if !defined(ALTAIROPT) static void warnUnsuccessfulWriteAttempt(const uint32 Addr); static uint8 warnUnsuccessfulReadAttempt(const uint32 Addr); static t_stat cpu_set_rom (UNIT *uptr, int32 value, char *cptr, void *desc); @@ -199,8 +169,6 @@ static t_stat cpu_set_altairrom (UNIT *uptr, int32 value, char *cptr, void *desc static t_stat cpu_set_warnrom (UNIT *uptr, int32 value, char *cptr, void *desc); static t_stat cpu_set_banked (UNIT *uptr, int32 value, char *cptr, void *desc); static t_stat cpu_set_nonbanked (UNIT *uptr, int32 value, char *cptr, void *desc); -#endif - static t_stat cpu_set_size (UNIT *uptr, int32 value, char *cptr, void *desc); static void prepareMemoryAccessMessage(t_addr loc); static void checkROMBoundaries(void); @@ -239,18 +207,14 @@ static int32 HL1_S; /* alternate HL register */ static int32 IFF_S; /* interrupt Flip Flop */ static int32 IR_S; /* interrupt (upper)/refresh (lower) register */ int32 SR = 0; /* switch register */ - -#if !defined(ALTAIROPT) static int32 bankSelect = 0; /* determines selected memory bank */ static uint32 common = 0xc000; /* addresses >= 'common' are in common memory */ -#endif - static uint32 ROMLow = defaultROMLow; /* lowest address of ROM */ static uint32 ROMHigh = defaultROMHigh; /* highest address of ROM */ static uint32 previousCapacity= 0; /* safe for previous memory capacity */ static uint32 clockFrequency = 0; /* in kHz, 0 means as fast as possible */ static uint32 sliceLength = 10; /* length of time-slice for CPU speed */ - /* adjustment in milliseonds */ + /* adjustment in milliseconds */ static uint32 executedTStates = 0; /* executed t-states */ static uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */ static int32 pcq_p = 0; /* PC queue ptr */ @@ -274,17 +238,10 @@ REG cpu_reg[] = { { FLDATA (Z80, cpu_unit.flags, UNIT_V_CHIP), REG_HRO }, { FLDATA (OPSTOP, cpu_unit.flags, UNIT_V_OPSTOP), REG_HRO }, { HRDATA (SR, SR, 8) }, - -#if defined(ALTAIROPT) - { HRDATA (ROMLOW, ROMLow, 16), REG_RO }, - { HRDATA (ROMHIGH, ROMHigh, 16), REG_RO }, -#else { HRDATA (BANK, bankSelect, MAXBANKSLOG2) }, { HRDATA (COMMON, common, 16) }, { HRDATA (ROMLOW, ROMLow, 16) }, { HRDATA (ROMHIGH, ROMHigh, 16) }, -#endif - { DRDATA (CLOCK, clockFrequency, 32) }, { DRDATA (SLICE, sliceLength, 16) }, { DRDATA (TSTATES, executedTStates,32), REG_RO }, @@ -300,8 +257,6 @@ static MTAB cpu_mod[] = { { UNIT_CHIP, 0, "8080", "8080", NULL }, { UNIT_OPSTOP, UNIT_OPSTOP, "ITRAP", "ITRAP", NULL }, { UNIT_OPSTOP, 0, "NOITRAP", "NOITRAP", NULL }, - -#if !defined(ALTAIROPT) { UNIT_BANKED, UNIT_BANKED, "BANKED", "BANKED", &cpu_set_banked }, { UNIT_BANKED, 0, "NONBANKED", "NONBANKED", &cpu_set_nonbanked }, { UNIT_ROM, UNIT_ROM, "ROM", "ROM", &cpu_set_rom }, @@ -310,8 +265,6 @@ static MTAB cpu_mod[] = { { UNIT_ALTAIRROM, 0, "NOALTAIRROM", "NOALTAIRROM", NULL }, { UNIT_WARNROM, UNIT_WARNROM, "WARNROM", "WARNROM", &cpu_set_warnrom }, { UNIT_WARNROM, 0, "NOWARNROM", "NOWARNROM", NULL }, -#endif - { UNIT_MSIZE, 4 * KB, NULL, "4K", &cpu_set_size }, { UNIT_MSIZE, 8 * KB, NULL, "8K", &cpu_set_size }, { UNIT_MSIZE, 12 * KB, NULL, "12K", &cpu_set_size }, @@ -1492,10 +1445,7 @@ static void altairz80_init(void) { } */ -/* Memory management. Two options available: - 1) All features (ROM checking, ROM boundaries definable at run time, banked memory) - 2) Bare bones (faster, no checking, no banked memory) - define ALTAIROPT -*/ +/* Memory management */ static int32 lowProtect; static int32 highProtect; @@ -1507,101 +1457,6 @@ void protect(const int32 l, const int32 h) { highProtect = h; } -#if defined(ALTAIROPT) - -static uint8 M[MAXMEMSIZE]; /* RAM which is present */ - -/* determine whether Addr points to Read Only Memory */ -INLINE int32 addressIsInROM(const uint32 Addr) { - return FALSE; -} - -/* determine whether Addr points to a valid memory address */ -INLINE int32 addressExists(const uint32 Addr) { - return TRUE; -} - -#if defined(ALTAIROPTMACRO) - -#define GetBYTE(Addr) M[(Addr) & ADDRMASK] - -#define PutBYTE(Addr, Value) M[(Addr) & ADDRMASK] = Value; - -#define PutWORD(Addr, Value) \ - M[(Addr) & ADDRMASK] = Value; \ - M[((Addr) + 1) & ADDRMASK] = Value >> 8; - -#else - -static INLINE uint8 GetBYTE(register uint32 Addr) { - return M[Addr & ADDRMASK]; -} - -static INLINE void PutBYTE(register uint32 Addr, register uint32 Value) { - M[Addr & ADDRMASK] = Value; -} - -static INLINE void PutWORD(register uint32 Addr, register uint32 Value) { - M[Addr & ADDRMASK] = Value; - M[(Addr + 1) & ADDRMASK] = Value >> 8; -} - -#endif - -INLINE void PutBYTEForced(register uint32 Addr, register uint32 Value) { - M[Addr & ADDRMASK] = Value; -} - -void PutBYTEBasic(const uint32 Addr, const uint32 Bank, const uint32 Value) { - M[Addr & ADDRMASK] = Value; -} - -int32 install_bootrom(void) { - extern int32 bootrom[bootrom_size]; - int32 i, cnt = 0; - for (i = 0; i < bootrom_size; i++) { - if (M[i + defaultROMLow] != (bootrom[i] & 0xff)) { - cnt++; - M[i + defaultROMLow] = bootrom[i] & 0xff; - } - } - return cnt; -} - -static void resetCell(const int32 address, const int32 bank) { - if (!(isProtected && (lowProtect <= address) && (address <= highProtect))) { - M[address] = 0; - } -} - -/* memory examine */ -t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) { - *vptr = M[addr & ADDRMASK]; - return SCPE_OK; -} - -/* memory deposit */ -t_stat cpu_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw) { - M[addr & ADDRMASK] = val & 0xff; - return SCPE_OK; -} - -int32 getBankSelect(void) { - return 0; -} - -void setBankSelect(int32 b) { -} - -uint32 getCommon(void) { - return 0; -} - -void setCommon(uint32 c) { -} - -#else - static uint8 M[MAXMEMSIZE][MAXBANKS]; /* RAM which is present */ static void warnUnsuccessfulWriteAttempt(const uint32 Addr) { @@ -1776,8 +1631,6 @@ void setCommon(uint32 c) { common = c; } -#endif - uint8 GetBYTEWrapper(register uint32 Addr) { /* make sure that non-inlined version exists */ return GetBYTE(Addr); } @@ -1865,16 +1718,7 @@ static void prepareMemoryAccessMessage(t_addr loc) { #define CheckBreakWord(a) CheckBreakTwoBytes(a, (a + 1)) -#define updateTStates(n) \ - tStates += n; \ - if (sim_step) { \ - if (sim_switches & SWMASK ('T')) { sim_step -= n; } else { sim_step--; } \ - if (sim_step <= 0) { reason = SCPE_STOP; goto end_decode; } \ - } - -int32 sim_instr (void) { - extern int32 sim_switches; - extern int32 sim_step; +t_stat sim_instr (void) { extern int32 sim_interval; extern t_bool sim_brk_pend; extern int32 timerInterrupt; @@ -1905,30 +1749,14 @@ int32 sim_instr (void) { uint32 startTime; int32 br1, br2, tStateModifier = FALSE; - sim_cancel_step (); - pc = saved_PC & ADDRMASK; /* load local PC */ - af[af_sel] = AF_S; - regs[regs_sel].bc = BC_S; - regs[regs_sel].de = DE_S; - regs[regs_sel].hl = HL_S; - ix = IX_S; - iy = IY_S; - sp = SP_S; - af[1 - af_sel] = AF1_S; - regs[1 - regs_sel].bc = BC1_S; - regs[1 - regs_sel].de = DE1_S; - regs[1 - regs_sel].hl = HL1_S; - IFF = IFF_S; - ir = IR_S; - - AF = af[af_sel]; - BC = regs[regs_sel].bc; - DE = regs[regs_sel].de; - HL = regs[regs_sel].hl; - PC = pc; - SP = sp; - IX = ix; - IY = iy; + AF = AF_S; + BC = BC_S; + DE = DE_S; + HL = HL_S; + PC = saved_PC & ADDRMASK; + SP = SP_S; + IX = IX_S; + IY = IY_S; specialProcessing = clockFrequency | timerInterrupt | sim_brk_summ; tStates = 0; if (rtc_avail) { @@ -1967,11 +1795,11 @@ int32 sim_instr (void) { #endif } - if (timerInterrupt && (IFF & 1)) { + if (timerInterrupt && (IFF_S & 1)) { timerInterrupt = FALSE; specialProcessing = clockFrequency | sim_brk_summ; - IFF = 0; /* disable interrupts */ - CheckBreakTwoBytesExtended(SP - 2, SP - 1, (timerInterrupt = TRUE, IFF |= 1)); + IFF_S = 0; /* disable interrupts */ + CheckBreakTwoBytesExtended(SP - 2, SP - 1, (timerInterrupt = TRUE, IFF_S |= 1)); PUSH(PC); PCQ_ENTRY(PC - 1); PC = timerInterruptHandler & ADDRMASK; @@ -1992,60 +1820,60 @@ int32 sim_instr (void) { */ switch(RAM_pp(PC)) { case 0x00: /* NOP */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; break; case 0x01: /* LD BC,nnnn */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; BC = GetWORD(PC); PC += 2; break; case 0x02: /* LD (BC),A */ - updateTStates(7); + tStates += 7; CheckBreakByte(BC) PutBYTE(BC, hreg(AF)); break; case 0x03: /* INC BC */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; ++BC; break; case 0x04: /* INC B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC += 0x100; temp = hreg(BC); AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); /* SetPV2 uses temp */ break; case 0x05: /* DEC B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC -= 0x100; temp = hreg(BC); AF = (AF & ~0xfe) | decTable[temp] | SetPV2(0x7f); /* SetPV2 uses temp */ break; case 0x06: /* LD B,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; Sethreg(BC, RAM_pp(PC)); break; case 0x07: /* RLCA */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) | (AF & 0xc4) | ((AF >> 15) & 1); break; case 0x08: /* EX AF,AF' */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; checkCPU8080; - af[af_sel] = AF; - af_sel = 1 - af_sel; - AF = af[af_sel]; + temp = AF; + AF = AF1_S; + AF1_S = temp; break; case 0x09: /* ADD HL,BC */ - updateTStates(11); + tStates += 11; sim_brk_pend = FALSE; HL &= ADDRMASK; BC &= ADDRMASK; @@ -2054,36 +1882,36 @@ int32 sim_instr (void) { HL = sum; break; case 0x0a: /* LD A,(BC) */ - updateTStates(7); + tStates += 7; CheckBreakByte(BC) Sethreg(AF, GetBYTE(BC)); break; case 0x0b: /* DEC BC */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; --BC; break; case 0x0c: /* INC C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC) + 1; Setlreg(BC, temp); AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x0d: /* DEC C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC) - 1; Setlreg(BC, temp); AF = (AF & ~0xfe) | decTable[temp & 0xff] | SetPV2(0x7f); break; case 0x0e: /* LD C,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; Setlreg(BC, RAM_pp(PC)); break; case 0x0f: /* RRCA */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & 0xc4) | rrcaTable[hreg(AF)]; break; @@ -2092,64 +1920,64 @@ int32 sim_instr (void) { checkCPU8080; if ((BC -= 0x100) & 0xff00) { PCQ_ENTRY(PC - 1); - PC += (signed char) GetBYTE(PC) + 1; - updateTStates(13); + PC += (int8) GetBYTE(PC) + 1; + tStates += 13; } else { PC++; - updateTStates(8); + tStates += 8; } break; case 0x11: /* LD DE,nnnn */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; DE = GetWORD(PC); PC += 2; break; case 0x12: /* LD (DE),A */ - updateTStates(7); + tStates += 7; CheckBreakByte(DE) PutBYTE(DE, hreg(AF)); break; case 0x13: /* INC DE */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; ++DE; break; case 0x14: /* INC D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE += 0x100; temp = hreg(DE); AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); /* SetPV2 uses temp */ break; case 0x15: /* DEC D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE -= 0x100; temp = hreg(DE); AF = (AF & ~0xfe) | decTable[temp] | SetPV2(0x7f); /* SetPV2 uses temp */ break; case 0x16: /* LD D,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; Sethreg(DE, RAM_pp(PC)); break; case 0x17: /* RLA */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) | (AF & 0xc4) | ((AF >> 15) & 1); break; case 0x18: /* JR dd */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; checkCPU8080; PCQ_ENTRY(PC - 1); - PC += (signed char) GetBYTE(PC) + 1; + PC += (int8) GetBYTE(PC) + 1; break; case 0x19: /* ADD HL,DE */ - updateTStates(11); + tStates += 11; sim_brk_pend = FALSE; HL &= ADDRMASK; DE &= ADDRMASK; @@ -2158,36 +1986,36 @@ int32 sim_instr (void) { HL = sum; break; case 0x1a: /* LD A,(DE) */ - updateTStates(7); + tStates += 7; CheckBreakByte(DE) Sethreg(AF, GetBYTE(DE)); break; case 0x1b: /* DEC DE */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; --DE; break; case 0x1c: /* INC E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE) + 1; Setlreg(DE, temp); AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x1d: /* DEC E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE) - 1; Setlreg(DE, temp); AF = (AF & ~0xfe) | decTable[temp & 0xff] | SetPV2(0x7f); break; case 0x1e: /* LD E,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; Setlreg(DE, RAM_pp(PC)); break; case 0x1f: /* RRA */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = ((AF & 1) << 15) | (AF & 0xc4) | rraTable[hreg(AF)]; break; @@ -2196,53 +2024,53 @@ int32 sim_instr (void) { checkCPU8080; if (TSTFLAG(Z)) { PC++; - updateTStates(7); + tStates += 7; } else { PCQ_ENTRY(PC - 1); - PC += (signed char) GetBYTE(PC) + 1; - updateTStates(12); + PC += (int8) GetBYTE(PC) + 1; + tStates += 12; } break; case 0x21: /* LD HL,nnnn */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; HL = GetWORD(PC); PC += 2; break; case 0x22: /* LD (nnnn),HL */ - updateTStates(16); + tStates += 16; temp = GetWORD(PC); CheckBreakWord(temp); PutWORD(temp, HL); PC += 2; break; case 0x23: /* INC HL */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; ++HL; break; case 0x24: /* INC H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL += 0x100; temp = hreg(HL); AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); /* SetPV2 uses temp */ break; case 0x25: /* DEC H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL -= 0x100; temp = hreg(HL); AF = (AF & ~0xfe) | decTable[temp] | SetPV2(0x7f); /* SetPV2 uses temp */ break; case 0x26: /* LD H,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; Sethreg(HL, RAM_pp(PC)); break; case 0x27: /* DAA */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; acu = hreg(AF); temp = ldig(acu); @@ -2276,16 +2104,16 @@ int32 sim_instr (void) { checkCPU8080; if (TSTFLAG(Z)) { PCQ_ENTRY(PC - 1); - PC += (signed char) GetBYTE(PC) + 1; - updateTStates(12); + PC += (int8) GetBYTE(PC) + 1; + tStates += 12; } else { PC++; - updateTStates(7); + tStates += 7; } break; case 0x29: /* ADD HL,HL */ - updateTStates(11); + tStates += 11; sim_brk_pend = FALSE; HL &= ADDRMASK; sum = HL + HL; @@ -2293,38 +2121,38 @@ int32 sim_instr (void) { HL = sum; break; case 0x2a: /* LD HL,(nnnn) */ - updateTStates(16); + tStates += 16; temp = GetWORD(PC); CheckBreakWord(temp); HL = GetWORD(temp); PC += 2; break; case 0x2b: /* DEC HL */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; --HL; break; case 0x2c: /* INC L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL) + 1; Setlreg(HL, temp); AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x2d: /* DEC L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL) - 1; Setlreg(HL, temp); AF = (AF & ~0xfe) | decTable[temp & 0xff] | SetPV2(0x7f); break; case 0x2e: /* LD L,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; Setlreg(HL, RAM_pp(PC)); break; case 0x2f: /* CPL */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12; break; @@ -2333,53 +2161,53 @@ int32 sim_instr (void) { checkCPU8080; if (TSTFLAG(C)) { PC++; - updateTStates(7); + tStates += 7; } else { PCQ_ENTRY(PC - 1); - PC += (signed char) GetBYTE(PC) + 1; - updateTStates(12); + PC += (int8) GetBYTE(PC) + 1; + tStates += 12; } break; case 0x31: /* LD SP,nnnn */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; SP = GetWORD(PC); PC += 2; break; case 0x32: /* LD (nnnn),A */ - updateTStates(13); + tStates += 13; temp = GetWORD(PC); CheckBreakByte(temp); PutBYTE(temp, hreg(AF)); PC += 2; break; case 0x33: /* INC SP */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; ++SP; break; case 0x34: /* INC (HL) */ - updateTStates(11); + tStates += 11; CheckBreakByte(HL); temp = GetBYTE(HL) + 1; PutBYTE(HL, temp); AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x35: /* DEC (HL) */ - updateTStates(11); + tStates += 11; CheckBreakByte(HL); temp = GetBYTE(HL) - 1; PutBYTE(HL, temp); AF = (AF & ~0xfe) | decTable[temp & 0xff] | SetPV2(0x7f); break; case 0x36: /* LD (HL),nn */ - updateTStates(10); + tStates += 10; CheckBreakByte(HL); PutBYTE(HL, RAM_pp(PC)); break; case 0x37: /* SCF */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | 1; break; @@ -2388,16 +2216,16 @@ int32 sim_instr (void) { checkCPU8080; if (TSTFLAG(C)) { PCQ_ENTRY(PC - 1); - PC += (signed char) GetBYTE(PC) + 1; - updateTStates(12); + PC += (int8) GetBYTE(PC) + 1; + tStates += 12; } else { PC++; - updateTStates(7); + tStates += 7; } break; case 0x39: /* ADD HL,SP */ - updateTStates(11); + tStates += 11; sim_brk_pend = FALSE; HL &= ADDRMASK; SP &= ADDRMASK; @@ -2406,357 +2234,357 @@ int32 sim_instr (void) { HL = sum; break; case 0x3a: /* LD A,(nnnn) */ - updateTStates(13); + tStates += 13; temp = GetWORD(PC); CheckBreakByte(temp); Sethreg(AF, GetBYTE(temp)); PC += 2; break; case 0x3b: /* DEC SP */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; --SP; break; case 0x3c: /* INC A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF += 0x100; temp = hreg(AF); AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); /* SetPV2 uses temp */ break; case 0x3d: /* DEC A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF -= 0x100; temp = hreg(AF); AF = (AF & ~0xfe) | decTable[temp] | SetPV2(0x7f); /* SetPV2 uses temp */ break; case 0x3e: /* LD A,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; Sethreg(AF, RAM_pp(PC)); break; case 0x3f: /* CCF */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | ((AF & 1) << 4) | (~AF & 1); break; case 0x40: /* LD B,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; /* nop */ break; case 0x41: /* LD B,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & 0xff) | ((BC & 0xff) << 8); break; case 0x42: /* LD B,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & 0xff) | (DE & ~0xff); break; case 0x43: /* LD B,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & 0xff) | ((DE & 0xff) << 8); break; case 0x44: /* LD B,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & 0xff) | (HL & ~0xff); break; case 0x45: /* LD B,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & 0xff) | ((HL & 0xff) << 8); break; case 0x46: /* LD B,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); Sethreg(BC, GetBYTE(HL)); break; case 0x47: /* LD B,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & 0xff) | (AF & ~0xff); break; case 0x48: /* LD C,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & ~0xff) | ((BC >> 8) & 0xff); break; case 0x49: /* LD C,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; /* nop */ break; case 0x4a: /* LD C,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & ~0xff) | ((DE >> 8) & 0xff); break; case 0x4b: /* LD C,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & ~0xff) | (DE & 0xff); break; case 0x4c: /* LD C,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & ~0xff) | ((HL >> 8) & 0xff); break; case 0x4d: /* LD C,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & ~0xff) | (HL & 0xff); break; case 0x4e: /* LD C,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); Setlreg(BC, GetBYTE(HL)); break; case 0x4f: /* LD C,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; BC = (BC & ~0xff) | ((AF >> 8) & 0xff); break; case 0x50: /* LD D,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & 0xff) | (BC & ~0xff); break; case 0x51: /* LD D,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & 0xff) | ((BC & 0xff) << 8); break; case 0x52: /* LD D,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; /* nop */ break; case 0x53: /* LD D,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & 0xff) | ((DE & 0xff) << 8); break; case 0x54: /* LD D,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & 0xff) | (HL & ~0xff); break; case 0x55: /* LD D,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & 0xff) | ((HL & 0xff) << 8); break; case 0x56: /* LD D,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); Sethreg(DE, GetBYTE(HL)); break; case 0x57: /* LD D,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & 0xff) | (AF & ~0xff); break; case 0x58: /* LD E,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & ~0xff) | ((BC >> 8) & 0xff); break; case 0x59: /* LD E,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & ~0xff) | (BC & 0xff); break; case 0x5a: /* LD E,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & ~0xff) | ((DE >> 8) & 0xff); break; case 0x5b: /* LD E,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; /* nop */ break; case 0x5c: /* LD E,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & ~0xff) | ((HL >> 8) & 0xff); break; case 0x5d: /* LD E,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & ~0xff) | (HL & 0xff); break; case 0x5e: /* LD E,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); Setlreg(DE, GetBYTE(HL)); break; case 0x5f: /* LD E,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; DE = (DE & ~0xff) | ((AF >> 8) & 0xff); break; case 0x60: /* LD H,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & 0xff) | (BC & ~0xff); break; case 0x61: /* LD H,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & 0xff) | ((BC & 0xff) << 8); break; case 0x62: /* LD H,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & 0xff) | (DE & ~0xff); break; case 0x63: /* LD H,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & 0xff) | ((DE & 0xff) << 8); break; case 0x64: /* LD H,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; /* nop */ break; case 0x65: /* LD H,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & 0xff) | ((HL & 0xff) << 8); break; case 0x66: /* LD H,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); Sethreg(HL, GetBYTE(HL)); break; case 0x67: /* LD H,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & 0xff) | (AF & ~0xff); break; case 0x68: /* LD L,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & ~0xff) | ((BC >> 8) & 0xff); break; case 0x69: /* LD L,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & ~0xff) | (BC & 0xff); break; case 0x6a: /* LD L,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & ~0xff) | ((DE >> 8) & 0xff); break; case 0x6b: /* LD L,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & ~0xff) | (DE & 0xff); break; case 0x6c: /* LD L,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & ~0xff) | ((HL >> 8) & 0xff); break; case 0x6d: /* LD L,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; /* nop */ break; case 0x6e: /* LD L,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); Setlreg(HL, GetBYTE(HL)); break; case 0x6f: /* LD L,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; HL = (HL & ~0xff) | ((AF >> 8) & 0xff); break; case 0x70: /* LD (HL),B */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, hreg(BC)); break; case 0x71: /* LD (HL),C */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, lreg(BC)); break; case 0x72: /* LD (HL),D */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, hreg(DE)); break; case 0x73: /* LD (HL),E */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, lreg(DE)); break; case 0x74: /* LD (HL),H */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, hreg(HL)); break; case 0x75: /* LD (HL),L */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, lreg(HL)); break; case 0x76: /* HALT */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; reason = STOP_HALT; PC--; goto end_decode; case 0x77: /* LD (HL),A */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, hreg(AF)); break; case 0x78: /* LD A,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & 0xff) | (BC & ~0xff); break; case 0x79: /* LD A,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & 0xff) | ((BC & 0xff) << 8); break; case 0x7a: /* LD A,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & 0xff) | (DE & ~0xff); break; case 0x7b: /* LD A,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & 0xff) | ((DE & 0xff) << 8); break; case 0x7c: /* LD A,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & 0xff) | (HL & ~0xff); break; case 0x7d: /* LD A,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = (AF & 0xff) | ((HL & 0xff) << 8); break; case 0x7e: /* LD A,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); Sethreg(AF, GetBYTE(HL)); break; case 0x7f: /* LD A,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; /* nop */ break; case 0x80: /* ADD A,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); acu = hreg(AF); @@ -2765,7 +2593,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x81: /* ADD A,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); acu = hreg(AF); @@ -2774,7 +2602,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x82: /* ADD A,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); acu = hreg(AF); @@ -2783,7 +2611,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x83: /* ADD A,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); acu = hreg(AF); @@ -2792,7 +2620,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x84: /* ADD A,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); acu = hreg(AF); @@ -2801,7 +2629,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x85: /* ADD A,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); acu = hreg(AF); @@ -2810,7 +2638,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x86: /* ADD A,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); acu = hreg(AF); @@ -2819,13 +2647,13 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x87: /* ADD A,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; cbits = 2 * hreg(AF); AF = cbitsDup8Table[cbits] | (SetPVS(cbits)); break; case 0x88: /* ADC A,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); acu = hreg(AF); @@ -2834,7 +2662,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x89: /* ADC A,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); acu = hreg(AF); @@ -2843,7 +2671,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8a: /* ADC A,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); acu = hreg(AF); @@ -2852,7 +2680,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8b: /* ADC A,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); acu = hreg(AF); @@ -2861,7 +2689,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8c: /* ADC A,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); acu = hreg(AF); @@ -2870,7 +2698,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8d: /* ADC A,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); acu = hreg(AF); @@ -2879,7 +2707,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8e: /* ADC A,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); acu = hreg(AF); @@ -2888,13 +2716,13 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8f: /* ADC A,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; cbits = 2 * hreg(AF) + TSTFLAG(C); AF = cbitsDup8Table[cbits] | (SetPVS(cbits)); break; case 0x90: /* SUB B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); acu = hreg(AF); @@ -2903,7 +2731,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x91: /* SUB C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); acu = hreg(AF); @@ -2912,7 +2740,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x92: /* SUB D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); acu = hreg(AF); @@ -2921,7 +2749,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x93: /* SUB E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); acu = hreg(AF); @@ -2930,7 +2758,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x94: /* SUB H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); acu = hreg(AF); @@ -2939,7 +2767,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x95: /* SUB L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); acu = hreg(AF); @@ -2948,7 +2776,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x96: /* SUB (HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); acu = hreg(AF); @@ -2957,12 +2785,12 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x97: /* SUB A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = cpu_unit.flags & UNIT_CHIP ? 0x42 : 0x46; break; case 0x98: /* SBC A,B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); acu = hreg(AF); @@ -2971,7 +2799,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x99: /* SBC A,C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); acu = hreg(AF); @@ -2980,7 +2808,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9a: /* SBC A,D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); acu = hreg(AF); @@ -2989,7 +2817,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9b: /* SBC A,E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); acu = hreg(AF); @@ -2998,7 +2826,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9c: /* SBC A,H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); acu = hreg(AF); @@ -3007,7 +2835,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9d: /* SBC A,L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); acu = hreg(AF); @@ -3016,7 +2844,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9e: /* SBC A,(HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); acu = hreg(AF); @@ -3025,133 +2853,133 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9f: /* SBC A,A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; cbits = -TSTFLAG(C); AF = subTable[cbits & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPVS(cbits)); break; case 0xa0: /* AND B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = andTable[((AF & BC) >> 8) & 0xff]; break; case 0xa1: /* AND C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = andTable[((AF >> 8) & BC) & 0xff]; break; case 0xa2: /* AND D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = andTable[((AF & DE) >> 8) & 0xff]; break; case 0xa3: /* AND E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = andTable[((AF >> 8) & DE) & 0xff]; break; case 0xa4: /* AND H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = andTable[((AF & HL) >> 8) & 0xff]; break; case 0xa5: /* AND L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = andTable[((AF >> 8) & HL) & 0xff]; break; case 0xa6: /* AND (HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); AF = andTable[((AF >> 8) & GetBYTE(HL)) & 0xff]; break; case 0xa7: /* AND A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = andTable[(AF >> 8) & 0xff]; break; case 0xa8: /* XOR B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF ^ BC) >> 8) & 0xff]; break; case 0xa9: /* XOR C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) ^ BC) & 0xff]; break; case 0xaa: /* XOR D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF ^ DE) >> 8) & 0xff]; break; case 0xab: /* XOR E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) ^ DE) & 0xff]; break; case 0xac: /* XOR H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF ^ HL) >> 8) & 0xff]; break; case 0xad: /* XOR L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) ^ HL) & 0xff]; break; case 0xae: /* XOR (HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); AF = xororTable[((AF >> 8) ^ GetBYTE(HL)) & 0xff]; break; case 0xaf: /* XOR A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = 0x44; break; case 0xb0: /* OR B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF | BC) >> 8) & 0xff]; break; case 0xb1: /* OR C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) | BC) & 0xff]; break; case 0xb2: /* OR D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF | DE) >> 8) & 0xff]; break; case 0xb3: /* OR E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) | DE) & 0xff]; break; case 0xb4: /* OR H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF | HL) >> 8) & 0xff]; break; case 0xb5: /* OR L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) | HL) & 0xff]; break; case 0xb6: /* OR (HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); AF = xororTable[((AF >> 8) | GetBYTE(HL)) & 0xff]; break; case 0xb7: /* OR A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; AF = xororTable[(AF >> 8) & 0xff]; break; case 0xb8: /* CP B */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); AF = (AF & ~0x28) | (temp & 0x28); @@ -3162,7 +2990,7 @@ int32 sim_instr (void) { (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xb9: /* CP C */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); AF = (AF & ~0x28) | (temp & 0x28); @@ -3173,7 +3001,7 @@ int32 sim_instr (void) { (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xba: /* CP D */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); AF = (AF & ~0x28) | (temp & 0x28); @@ -3184,7 +3012,7 @@ int32 sim_instr (void) { (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbb: /* CP E */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); AF = (AF & ~0x28) | (temp & 0x28); @@ -3195,7 +3023,7 @@ int32 sim_instr (void) { (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbc: /* CP H */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); AF = (AF & ~0x28) | (temp & 0x28); @@ -3206,7 +3034,7 @@ int32 sim_instr (void) { (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbd: /* CP L */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); AF = (AF & ~0x28) | (temp & 0x28); @@ -3217,7 +3045,7 @@ int32 sim_instr (void) { (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbe: /* CP (HL) */ - updateTStates(7); + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); AF = (AF & ~0x28) | (temp & 0x28); @@ -3228,24 +3056,24 @@ int32 sim_instr (void) { (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbf: /* CP A */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; Setlreg(AF, (hreg(AF) & 0x28) | (cpu_unit.flags & UNIT_CHIP ? 0x42 : 0x46)); break; case 0xc0: /* RET NZ */ if (TSTFLAG(Z)) { sim_brk_pend = FALSE; - updateTStates(5); + tStates += 5; } else { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); - updateTStates(11); + tStates += 11; } break; case 0xc1: /* POP BC */ - updateTStates(10); + tStates += 10; CheckBreakWord(SP); POP(BC); break; @@ -3261,12 +3089,12 @@ int32 sim_instr (void) { CALLC(!TSTFLAG(Z)); /* also updates tStates */ break; case 0xc5: /* PUSH BC */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(BC); break; case 0xc6: /* ADD A,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); acu = hreg(AF); @@ -3275,7 +3103,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0xc7: /* RST 0 */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(PC); PCQ_ENTRY(PC - 1); @@ -3286,15 +3114,15 @@ int32 sim_instr (void) { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); - updateTStates(11); + tStates += 11; } else { sim_brk_pend = FALSE; - updateTStates(5); + tStates += 5; } break; case 0xc9: /* RET */ - updateTStates(10); + tStates += 10; CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); @@ -3311,50 +3139,50 @@ int32 sim_instr (void) { sim_brk_pend = tStateModifier = FALSE; ++PC; acu = hreg(BC); - updateTStates(8); + tStates += 8; break; case 1: sim_brk_pend = tStateModifier = FALSE; ++PC; acu = lreg(BC); - updateTStates(8); + tStates += 8; break; case 2: sim_brk_pend = tStateModifier = FALSE; ++PC; acu = hreg(DE); - updateTStates(8); + tStates += 8; break; case 3: sim_brk_pend = tStateModifier = FALSE; ++PC; acu = lreg(DE); - updateTStates(8); + tStates += 8; break; case 4: sim_brk_pend = tStateModifier = FALSE; ++PC; acu = hreg(HL); - updateTStates(8); + tStates += 8; break; case 5: sim_brk_pend = tStateModifier = FALSE; ++PC; acu = lreg(HL); - updateTStates(8); + tStates += 8; break; case 6: CheckBreakByte(adr); ++PC; acu = GetBYTE(adr); tStateModifier = TRUE; - updateTStates(15); + tStates += 15; break; case 7: sim_brk_pend = tStateModifier = FALSE; ++PC; acu = hreg(AF); - updateTStates(8); + tStates += 8; break; } switch (op & 0xc0) { @@ -3451,7 +3279,7 @@ int32 sim_instr (void) { CALLC(1); /* also updates tStates */ break; case 0xce: /* ADC A,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); acu = hreg(AF); @@ -3460,7 +3288,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0xcf: /* RST 8 */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(PC); PCQ_ENTRY(PC - 1); @@ -3469,17 +3297,17 @@ int32 sim_instr (void) { case 0xd0: /* RET NC */ if (TSTFLAG(C)) { sim_brk_pend = FALSE; - updateTStates(5); + tStates += 5; } else { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); - updateTStates(11); + tStates += 11; } break; case 0xd1: /* POP DE */ - updateTStates(10); + tStates += 10; CheckBreakWord(SP); POP(DE); break; @@ -3488,7 +3316,7 @@ int32 sim_instr (void) { JPC(!TSTFLAG(C)); /* also updates tStates */ break; case 0xd3: /* OUT (nn),A */ - updateTStates(11); + tStates += 11; sim_brk_pend = FALSE; out(RAM_pp(PC), hreg(AF)); break; @@ -3496,12 +3324,12 @@ int32 sim_instr (void) { CALLC(!TSTFLAG(C)); /* also updates tStates */ break; case 0xd5: /* PUSH DE */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(DE); break; case 0xd6: /* SUB nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); acu = hreg(AF); @@ -3510,7 +3338,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0xd7: /* RST 10H */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(PC); PCQ_ENTRY(PC - 1); @@ -3521,31 +3349,33 @@ int32 sim_instr (void) { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); - updateTStates(11); + tStates += 11; } else { sim_brk_pend = FALSE; - updateTStates(5); + tStates += 5; } break; case 0xd9: /* EXX */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; checkCPU8080; - regs[regs_sel].bc = BC; - regs[regs_sel].de = DE; - regs[regs_sel].hl = HL; - regs_sel = 1 - regs_sel; - BC = regs[regs_sel].bc; - DE = regs[regs_sel].de; - HL = regs[regs_sel].hl; + temp = BC; + BC = BC1_S; + BC1_S = temp; + temp = DE; + DE = DE1_S; + DE1_S = temp; + temp = HL; + HL = HL1_S; + HL1_S = temp; break; case 0xda: /* JP C,nnnn */ sim_brk_pend = FALSE; JPC(TSTFLAG(C)); /* also updates tStates */ break; case 0xdb: /* IN A,(nn) */ - updateTStates(11); + tStates += 11; sim_brk_pend = FALSE; Sethreg(AF, in(RAM_pp(PC))); break; @@ -3556,7 +3386,7 @@ int32 sim_instr (void) { checkCPU8080; switch (op = RAM_pp(PC)) { case 0x09: /* ADD IX,BC */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; IX &= ADDRMASK; BC &= ADDRMASK; @@ -3565,7 +3395,7 @@ int32 sim_instr (void) { IX = sum; break; case 0x19: /* ADD IX,DE */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; IX &= ADDRMASK; DE &= ADDRMASK; @@ -3574,42 +3404,42 @@ int32 sim_instr (void) { IX = sum; break; case 0x21: /* LD IX,nnnn */ - updateTStates(14); + tStates += 14; sim_brk_pend = FALSE; IX = GetWORD(PC); PC += 2; break; case 0x22: /* LD (nnnn),IX */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); PutWORD(temp, IX); PC += 2; break; case 0x23: /* INC IX */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; ++IX; break; case 0x24: /* INC IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; IX += 0x100; AF = (AF & ~0xfe) | incZ80Table[hreg(IX)]; break; case 0x25: /* DEC IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; IX -= 0x100; AF = (AF & ~0xfe) | decZ80Table[hreg(IX)]; break; case 0x26: /* LD IXH,nn */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IX, RAM_pp(PC)); break; case 0x29: /* ADD IX,IX */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; IX &= ADDRMASK; sum = IX + IX; @@ -3617,60 +3447,60 @@ int32 sim_instr (void) { IX = sum; break; case 0x2a: /* LD IX,(nnnn) */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); IX = GetWORD(temp); PC += 2; break; case 0x2b: /* DEC IX */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; --IX; break; case 0x2c: /* INC IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IX) + 1; Setlreg(IX, temp); AF = (AF & ~0xfe) | incZ80Table[temp]; break; case 0x2d: /* DEC IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IX) - 1; Setlreg(IX, temp); AF = (AF & ~0xfe) | decZ80Table[temp & 0xff]; break; case 0x2e: /* LD IXL,nn */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IX, RAM_pp(PC)); break; case 0x34: /* INC (IX+dd) */ - updateTStates(23); - adr = IX + (signed char) RAM_pp(PC); + tStates += 23; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr) + 1; PutBYTE(adr, temp); AF = (AF & ~0xfe) | incZ80Table[temp]; break; case 0x35: /* DEC (IX+dd) */ - updateTStates(23); - adr = IX + (signed char) RAM_pp(PC); + tStates += 23; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr) - 1; PutBYTE(adr, temp); AF = (AF & ~0xfe) | decZ80Table[temp & 0xff]; break; case 0x36: /* LD (IX+dd),nn */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, RAM_pp(PC)); break; case 0x39: /* ADD IX,SP */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; IX &= ADDRMASK; SP &= ADDRMASK; @@ -3679,209 +3509,209 @@ int32 sim_instr (void) { IX = sum; break; case 0x44: /* LD B,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(BC, hreg(IX)); break; case 0x45: /* LD B,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(BC, lreg(IX)); break; case 0x46: /* LD B,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); Sethreg(BC, GetBYTE(adr)); break; case 0x4c: /* LD C,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(BC, hreg(IX)); break; case 0x4d: /* LD C,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(BC, lreg(IX)); break; case 0x4e: /* LD C,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); Setlreg(BC, GetBYTE(adr)); break; case 0x54: /* LD D,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(DE, hreg(IX)); break; case 0x55: /* LD D,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(DE, lreg(IX)); break; case 0x56: /* LD D,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); Sethreg(DE, GetBYTE(adr)); break; case 0x5c: /* LD E,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(DE, hreg(IX)); break; case 0x5d: /* LD E,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(DE, lreg(IX)); break; case 0x5e: /* LD E,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); Setlreg(DE, GetBYTE(adr)); break; case 0x60: /* LD IXH,B */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IX, hreg(BC)); break; case 0x61: /* LD IXH,C */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IX, lreg(BC)); break; case 0x62: /* LD IXH,D */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IX, hreg(DE)); break; case 0x63: /* LD IXH,E */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IX, lreg(DE)); break; case 0x64: /* LD IXH,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; /* nop */ break; case 0x65: /* LD IXH,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IX, lreg(IX)); break; case 0x66: /* LD H,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); Sethreg(HL, GetBYTE(adr)); break; case 0x67: /* LD IXH,A */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IX, hreg(AF)); break; case 0x68: /* LD IXL,B */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IX, hreg(BC)); break; case 0x69: /* LD IXL,C */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IX, lreg(BC)); break; case 0x6a: /* LD IXL,D */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IX, hreg(DE)); break; case 0x6b: /* LD IXL,E */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IX, lreg(DE)); break; case 0x6c: /* LD IXL,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IX, hreg(IX)); break; case 0x6d: /* LD IXL,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; /* nop */ break; case 0x6e: /* LD L,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); Setlreg(HL, GetBYTE(adr)); break; case 0x6f: /* LD IXL,A */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IX, hreg(AF)); break; case 0x70: /* LD (IX+dd),B */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, hreg(BC)); break; case 0x71: /* LD (IX+dd),C */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, lreg(BC)); break; case 0x72: /* LD (IX+dd),D */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, hreg(DE)); break; case 0x73: /* LD (IX+dd),E */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, lreg(DE)); break; case 0x74: /* LD (IX+dd),H */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, hreg(HL)); break; case 0x75: /* LD (IX+dd),L */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, lreg(HL)); break; case 0x77: /* LD (IX+dd),A */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, hreg(AF)); break; case 0x7c: /* LD A,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(AF, hreg(IX)); break; case 0x7d: /* LD A,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(AF, lreg(IX)); break; case 0x7e: /* LD A,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); Sethreg(AF, GetBYTE(adr)); break; case 0x84: /* ADD A,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = hreg(IX); acu = hreg(AF); @@ -3889,7 +3719,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x85: /* ADD A,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IX); acu = hreg(AF); @@ -3897,8 +3727,8 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x86: /* ADD A,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); acu = hreg(AF); @@ -3906,7 +3736,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x8c: /* ADC A,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = hreg(IX); acu = hreg(AF); @@ -3914,7 +3744,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x8d: /* ADC A,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IX); acu = hreg(AF); @@ -3922,8 +3752,8 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x8e: /* ADC A,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); acu = hreg(AF); @@ -3931,8 +3761,8 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x96: /* SUB (IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); acu = hreg(AF); @@ -3942,7 +3772,7 @@ int32 sim_instr (void) { case 0x94: /* SUB IXH */ SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */ case 0x9c: /* SBC A,IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = hreg(IX); acu = hreg(AF); @@ -3952,7 +3782,7 @@ int32 sim_instr (void) { case 0x95: /* SUB IXL */ SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */ case 0x9d: /* SBC A,IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IX); acu = hreg(AF); @@ -3960,8 +3790,8 @@ int32 sim_instr (void) { AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0x9e: /* SBC A,(IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); acu = hreg(AF); @@ -3969,55 +3799,55 @@ int32 sim_instr (void) { AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0xa4: /* AND IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = andTable[((AF & IX) >> 8) & 0xff]; break; case 0xa5: /* AND IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = andTable[((AF >> 8) & IX) & 0xff]; break; case 0xa6: /* AND (IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); AF = andTable[((AF >> 8) & GetBYTE(adr)) & 0xff]; break; case 0xac: /* XOR IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = xororTable[((AF ^ IX) >> 8) & 0xff]; break; case 0xad: /* XOR IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) ^ IX) & 0xff]; break; case 0xae: /* XOR (IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); AF = xororTable[((AF >> 8) ^ GetBYTE(adr)) & 0xff]; break; case 0xb4: /* OR IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = xororTable[((AF | IX) >> 8) & 0xff]; break; case 0xb5: /* OR IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) | IX) & 0xff]; break; case 0xb6: /* OR (IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); AF = xororTable[((AF >> 8) | GetBYTE(adr)) & 0xff]; break; case 0xbc: /* CP IXH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = hreg(IX); AF = (AF & ~0x28) | (temp & 0x28); @@ -4027,7 +3857,7 @@ int32 sim_instr (void) { cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0xbd: /* CP IXL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IX); AF = (AF & ~0x28) | (temp & 0x28); @@ -4037,8 +3867,8 @@ int32 sim_instr (void) { cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0xbe: /* CP (IX+dd) */ - updateTStates(19); - adr = IX + (signed char) RAM_pp(PC); + tStates += 19; + adr = IX + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); AF = (AF & ~0x28) | (temp & 0x28); @@ -4048,7 +3878,7 @@ int32 sim_instr (void) { cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0xcb: /* CB prefix */ - adr = IX + (signed char) RAM_pp(PC); + adr = IX + (int8) RAM_pp(PC); switch ((op = GetBYTE(PC)) & 7) { case 0: sim_brk_pend = FALSE; @@ -4093,7 +3923,7 @@ int32 sim_instr (void) { } switch (op & 0xc0) { case 0x00: /* shift/rotate */ - updateTStates(23); + tStates += 23; switch (op & 0x38) { case 0x00: /* RLC */ temp = (acu << 1) | (acu >> 7); @@ -4131,7 +3961,7 @@ int32 sim_instr (void) { } break; case 0x40: /* BIT */ - updateTStates(20); + tStates += 20; if (acu & (1 << ((op >> 3) & 7))) { AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7); } @@ -4144,11 +3974,11 @@ int32 sim_instr (void) { temp = acu; break; case 0x80: /* RES */ - updateTStates(23); + tStates += 23; temp = acu & ~(1 << ((op >> 3) & 7)); break; case 0xc0: /* SET */ - updateTStates(23); + tStates += 23; temp = acu | (1 << ((op >> 3) & 7)); break; } @@ -4180,30 +4010,30 @@ int32 sim_instr (void) { } break; case 0xe1: /* POP IX */ - updateTStates(14); + tStates += 14; CheckBreakWord(SP); POP(IX); break; case 0xe3: /* EX (SP),IX */ - updateTStates(23); + tStates += 23; CheckBreakWord(SP); temp = IX; POP(IX); PUSH(temp); break; case 0xe5: /* PUSH IX */ - updateTStates(15); + tStates += 15; CheckBreakWord(SP - 2); PUSH(IX); break; case 0xe9: /* JP (IX) */ - updateTStates(8); + tStates += 8; sim_brk_pend = FALSE; PCQ_ENTRY(PC - 2); PC = IX; break; case 0xf9: /* LD SP,IX */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; SP = IX; break; @@ -4214,7 +4044,7 @@ int32 sim_instr (void) { } break; case 0xde: /* SBC A,nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); acu = hreg(AF); @@ -4223,7 +4053,7 @@ int32 sim_instr (void) { AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0xdf: /* RST 18H */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(PC); PCQ_ENTRY(PC - 1); @@ -4232,17 +4062,17 @@ int32 sim_instr (void) { case 0xe0: /* RET PO */ if (TSTFLAG(P)) { sim_brk_pend = FALSE; - updateTStates(5); + tStates += 5; } else { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); - updateTStates(11); + tStates += 11; } break; case 0xe1: /* POP HL */ - updateTStates(10); + tStates += 10; CheckBreakWord(SP); POP(HL); break; @@ -4251,7 +4081,7 @@ int32 sim_instr (void) { JPC(!TSTFLAG(P)); /* also updates tStates */ break; case 0xe3: /* EX (SP),HL */ - updateTStates(19); + tStates += 19; CheckBreakWord(SP); temp = HL; POP(HL); @@ -4261,17 +4091,17 @@ int32 sim_instr (void) { CALLC(!TSTFLAG(P)); /* also updates tStates */ break; case 0xe5: /* PUSH HL */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(HL); break; case 0xe6: /* AND nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; AF = andTable[((AF >> 8) & RAM_pp(PC)) & 0xff]; break; case 0xe7: /* RST 20H */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(PC); PCQ_ENTRY(PC - 1); @@ -4282,15 +4112,15 @@ int32 sim_instr (void) { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); - updateTStates(11); + tStates += 11; } else { sim_brk_pend = FALSE; - updateTStates(5); + tStates += 5; } break; case 0xe9: /* JP (HL) */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; PCQ_ENTRY(PC - 1); PC = HL; @@ -4300,7 +4130,7 @@ int32 sim_instr (void) { JPC(TSTFLAG(P)); /* also updates tStates */ break; case 0xeb: /* EX DE,HL */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; temp = HL; HL = DE; @@ -4313,19 +4143,19 @@ int32 sim_instr (void) { checkCPU8080; switch (op = RAM_pp(PC)) { case 0x40: /* IN B,(C) */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; temp = in(lreg(BC)); Sethreg(BC, temp); AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; break; case 0x41: /* OUT (C),B */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; out(lreg(BC), hreg(BC)); break; case 0x42: /* SBC HL,BC */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; HL &= ADDRMASK; BC &= ADDRMASK; @@ -4335,7 +4165,7 @@ int32 sim_instr (void) { HL = sum; break; case 0x43: /* LD (nnnn),BC */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); PutWORD(temp, BC); @@ -4349,7 +4179,7 @@ int32 sim_instr (void) { case 0x6C: /* NEG, unofficial */ case 0x74: /* NEG, unofficial */ case 0x7C: /* NEG, unofficial */ - updateTStates(8); + tStates += 8; sim_brk_pend = FALSE; temp = hreg(AF); AF = ((~(AF & 0xff00) + 1) & 0xff00); /* AF = (-(AF & 0xff00) & 0xff00); */ @@ -4362,36 +4192,36 @@ int32 sim_instr (void) { case 0x6D: /* RETN, unofficial */ case 0x75: /* RETN, unofficial */ case 0x7D: /* RETN, unofficial */ - updateTStates(14); - IFF |= IFF >> 1; + tStates += 14; + IFF_S |= IFF_S >> 1; CheckBreakWord(SP); PCQ_ENTRY(PC - 2); POP(PC); break; case 0x46: /* IM 0 */ - updateTStates(8); + tStates += 8; sim_brk_pend = FALSE; /* interrupt mode 0 */ break; case 0x47: /* LD I,A */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; - ir = (ir & 0xff) | (AF & ~0xff); + IR_S = (IR_S & 0xff) | (AF & ~0xff); break; case 0x48: /* IN C,(C) */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; temp = in(lreg(BC)); Setlreg(BC, temp); AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; break; case 0x49: /* OUT (C),C */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; out(lreg(BC), lreg(BC)); break; case 0x4a: /* ADC HL,BC */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; HL &= ADDRMASK; BC &= ADDRMASK; @@ -4401,38 +4231,38 @@ int32 sim_instr (void) { HL = sum; break; case 0x4b: /* LD BC,(nnnn) */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); BC = GetWORD(temp); PC += 2; break; case 0x4d: /* RETI */ - updateTStates(14); - IFF |= IFF >> 1; + tStates += 14; + IFF_S |= IFF_S >> 1; CheckBreakWord(SP); PCQ_ENTRY(PC - 2); POP(PC); break; case 0x4f: /* LD R,A */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; - ir = (ir & ~0xff) | ((AF >> 8) & 0xff); + IR_S = (IR_S & ~0xff) | ((AF >> 8) & 0xff); break; case 0x50: /* IN D,(C) */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; temp = in(lreg(BC)); Sethreg(DE, temp); AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; break; case 0x51: /* OUT (C),D */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; out(lreg(BC), hreg(DE)); break; case 0x52: /* SBC HL,DE */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; HL &= ADDRMASK; DE &= ADDRMASK; @@ -4442,36 +4272,36 @@ int32 sim_instr (void) { HL = sum; break; case 0x53: /* LD (nnnn),DE */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); PutWORD(temp, DE); PC += 2; break; case 0x56: /* IM 1 */ - updateTStates(8); + tStates += 8; sim_brk_pend = FALSE; /* interrupt mode 1 */ break; case 0x57: /* LD A,I */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; - AF = (AF & 0x29) | (ir & ~0xff) | ((ir >> 8) & 0x80) | (((ir & ~0xff) == 0) << 6) | ((IFF & 2) << 1); + AF = (AF & 0x29) | (IR_S & ~0xff) | ((IR_S >> 8) & 0x80) | (((IR_S & ~0xff) == 0) << 6) | ((IFF_S & 2) << 1); break; case 0x58: /* IN E,(C) */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; temp = in(lreg(BC)); Setlreg(DE, temp); AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; break; case 0x59: /* OUT (C),E */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; out(lreg(BC), lreg(DE)); break; case 0x5a: /* ADC HL,DE */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; HL &= ADDRMASK; DE &= ADDRMASK; @@ -4481,37 +4311,37 @@ int32 sim_instr (void) { HL = sum; break; case 0x5b: /* LD DE,(nnnn) */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); DE = GetWORD(temp); PC += 2; break; case 0x5e: /* IM 2 */ - updateTStates(8); + tStates += 8; sim_brk_pend = FALSE; /* interrupt mode 2 */ break; case 0x5f: /* LD A,R */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; - AF = (AF & 0x29) | ((ir & 0xff) << 8) | (ir & 0x80) | - (((ir & 0xff) == 0) << 6) | ((IFF & 2) << 1); + AF = (AF & 0x29) | ((IR_S & 0xff) << 8) | (IR_S & 0x80) | + (((IR_S & 0xff) == 0) << 6) | ((IFF_S & 2) << 1); break; case 0x60: /* IN H,(C) */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; temp = in(lreg(BC)); Sethreg(HL, temp); AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; break; case 0x61: /* OUT (C),H */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; out(lreg(BC), hreg(HL)); break; case 0x62: /* SBC HL,HL */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; HL &= ADDRMASK; sum = HL - HL - TSTFLAG(C); @@ -4520,14 +4350,14 @@ int32 sim_instr (void) { HL = sum; break; case 0x63: /* LD (nnnn),HL */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); PutWORD(temp, HL); PC += 2; break; case 0x67: /* RRD */ - updateTStates(18); + tStates += 18; sim_brk_pend = FALSE; temp = GetBYTE(HL); acu = hreg(AF); @@ -4535,19 +4365,19 @@ int32 sim_instr (void) { AF = rrdrldTable[(acu & 0xf0) | ldig(temp)] | (AF & 1); break; case 0x68: /* IN L,(C) */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; temp = in(lreg(BC)); Setlreg(HL, temp); AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; break; case 0x69: /* OUT (C),L */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; out(lreg(BC), lreg(HL)); break; case 0x6a: /* ADC HL,HL */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; HL &= ADDRMASK; sum = HL + HL + TSTFLAG(C); @@ -4556,14 +4386,14 @@ int32 sim_instr (void) { HL = sum; break; case 0x6b: /* LD HL,(nnnn) */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); HL = GetWORD(temp); PC += 2; break; case 0x6f: /* RLD */ - updateTStates(18); + tStates += 18; sim_brk_pend = FALSE; temp = GetBYTE(HL); acu = hreg(AF); @@ -4571,19 +4401,19 @@ int32 sim_instr (void) { AF = rrdrldTable[(acu & 0xf0) | hdig(temp)] | (AF & 1); break; case 0x70: /* IN (C) */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; temp = in(lreg(BC)); Setlreg(temp, temp); AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; break; case 0x71: /* OUT (C),0 */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; out(lreg(BC), 0); break; case 0x72: /* SBC HL,SP */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; HL &= ADDRMASK; SP &= ADDRMASK; @@ -4593,26 +4423,26 @@ int32 sim_instr (void) { HL = sum; break; case 0x73: /* LD (nnnn),SP */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); PutWORD(temp, SP); PC += 2; break; case 0x78: /* IN A,(C) */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; temp = in(lreg(BC)); Sethreg(AF, temp); AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; break; case 0x79: /* OUT (C),A */ - updateTStates(12); + tStates += 12; sim_brk_pend = FALSE; out(lreg(BC), hreg(AF)); break; case 0x7a: /* ADC HL,SP */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; HL &= ADDRMASK; SP &= ADDRMASK; @@ -4622,14 +4452,14 @@ int32 sim_instr (void) { HL = sum; break; case 0x7b: /* LD SP,(nnnn) */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); SP = GetWORD(temp); PC += 2; break; case 0xa0: /* LDI */ - updateTStates(16); + tStates += 16; CheckBreakTwoBytes(HL, DE); acu = RAM_pp(HL); PutBYTE_pp(DE, acu); @@ -4638,7 +4468,7 @@ int32 sim_instr (void) { (((--BC & ADDRMASK) != 0) << 2); break; case 0xa1: /* CPI */ - updateTStates(16); + tStates += 16; CheckBreakByte(HL); acu = hreg(AF); temp = RAM_pp(HL); @@ -4653,7 +4483,7 @@ int32 sim_instr (void) { } break; case 0xa2: /* INI */ - updateTStates(16); + tStates += 16; CheckBreakByte(HL); PutBYTE(HL, in(lreg(BC))); ++HL; @@ -4661,7 +4491,7 @@ int32 sim_instr (void) { SETFLAG(P, (--BC & ADDRMASK) != 0); break; case 0xa3: /* OUTI */ - updateTStates(16); + tStates += 16; CheckBreakByte(HL); out(lreg(BC), GetBYTE(HL)); ++HL; @@ -4670,7 +4500,7 @@ int32 sim_instr (void) { SETFLAG(Z, lreg(BC) == 0); break; case 0xa8: /* LDD */ - updateTStates(16); + tStates += 16; CheckBreakTwoBytes(HL, DE); acu = RAM_mm(HL); PutBYTE_mm(DE, acu); @@ -4679,7 +4509,7 @@ int32 sim_instr (void) { (((--BC & ADDRMASK) != 0) << 2); break; case 0xa9: /* CPD */ - updateTStates(16); + tStates += 16; CheckBreakByte(HL); acu = hreg(AF); temp = RAM_mm(HL); @@ -4694,7 +4524,7 @@ int32 sim_instr (void) { } break; case 0xaa: /* IND */ - updateTStates(16); + tStates += 16; CheckBreakByte(HL); PutBYTE(HL, in(lreg(BC))); --HL; @@ -4703,7 +4533,7 @@ int32 sim_instr (void) { SETFLAG(Z, lreg(BC) == 0); break; case 0xab: /* OUTD */ - updateTStates(16); + tStates += 16; CheckBreakByte(HL); out(lreg(BC), GetBYTE(HL)); --HL; @@ -4716,7 +4546,7 @@ int32 sim_instr (void) { acu = hreg(AF); BC &= ADDRMASK; do { - updateTStates(21); + tStates += 21; CheckBreakTwoBytes(HL, DE); acu = RAM_pp(HL); PutBYTE_pp(DE, acu); @@ -4729,7 +4559,7 @@ int32 sim_instr (void) { acu = hreg(AF); BC &= ADDRMASK; do { - updateTStates(21); + tStates += 21; CheckBreakByte(HL); temp = RAM_pp(HL); op = --BC != 0; @@ -4748,7 +4578,7 @@ int32 sim_instr (void) { tStates -= 5; temp = hreg(BC); do { - updateTStates(21); + tStates += 21; CheckBreakByte(HL); PutBYTE(HL, in(lreg(BC))); ++HL; @@ -4761,7 +4591,7 @@ int32 sim_instr (void) { tStates -= 5; temp = hreg(BC); do { - updateTStates(21); + tStates += 21; CheckBreakByte(HL); out(lreg(BC), GetBYTE(HL)); ++HL; @@ -4774,7 +4604,7 @@ int32 sim_instr (void) { tStates -= 5; BC &= ADDRMASK; do { - updateTStates(21); + tStates += 21; CheckBreakTwoBytes(HL, DE); acu = RAM_mm(HL); PutBYTE_mm(DE, acu); @@ -4787,7 +4617,7 @@ int32 sim_instr (void) { acu = hreg(AF); BC &= ADDRMASK; do { - updateTStates(21); + tStates += 21; CheckBreakByte(HL); temp = RAM_mm(HL); op = --BC != 0; @@ -4806,7 +4636,7 @@ int32 sim_instr (void) { tStates -= 5; temp = hreg(BC); do { - updateTStates(21); + tStates += 21; CheckBreakByte(HL); PutBYTE(HL, in(lreg(BC))); --HL; @@ -4819,7 +4649,7 @@ int32 sim_instr (void) { tStates -= 5; temp = hreg(BC); do { - updateTStates(21); + tStates += 21; CheckBreakByte(HL); out(lreg(BC), GetBYTE(HL)); --HL; @@ -4834,12 +4664,12 @@ int32 sim_instr (void) { } break; case 0xee: /* XOR nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) ^ RAM_pp(PC)) & 0xff]; break; case 0xef: /* RST 28H */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(PC); PCQ_ENTRY(PC - 1); @@ -4848,17 +4678,17 @@ int32 sim_instr (void) { case 0xf0: /* RET P */ if (TSTFLAG(S)) { sim_brk_pend = FALSE; - updateTStates(5); + tStates += 5; } else { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); - updateTStates(11); + tStates += 11; } break; case 0xf1: /* POP AF */ - updateTStates(10); + tStates += 10; CheckBreakWord(SP); POP(AF); break; @@ -4867,25 +4697,25 @@ int32 sim_instr (void) { JPC(!TSTFLAG(S)); /* also updates tStates */ break; case 0xf3: /* DI */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; - IFF = 0; + IFF_S = 0; break; case 0xf4: /* CALL P,nnnn */ CALLC(!TSTFLAG(S)); /* also updates tStates */ break; case 0xf5: /* PUSH AF */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(AF); break; case 0xf6: /* OR nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) | RAM_pp(PC)) & 0xff]; break; case 0xf7: /* RST 30H */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(PC); PCQ_ENTRY(PC - 1); @@ -4896,15 +4726,15 @@ int32 sim_instr (void) { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); - updateTStates(11); + tStates += 11; } else { sim_brk_pend = FALSE; - updateTStates(5); + tStates += 5; } break; case 0xf9: /* LD SP,HL */ - updateTStates(6); + tStates += 6; sim_brk_pend = FALSE; SP = HL; break; @@ -4913,9 +4743,9 @@ int32 sim_instr (void) { JPC(TSTFLAG(S)); /* also updates tStates */ break; case 0xfb: /* EI */ - updateTStates(4); + tStates += 4; sim_brk_pend = FALSE; - IFF = 3; + IFF_S = 3; break; case 0xfc: /* CALL M,nnnn */ CALLC(TSTFLAG(S)); /* also updates tStates */ @@ -4924,7 +4754,7 @@ int32 sim_instr (void) { checkCPU8080; switch (op = RAM_pp(PC)) { case 0x09: /* ADD IY,BC */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; IY &= ADDRMASK; BC &= ADDRMASK; @@ -4933,7 +4763,7 @@ int32 sim_instr (void) { IY = sum; break; case 0x19: /* ADD IY,DE */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; IY &= ADDRMASK; DE &= ADDRMASK; @@ -4942,42 +4772,42 @@ int32 sim_instr (void) { IY = sum; break; case 0x21: /* LD IY,nnnn */ - updateTStates(14); + tStates += 14; sim_brk_pend = FALSE; IY = GetWORD(PC); PC += 2; break; case 0x22: /* LD (nnnn),IY */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); PutWORD(temp, IY); PC += 2; break; case 0x23: /* INC IY */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; ++IY; break; case 0x24: /* INC IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; IY += 0x100; AF = (AF & ~0xfe) | incZ80Table[hreg(IY)]; break; case 0x25: /* DEC IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; IY -= 0x100; AF = (AF & ~0xfe) | decZ80Table[hreg(IY)]; break; case 0x26: /* LD IYH,nn */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IY, RAM_pp(PC)); break; case 0x29: /* ADD IY,IY */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; IY &= ADDRMASK; sum = IY + IY; @@ -4985,60 +4815,60 @@ int32 sim_instr (void) { IY = sum; break; case 0x2a: /* LD IY,(nnnn) */ - updateTStates(20); + tStates += 20; temp = GetWORD(PC); CheckBreakWord(temp); IY = GetWORD(temp); PC += 2; break; case 0x2b: /* DEC IY */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; --IY; break; case 0x2c: /* INC IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IY) + 1; Setlreg(IY, temp); AF = (AF & ~0xfe) | incZ80Table[temp]; break; case 0x2d: /* DEC IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IY) - 1; Setlreg(IY, temp); AF = (AF & ~0xfe) | decZ80Table[temp & 0xff]; break; case 0x2e: /* LD IYL,nn */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IY, RAM_pp(PC)); break; case 0x34: /* INC (IY+dd) */ - updateTStates(23); - adr = IY + (signed char) RAM_pp(PC); + tStates += 23; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr) + 1; PutBYTE(adr, temp); AF = (AF & ~0xfe) | incZ80Table[temp]; break; case 0x35: /* DEC (IY+dd) */ - updateTStates(23); - adr = IY + (signed char) RAM_pp(PC); + tStates += 23; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr) - 1; PutBYTE(adr, temp); AF = (AF & ~0xfe) | decZ80Table[temp & 0xff]; break; case 0x36: /* LD (IY+dd),nn */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, RAM_pp(PC)); break; case 0x39: /* ADD IY,SP */ - updateTStates(15); + tStates += 15; sim_brk_pend = FALSE; IY &= ADDRMASK; SP &= ADDRMASK; @@ -5047,209 +4877,209 @@ int32 sim_instr (void) { IY = sum; break; case 0x44: /* LD B,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(BC, hreg(IY)); break; case 0x45: /* LD B,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(BC, lreg(IY)); break; case 0x46: /* LD B,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); Sethreg(BC, GetBYTE(adr)); break; case 0x4c: /* LD C,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(BC, hreg(IY)); break; case 0x4d: /* LD C,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(BC, lreg(IY)); break; case 0x4e: /* LD C,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); Setlreg(BC, GetBYTE(adr)); break; case 0x54: /* LD D,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(DE, hreg(IY)); break; case 0x55: /* LD D,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(DE, lreg(IY)); break; case 0x56: /* LD D,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); Sethreg(DE, GetBYTE(adr)); break; case 0x5c: /* LD E,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(DE, hreg(IY)); break; case 0x5d: /* LD E,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(DE, lreg(IY)); break; case 0x5e: /* LD E,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); Setlreg(DE, GetBYTE(adr)); break; case 0x60: /* LD IYH,B */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IY, hreg(BC)); break; case 0x61: /* LD IYH,C */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IY, lreg(BC)); break; case 0x62: /* LD IYH,D */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IY, hreg(DE)); break; case 0x63: /* LD IYH,E */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IY, lreg(DE)); break; case 0x64: /* LD IYH,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; /* nop */ break; case 0x65: /* LD IYH,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IY, lreg(IY)); break; case 0x66: /* LD H,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); Sethreg(HL, GetBYTE(adr)); break; case 0x67: /* LD IYH,A */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(IY, hreg(AF)); break; case 0x68: /* LD IYL,B */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IY, hreg(BC)); break; case 0x69: /* LD IYL,C */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IY, lreg(BC)); break; case 0x6a: /* LD IYL,D */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IY, hreg(DE)); break; case 0x6b: /* LD IYL,E */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IY, lreg(DE)); break; case 0x6c: /* LD IYL,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IY, hreg(IY)); break; case 0x6d: /* LD IYL,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; /* nop */ break; case 0x6e: /* LD L,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); Setlreg(HL, GetBYTE(adr)); break; case 0x6f: /* LD IYL,A */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Setlreg(IY, hreg(AF)); break; case 0x70: /* LD (IY+dd),B */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, hreg(BC)); break; case 0x71: /* LD (IY+dd),C */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, lreg(BC)); break; case 0x72: /* LD (IY+dd),D */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, hreg(DE)); break; case 0x73: /* LD (IY+dd),E */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, lreg(DE)); break; case 0x74: /* LD (IY+dd),H */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, hreg(HL)); break; case 0x75: /* LD (IY+dd),L */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, lreg(HL)); break; case 0x77: /* LD (IY+dd),A */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); PutBYTE(adr, hreg(AF)); break; case 0x7c: /* LD A,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(AF, hreg(IY)); break; case 0x7d: /* LD A,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; Sethreg(AF, lreg(IY)); break; case 0x7e: /* LD A,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); Sethreg(AF, GetBYTE(adr)); break; case 0x84: /* ADD A,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = hreg(IY); acu = hreg(AF); @@ -5257,7 +5087,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x85: /* ADD A,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IY); acu = hreg(AF); @@ -5265,8 +5095,8 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x86: /* ADD A,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); acu = hreg(AF); @@ -5274,7 +5104,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x8c: /* ADC A,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = hreg(IY); acu = hreg(AF); @@ -5282,7 +5112,7 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x8d: /* ADC A,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IY); acu = hreg(AF); @@ -5290,8 +5120,8 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x8e: /* ADC A,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); acu = hreg(AF); @@ -5299,8 +5129,8 @@ int32 sim_instr (void) { AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; break; case 0x96: /* SUB (IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); acu = hreg(AF); @@ -5310,7 +5140,7 @@ int32 sim_instr (void) { case 0x94: /* SUB IYH */ SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */ case 0x9c: /* SBC A,IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = hreg(IY); acu = hreg(AF); @@ -5320,7 +5150,7 @@ int32 sim_instr (void) { case 0x95: /* SUB IYL */ SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */ case 0x9d: /* SBC A,IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IY); acu = hreg(AF); @@ -5328,8 +5158,8 @@ int32 sim_instr (void) { AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0x9e: /* SBC A,(IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); acu = hreg(AF); @@ -5337,55 +5167,55 @@ int32 sim_instr (void) { AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0xa4: /* AND IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = andTable[((AF & IY) >> 8) & 0xff]; break; case 0xa5: /* AND IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = andTable[((AF >> 8) & IY) & 0xff]; break; case 0xa6: /* AND (IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); AF = andTable[((AF >> 8) & GetBYTE(adr)) & 0xff]; break; case 0xac: /* XOR IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = xororTable[((AF ^ IY) >> 8) & 0xff]; break; case 0xad: /* XOR IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) ^ IY) & 0xff]; break; case 0xae: /* XOR (IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); AF = xororTable[((AF >> 8) ^ GetBYTE(adr)) & 0xff]; break; case 0xb4: /* OR IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = xororTable[((AF | IY) >> 8) & 0xff]; break; case 0xb5: /* OR IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; AF = xororTable[((AF >> 8) | IY) & 0xff]; break; case 0xb6: /* OR (IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); AF = xororTable[((AF >> 8) | GetBYTE(adr)) & 0xff]; break; case 0xbc: /* CP IYH */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = hreg(IY); AF = (AF & ~0x28) | (temp & 0x28); @@ -5395,7 +5225,7 @@ int32 sim_instr (void) { cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0xbd: /* CP IYL */ - updateTStates(9); + tStates += 9; sim_brk_pend = FALSE; temp = lreg(IY); AF = (AF & ~0x28) | (temp & 0x28); @@ -5405,8 +5235,8 @@ int32 sim_instr (void) { cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0xbe: /* CP (IY+dd) */ - updateTStates(19); - adr = IY + (signed char) RAM_pp(PC); + tStates += 19; + adr = IY + (int8) RAM_pp(PC); CheckBreakByte(adr); temp = GetBYTE(adr); AF = (AF & ~0x28) | (temp & 0x28); @@ -5416,7 +5246,7 @@ int32 sim_instr (void) { cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; break; case 0xcb: /* CB prefix */ - adr = IY + (signed char) RAM_pp(PC); + adr = IY + (int8) RAM_pp(PC); switch ((op = GetBYTE(PC)) & 7) { case 0: sim_brk_pend = FALSE; @@ -5461,7 +5291,7 @@ int32 sim_instr (void) { } switch (op & 0xc0) { case 0x00: /* shift/rotate */ - updateTStates(23); + tStates += 23; switch (op & 0x38) { case 0x00: /* RLC */ temp = (acu << 1) | (acu >> 7); @@ -5499,7 +5329,7 @@ int32 sim_instr (void) { } break; case 0x40: /* BIT */ - updateTStates(20); + tStates += 20; if (acu & (1 << ((op >> 3) & 7))) { AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7); } @@ -5512,11 +5342,11 @@ int32 sim_instr (void) { temp = acu; break; case 0x80: /* RES */ - updateTStates(23); + tStates += 23; temp = acu & ~(1 << ((op >> 3) & 7)); break; case 0xc0: /* SET */ - updateTStates(23); + tStates += 23; temp = acu | (1 << ((op >> 3) & 7)); break; } @@ -5548,30 +5378,30 @@ int32 sim_instr (void) { } break; case 0xe1: /* POP IY */ - updateTStates(14); + tStates += 14; CheckBreakWord(SP); POP(IY); break; case 0xe3: /* EX (SP),IY */ - updateTStates(23); + tStates += 23; CheckBreakWord(SP); temp = IY; POP(IY); PUSH(temp); break; case 0xe5: /* PUSH IY */ - updateTStates(15); + tStates += 15; CheckBreakWord(SP - 2); PUSH(IY); break; case 0xe9: /* JP (IY) */ - updateTStates(8); + tStates += 8; sim_brk_pend = FALSE; PCQ_ENTRY(PC - 2); PC = IY; break; case 0xf9: /* LD SP,IY */ - updateTStates(10); + tStates += 10; sim_brk_pend = FALSE; SP = IY; break; @@ -5582,7 +5412,7 @@ int32 sim_instr (void) { } break; case 0xfe: /* CP nn */ - updateTStates(7); + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); AF = (AF & ~0x28) | (temp & 0x28); @@ -5593,7 +5423,7 @@ int32 sim_instr (void) { (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xff: /* RST 38H */ - updateTStates(11); + tStates += 11; CheckBreakWord(SP - 2); PUSH(PC); PCQ_ENTRY(PC - 1); @@ -5601,31 +5431,17 @@ int32 sim_instr (void) { } } end_decode: - pc = PC; - af[af_sel] = AF; - regs[regs_sel].bc = BC; - regs[regs_sel].de = DE; - regs[regs_sel].hl = HL; - ix = IX; - iy = IY; - sp = SP; /* simulation halted */ - saved_PC = ((reason == STOP_OPCODE) || (reason == STOP_MEM)) ? PCX : pc; + saved_PC = ((reason == STOP_OPCODE) || (reason == STOP_MEM)) ? PCX : PC; pcq_r -> qptr = pcq_p; /* update pc q ptr */ - AF_S = af[af_sel]; - BC_S = regs[regs_sel].bc; - DE_S = regs[regs_sel].de; - HL_S = regs[regs_sel].hl; - IX_S = ix; - IY_S = iy; - SP_S = sp; - AF1_S = af[1 - af_sel]; - BC1_S = regs[1 - regs_sel].bc; - DE1_S = regs[1 - regs_sel].de; - HL1_S = regs[1 - regs_sel].hl; - IFF_S = IFF; - IR_S = ir; + AF_S = AF; + BC_S = BC; + DE_S = DE; + HL_S = HL; + IX_S = IX; + IY_S = IY; + SP_S = SP; executedTStates = tStates; return reason; } @@ -5671,9 +5487,7 @@ t_stat cpu_reset(DEVICE *dptr) { extern int32 sim_brk_types, sim_brk_dflt; /* breakpoint info */ int32 i; AF_S = AF1_S = 0; - af_sel = 0; BC_S = DE_S = HL_S = 0; - regs_sel = 0; BC1_S = DE1_S = HL1_S = 0; IR_S = IX_S = IY_S = SP_S = 0; IFF_S = 3; @@ -5794,7 +5608,7 @@ static t_stat cpu_set_size(UNIT *uptr, int32 value, char *cptr, void *desc) { ALTAIRROM/NOALTAIRROM settings are ignored. */ -int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag) { +t_stat sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag) { int32 i, addr = 0, cnt = 0, org, cntROM = 0, cntNonExist = 0; t_addr j, lo, hi; char *result; diff --git a/AltairZ80/altairZ80_defs.h b/AltairZ80/altairZ80_defs.h index 7eecd9b3..9e2574ed 100644 --- a/AltairZ80/altairZ80_defs.h +++ b/AltairZ80/altairZ80_defs.h @@ -1,6 +1,6 @@ /* altairz80_defs.h: MITS Altair simulator definitions - Copyright (c) 2002-2004, Peter Schorn + Copyright (c) 2002-2005, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -36,15 +36,15 @@ #define BANKMASK (MAXBANKS-1) /* bank mask */ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ #define KB 1024 /* kilo byte */ -#define defaultROMLow 0xff00 /* default for lowest addres of ROM */ -#define defaultROMHigh 0xffff /* default for highest addres of ROM */ +#define defaultROMLow 0xff00 /* default for lowest address of ROM */ +#define defaultROMHigh 0xffff /* default for highest address of ROM */ #define NUM_OF_DSK 8 /* NUM_OF_DSK must be power of two */ #define LDAInstruction 0x3e /* op-code for LD A,<8-bit value> instruction */ #define unitNoOffset1 0x37 /* LD A, */ #define unitNoOffset2 0xb4 /* LD a,80h | */ -#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* stop on nvalid operation */ +#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* stop on invalid operation */ #define UNIT_OPSTOP (1 << UNIT_V_OPSTOP) #define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 CPU */ #define UNIT_CHIP (1 << UNIT_V_CHIP) diff --git a/AltairZ80/altairZ80_dsk.c b/AltairZ80/altairZ80_dsk.c index fe450daa..20dba70c 100644 --- a/AltairZ80/altairZ80_dsk.c +++ b/AltairZ80/altairZ80_dsk.c @@ -1,6 +1,6 @@ /* altairz80_dsk.c: MITS Altair 88-DISK Simulator - Copyright (c) 2002-2004, Peter Schorn + Copyright (c) 2002-2005, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -30,7 +30,7 @@ Each diskette has physically 77 tracks of 32 137-byte sectors each. - The controller is interfaced to the CPU by use of 3 I/O addreses, + The controller is interfaced to the CPU by use of 3 I/O addresses, standardly, these are device numbers 10, 11, and 12 (octal). Address Mode Function diff --git a/AltairZ80/altairZ80_sio.c b/AltairZ80/altairZ80_sio.c index ed85ba79..34ac09e9 100644 --- a/AltairZ80/altairZ80_sio.c +++ b/AltairZ80/altairZ80_sio.c @@ -1,6 +1,6 @@ /* altairz80_sio: MITS Altair serial I/O card - Copyright (c) 2002-2004, Peter Schorn + Copyright (c) 2002-2005, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -58,7 +58,7 @@ #define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode, strip bit 8 on output */ #define UNIT_ANSI (1 << UNIT_V_ANSI) -#define UNIT_V_UPPER (UNIT_V_UF + 1) /* uppper case mode */ +#define UNIT_V_UPPER (UNIT_V_UF + 1) /* upper case mode */ #define UNIT_UPPER (1 << UNIT_V_UPPER) #define UNIT_V_BS (UNIT_V_UF + 2) /* map delete to backspace */ #define UNIT_BS (1 << UNIT_V_BS) @@ -170,7 +170,7 @@ static int32 warnUnattachedPTR = 0; /* display a warning message if < warnLe static int32 warnPTREOF = 0; /* display a warning message if < warnLevel and SIO set to VERBOSE and attempt to read from PTR past EOF */ static int32 warnUnassignedPort = 0; /* display a warning message if < warnLevel and SIO set to - VERBOSE andattempt to perform IN or OUT on an unassigned PORT */ + VERBOSE and attempt to perform IN or OUT on an unassigned PORT */ struct sio_terminal { int32 data; /* data for this terminal */ int32 status; /* status information for this terminal */ @@ -743,10 +743,10 @@ static t_stat simh_svc(UNIT *uptr) { return SCPE_OK; } -/* The CP/M commandline is used as the name of a file and UNIT* uptr is attached to it. */ +/* The CP/M command line is used as the name of a file and UNIT* uptr is attached to it. */ static void attachCPM(UNIT *uptr) { char cpmCommandLine[cpmCommandLineLength]; - uint32 i, len = (GetBYTEWrapper(0x80) & 0x7f) - 1; /* 0x80 contains length of commandline, discard first char */ + uint32 i, len = (GetBYTEWrapper(0x80) & 0x7f) - 1; /* 0x80 contains length of command line, discard first char */ for (i = 0; i < len; i++) { cpmCommandLine[i] = (char)GetBYTEWrapper(0x82 + i); /* the first char, typically ' ', is discarded */ } diff --git a/AltairZ80/altairZ80_sys.c b/AltairZ80/altairZ80_sys.c index 0fc65a78..26bcb9d2 100644 --- a/AltairZ80/altairZ80_sys.c +++ b/AltairZ80/altairZ80_sys.c @@ -1,6 +1,6 @@ /* altairz80_sys.c: MITS Altair system interface - Copyright (c) 2002-2004, Peter Schorn + Copyright (c) 2002-2005, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -425,7 +425,7 @@ int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw) { return 1 - ch; /* need to return additional bytes */ } -/* numString checks determines the base of the number (ch, *numString) +/* checkbase determines the base of the number (ch, *numString) and returns FALSE if the number is bad */ static int32 checkbase(char ch, const char *numString) { int32 decimal = (ch <= '9'); @@ -475,7 +475,7 @@ static int32 match(const char *pattern, const char *input, char *xyFirst, char * char inp = *input++; while ((pat) && (inp)) { switch(pat) { - case '_': /* patterns containting '_' should never match */ + case '_': /* patterns containing '_' should never match */ return FALSE; case ',': if (inp == ' ') { diff --git a/AltairZ80/altairz80_doc.txt b/AltairZ80/altairz80_doc.txt index 22530825..aa6321ef 100644 --- a/AltairZ80/altairz80_doc.txt +++ b/AltairZ80/altairz80_doc.txt @@ -1,13 +1,13 @@ To: Users From: Peter Schorn Subj: AltairZ80 Simulator Usage -Date: 12-Apr-2004 +Date: 05-Apr-2005 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Copyright (c) 2002-2004, Peter Schorn + Copyright (c) 2002-2005, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -61,7 +61,10 @@ sim/AltairZ80/altairz80_defs.h 2. Revision History -- 12-Apr-2004, Peter Schorn (added MAP/NOMAP capability to switch off key mapping) +- 05-Apr-2005, removed bogus t-state stepping support +- 24-Jul-2004, Peter Schorn (updated CP/M 2 and SPL packages) +- 12-Apr-2004, Peter Schorn (added MAP/NOMAP capability to switch off + key mapping) - 26-Jan-2004, Peter Schorn (added support for t-state stepping) - 25-Feb-2003, Peter Schorn (added support for real time simulation) - 9-Oct-2002, Peter Schorn (added support for simulated hard disk) @@ -169,7 +172,7 @@ the MITS Disk Basic and Altair DOS require about a minimum of 24K. a warning message if the CPU attempts to read from non-existing memory. - SET CPU NOWARNROM Suppreses all warning message of "WARNROM". Note that + SET CPU NOWARNROM Suppresses all warning message of "WARNROM". Note that some software tries on purpose to write to ROM in order to detect the available RAM. @@ -181,7 +184,7 @@ crashes. This is historically accurate behavior. The real 8080, on receiving a HLT (Halt) instruction, freezes the processor and only an interrupt or CPU hardware reset will restore it. The -simulator is alot nicer, it will halt but send you back to the simulator +simulator is a lot nicer, it will halt but send you back to the simulator command line. CPU Registers include the following: @@ -193,7 +196,7 @@ CPU Registers include the following: F = S Z - AC - P/V N C S = Sign flag. Z = Zero Flag. - AC = Auxillary Carry flag. + AC = Auxiliary Carry flag. P/V = Parity flag on 8080 Parity / Overflow flag on Z80 - = not used (undefined) @@ -307,10 +310,10 @@ for debugging purposes. The MITS 88-DISK is a simple programmed I/O interface to the MITS 8-inch floppy drive, which was basically a Pertec FD-400 with a power supply and -buffer board builtin. The controller supports neither interrupts nor DMA, +buffer board built-in. The controller supports neither interrupts nor DMA, so floppy access required the sustained attention of the CPU. The standard I/O addresses were 8, 9, and 0A (hex), and we follow the standard. Details -on controlling this hardware are in the altair_dsk.c source file. +on controlling this hardware are in the altairz80_dsk.c source file. The only difference is that the simulated disks may be larger than the original ones: The original disk had 77 tracks while the simulated disks @@ -438,10 +441,10 @@ DUMP .COM 2K ; hex dump a file ED .COM 8K ; line editor ELIZA .BAS 10K ; Eliza game in Basic EX8080 .COM 12K ; exercise 8080 instruction set -EXZ80N .COM 12K ; exercise Z80 instruction set, No undefined status bits -EXZ80U .COM 12K ; exercise Z80 instruction set, Undefined status bits -EXZ80 .MAC 54K ; source for EX8080.COM, EXZ80N.COM, EXZ80U.COM -EX .SUB 2K ; benchmark execution of EX8080.COM, EXZ80N.COM, EXZ80U.COM +EXZ80DOC.COM 12K ; exercise Z80 instruction set, No undefined status bits +EXZ80ALL.COM 12K ; exercise Z80 instruction set, Undefined status bits +EX .MAC 54K ; source for EX8080.COM, EXZ80DOC.COM, EXZ80ALL.COM +EX .SUB 2K ; benchmark execution of EX8080.COM,EXZ80DOC.COM,EXZ80ALL.COM FORMAT .COM 2K ; format disks GO .COM 0K ; start the currently loaded program at 100H HDSKBOOT.MAC 6K ; boot code for hard disk @@ -484,7 +487,7 @@ W .COM 4K ; write files to SIMH environment WM .COM 12K ; word master screen editor WM .HLP 3K ; help file for WM.COM WORM .COM 4K ; worm game for VT100 terminal -XFORMAT .COM 2K ; initialise a drive (floppy or hard disk) +XFORMAT .COM 2K ; initialize a drive (floppy or hard disk) XSUB .COM 2K ; support for DO.COM ZAP .COM 10K ; SuperZap 5.2 disk editor configured for VT100 ZSID .COM 10K ; debugger for Z80 @@ -493,7 +496,7 @@ ZTRAN4 .COM 4K ; translate 8080 mnemonics into Z80 equivalents 5.2 CP/M Version 3 with banked memory - CP/M 3 is the successor to CP/M 2.2. A customised BIOS (BIOS3.MAC) is + CP/M 3 is the successor to CP/M 2.2. A customized BIOS (BIOS3.MAC) is included to facilitate modification if so desired. The defaults supplied in GENCPM.DAT for system generation can be used. BOOTGEN.COM is used to place the CP/M loader (LDR.COM) on the boot tracks of a disk. @@ -545,13 +548,13 @@ HEXCOM .CPM 2K HIST .UTL 2K INITDIR .COM 32K L80 .COM 12K ; Microsoft linker -LDR .COM 4K ; CP/M loader with optimised loader BIOS -LDRBIOS3.MAC 14K ; optimised (for space) loader BIOS +LDR .COM 4K ; CP/M loader with optimized loader BIOS +LDRBIOS3.MAC 14K ; optimized (for space) loader BIOS LIB .COM 8K ; Digital Research librarian LINK .COM 16K ; Digital Research linker LOAD .COM 2K M80 .COM 20K ; Microsoft macro assembler -MC .SUB 2K ; assemble and link an assmbler program +MC .SUB 2K ; assemble and link an assembler program MCC .SUB 2K ; read, assemble and link an assembler program PATCH .COM 4K PIP .COM 10K ; Peripheral Interchange Program @@ -626,7 +629,7 @@ DUMP .MAC 6K ; source for DUMP.PRL DUMP .PRL 2K ; dump command ED .PRL 10K ; MP/M line editor ERA .PRL 2K ; erase command -ERAQ .PRL 4K ; erase comand (verbose) +ERAQ .PRL 4K ; erase command (verbose) GENHEX .COM 2K GENMOD .COM 2K GENSYS .COM 10K @@ -636,7 +639,7 @@ LIB .COM 8K ; library utility LINK .COM 16K ; linker LOAD .COM 2K ; loader M80 .COM 20K ; Microsoft macro assembler -MC .SUB 2K ; assemble and link an assmbler program +MC .SUB 2K ; assemble and link an assembler program MCC .SUB 2K ; read, assemble and link an assembler program MPM .COM 8K ; start MP/M II MPM .SYS 26K ; MP/M system file @@ -703,21 +706,22 @@ before booting CP/M. The disk "app.dsk" contains the following files: Name Ext Size Comment +ACKER .SPL 4K ; compute the Ackermann function +ACKER .COM 2K ; compute the Ackermann function, SPL source BOOTGEN .COM 2K BOOTGEN .SPL 6K ; SPL source for BOOTGEN.COM C .SUB 2K ; batch file for compiling an SPL source file CALC .PRO 4K ; Prolog demo program: Calculator -CC .SUB 2K ; compile an SPL source which is on the underlying - file system -DECLARAT. 12K ; common include file, SPL source DIF .COM 4K DIF .SPL 10K ; SPL source for DIF.COM -EDIT .SPL 10K ; screen editor for PROLOGZ, SPL source +FAC .COM 4K ; compute the factorial +FAC .SPL 4K ; compute the factorial, SPL source FAMILY .PRO 4K ; Prolog demo program: Family relations +FORMEL .COM 4K ; calculator +FORMEL .SPL 6K ; calculator, SPL source INTEGER .PRO 2K ; Prolog demo program: Integer arithmetic KNAKE .PRO 2K ; Prolog demo program: Logic puzzle LINKMT .COM 12K ; Pascal MT+ 5.5 linker -MAIN .SPL 14K ; main module for PROLOGZ, SPL source MOVE .MAC 4K ; helper functions for PROLOGZ in assembler MTERRS .TXT 6K ; Pascal MT+ error messages MTPLUS .000 14K ; Pascal MT+ 5.5 compiler file @@ -733,34 +737,31 @@ PASCFORM.PAS 54K ; Pascal formatter source code PASCFORM.SUB 2K ; create Pascal formatter PASLIB .ERL 24K ; Pascal MT+ 5.5 run time library PINST .COM 4K ; terminal installation program for PROLOGZ -PINST .SPL 16K ; terminal installation program for PROLOGZ, - SPL source +PINST .SPL 16K ; terminal installation program for PROLOGZ, SPL source +PRIM .COM 2K ; compute prime numbers +PRIM .SPL 2K ; compute prime numbers, SPL source PROLOGZ .COM 18K ; PROLOGZ interpreter and screen editor -PROLOGZ .SPL 2K ; PROLOGZ main program, SPL source +PROLOGZ .SPL 2K ; SPL source for PROLOGZ PROLOGZ .TXT 40K ; PROLOGZ documentation in German -PROVE .SPL 16K ; backtrack theorem prover for PROLOGZ, SPL source -PZCLEAN .SUB 2K ; PROLOGZ: remove all created ".rel" and ".lst" files -PZLINK .SUB 2K ; PROLOGZ: create PINST, PROLOGZ and personalise the - serial number -PZMAKE .SUB 2K ; PROLOGZ: compiles the sources (you can ignore - any compiler errors) QUEEN .PRO 2K ; Prolog demo program: N-queens problem READ .COM 4K READ .SPL 10K ; SPL source for R.COM -SHOWSEC .COM 4K +RELDUMP .COM 4K ; dump a .REL file to the console +RELDUMP .SPL 10K ; dump a .REL file to the console, SPL source +SHOWSEC .COM 2K SHOWSEC .SPL 6K ; SPL source for SHOWSEC.COM +SIEVE .COM 2K ; compute prime numbers with a sieve +SIEVE .SPL 6K ; compute prime numbers with a sieve, SPL source SPEED .COM 2K ; utility to measure the clock speed of the simulated CPU -SPEED .SPL 2K ; SPL source for SPEED.COM, requires SWLIB.MAC -SPL .COM 38K ; the SPL compiler itself -SPL .TXT 56K ; SPL language and compiler documentation in German -SPLERROR.DAT 12K ; error messages of the compiler (in German) -SPLIB .REL 6K ; SPL runtime library -STDIO . 2K ; include file for SPL programs -SWLIB .MAC 2K ; assembler utility routines needed by SPEED.SPL +SPEED .SPL 4K ; SPL source for SPEED.COM +SPL .COM 28K ; the SPL compiler itself +SPL .TXT 50K ; SPL language and compiler documentation +SPLERROR.DAT 8K ; error messages of the compiler +SPLRTLB .REL 2K ; SPL runtime library SYSCOPY .COM 2K SYSCOPY .SPL 6K ; SPL source for SYSCOPY.COM -TERMBDOS.SPL 2K ; terminal interface to CP/M for PROLOGZ, SPL source -UTIL .SPL 18K ; utility functions for PROLOGZ, SPL source +WC .COM 6K ; word count and query facility +WC .SPL 14K ; word count and query facility, SPL source WRITE .COM 4K WRITE .SPL 8K ; SPL source for W.COM XFORMAT .COM 2K @@ -828,7 +829,7 @@ trick is to get the Switch Register right). sim> set cpu 8080 ;note 4k Basic will not run on a Z80 CPU sim> set sio upper ;4k Basic does not like lower case letters as input - sim> set cpu noitrap ;4k Basic likes to execute non 8080 instructions - ignore + sim> set cpu noitrap ;4k Basic likes to execute non 8080 instructions-ignore sim> set sio ansi ;4k Basic produces 8-bit output, strip to seven bits sim> d sr 8 ;good setting for the Switch Register sim> load 4kbas.bin 0 ;load it at 0 @@ -873,8 +874,8 @@ trick is to get the Switch Register right). Execute the following commands to run Altair Extended Basic: - sim> set sio upper ;Extended Basic does not like lower case letters as input - sim> set sio ansi ;Extended Basic produces 8-bit output, strip to seven bits + sim> set sio upper ;Extended Basic requires upper case input + sim> set sio ansi ;Extended Basic produces 8-bit output, strip to 7 bits sim> d sr 8 ;good setting for the Switch Register sim> load exbas.bin 0 ;load it at 0 sim> go 0 ;and start it @@ -914,10 +915,7 @@ following commands: OK -6. Special simulator features - - -6.1 Memory access breakpoints +6. Special simulator feature: Memory access breakpoints In addition to the regular SIMH features such as PC queue, breakpoints etc., this simulator supports memory access breakpoints. A memory access @@ -932,21 +930,6 @@ a memory access breakpoint is not triggered by fetching code from memory by using the typing facility of the SIMH breakpoints. -6.2 T-state stepping - - The SIMH step command supports the "-t" modifier to allow steppping for -a predefined number of t-states. For example - -sim> step -t 1000 - -will cause the simulated CPU to execute 1000 t-states (note that the shortest -instruction will have 4 t-states). On the other hand, the command - -sim> step 1000 - -will cause the simulated CPU to execute 1000 instructions. - - 7. Brief summary of all major changes to the original Altair simulator - Full support for Z80. CP/M software requiring a Z80 CPU now runs properly. DDTZ and PROLOGZ are included for demonstration purposes. diff --git a/AltairZ80/altairz80_hdsk.c b/AltairZ80/altairz80_hdsk.c index bb1d0d01..7130c702 100644 --- a/AltairZ80/altairz80_hdsk.c +++ b/AltairZ80/altairz80_hdsk.c @@ -1,6 +1,6 @@ /* altairz80_hdsk.c: simulated hard disk device to increase capacity - Copyright (c) 2002-2004, Peter Schorn + Copyright (c) 2002-2005, Peter Schorn 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/HP2100/hp2100_cpu.c b/HP2100/hp2100_cpu.c index 43630b91..43304ed9 100644 --- a/HP2100/hp2100_cpu.c +++ b/HP2100/hp2100_cpu.c @@ -27,6 +27,7 @@ MP 12892B memory protect DMA0,DMA1 12895A/12897B direct memory access/dual channel port controller + 21-Jan-05 JDB Reorganized CPU option flags 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) @@ -340,9 +341,16 @@ #define UNIT_MP_INT (1 << UNIT_V_MP_INT) #define UNIT_MP_SEL1 (1 << UNIT_V_MP_SEL1) -#define MOD_2116 1 -#define MOD_2100 2 -#define MOD_21MX 4 +#define MOD_211X (1 << TYPE_211X) +#define MOD_2100 (1 << TYPE_2100) +#define MOD_21MX (1 << TYPE_21MX) +#define MOD_CURRENT (1 << CPU_TYPE) + +#define UNIT_SYSTEM (UNIT_CPU_MASK | UNIT_OPTS) +#define UNIT_SYS_2116 (UNIT_2116) +#define UNIT_SYS_2100 (UNIT_2100 | UNIT_EAU) +#define UNIT_SYS_21MX_M (UNIT_21MX_M | UNIT_EAU | UNIT_FP | UNIT_DMS) +#define UNIT_SYS_21MX_E (UNIT_21MX_E | UNIT_EAU | UNIT_FP | UNIT_DMS) #define ABORT(val) longjmp (save_env, (val)) @@ -396,13 +404,14 @@ struct opt_table { /* options table */ int32 cpuf; }; static struct opt_table opt_val[] = { - { UNIT_EAU, MOD_2116 }, + { UNIT_EAU, MOD_211X }, { UNIT_FP, MOD_2100 }, { UNIT_DMS, MOD_21MX }, { UNIT_IOP, MOD_2100 | MOD_21MX }, - { UNIT_2116, MOD_2116 | MOD_2100 | MOD_21MX }, - { UNIT_2100, MOD_2116 | MOD_2100 | MOD_21MX }, - { UNIT_21MX, MOD_2116 | MOD_2100 | MOD_21MX }, + { UNIT_FFP, MOD_2100 | MOD_21MX }, + { TYPE_211X, MOD_211X | MOD_2100 | MOD_21MX }, + { TYPE_2100, MOD_211X | MOD_2100 | MOD_21MX }, + { TYPE_21MX, MOD_211X | MOD_2100 | MOD_21MX }, { 0, 0 } }; extern int32 sim_interval; @@ -415,7 +424,7 @@ extern DEVICE *sim_devices[]; extern int32 sim_switches; extern char halt_msg[]; -t_stat Ea1 (uint32 *addr, uint32 irq); +t_stat Ea (uint32 IR, uint32 *addr, uint32 irq); uint16 ReadIO (uint32 addr, uint32 map); uint16 ReadPW (uint32 addr); uint16 ReadTAB (uint32 addr); @@ -440,7 +449,8 @@ t_bool dev_conflict (void); void hp_post_cmd (t_bool from_scp); extern t_stat cpu_eau (uint32 IR, uint32 intrq); -extern t_stat cpu_mac (uint32 IR, uint32 intrq); +extern t_stat cpu_uig_0 (uint32 IR, uint32 intrq); +extern t_stat cpu_uig_1 (uint32 IR, uint32 intrq); extern int32 clk_delay (int32 flg); extern void (*sim_vm_post) (t_bool from_scp); @@ -495,49 +505,50 @@ REG cpu_reg[] = { { NULL } }; MTAB cpu_mod[] = { - { UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX, - UNIT_2116, NULL, "2116", &cpu_set_opt, - NULL, (void *) UNIT_2116 }, - { UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX, - UNIT_2100+UNIT_EAU, NULL, "2100", &cpu_set_opt, - NULL, (void *) UNIT_2100 }, - { UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX, - UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX-E", &cpu_set_opt, - NULL, (void *) UNIT_21MX }, - { UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX, - UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX-M", &cpu_set_opt, - NULL, (void *) UNIT_21MX }, - { UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_2116, "2116", NULL, NULL }, - { 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, - 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, - 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, - 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, - 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, - NULL, (void *) UNIT_IOP }, - { UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size }, - { UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size }, - { UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size }, - { UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size }, - { UNIT_MSIZE, 65536, NULL, "64K", &cpu_set_size }, - { UNIT_MSIZE, 131072, NULL, "128K", &cpu_set_size }, - { UNIT_MSIZE, 262144, NULL, "256K", &cpu_set_size }, - { UNIT_MSIZE, 524288, NULL, "512K", &cpu_set_size }, - { UNIT_MSIZE, 1048576, NULL, "1024K", &cpu_set_size }, + { UNIT_SYSTEM, UNIT_SYS_2116, NULL, "2116", &cpu_set_opt, NULL, + (void *) TYPE_211X }, + { UNIT_SYSTEM, UNIT_SYS_2100, NULL, "2100", &cpu_set_opt, NULL, + (void *) TYPE_2100 }, + { UNIT_SYSTEM, UNIT_SYS_21MX_E, NULL, "21MX-E", &cpu_set_opt, NULL, + (void *) TYPE_21MX }, + { UNIT_SYSTEM, UNIT_SYS_21MX_M, NULL, "21MX-M", &cpu_set_opt, NULL, + (void *) TYPE_21MX }, + + { UNIT_CPU_MASK, UNIT_2116, "2116", NULL, NULL }, + { UNIT_CPU_MASK, UNIT_2100, "2100", NULL, NULL }, + { UNIT_CPU_MASK, UNIT_21MX_E, "21MX-E", NULL, NULL }, + { UNIT_CPU_MASK, UNIT_21MX_M, "21MX-M", NULL, NULL }, + + { 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, NULL, + (void *) UNIT_FP }, + { UNIT_FP, 0, "no FP", "NOFP", &cpu_set_opt, NULL, + (void *) UNIT_FP }, + { UNIT_IOP, UNIT_IOP, "IOP", "IOP", &cpu_set_opt, NULL, + (void *) UNIT_IOP }, + { UNIT_IOP, 0, "no IOP", "NOIOP", &cpu_set_opt, NULL, + (void *) UNIT_IOP }, + { 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_FFP, UNIT_FFP, "FFP", "FFP", &cpu_set_opt, NULL, + (void *) UNIT_FFP }, + { UNIT_FFP, 0, "no FFP", "NOFFP", &cpu_set_opt, NULL, + (void *) UNIT_FFP }, + + { MTAB_XTD | MTAB_VDV, 4096, NULL, "4K", &cpu_set_size }, + { MTAB_XTD | MTAB_VDV, 8192, NULL, "8K", &cpu_set_size }, + { MTAB_XTD | MTAB_VDV, 16384, NULL, "16K", &cpu_set_size }, + { MTAB_XTD | MTAB_VDV, 32768, NULL, "32K", &cpu_set_size }, + { MTAB_XTD | MTAB_VDV, 65536, NULL, "64K", &cpu_set_size }, + { MTAB_XTD | MTAB_VDV, 131072, NULL, "128K", &cpu_set_size }, + { MTAB_XTD | MTAB_VDV, 262144, NULL, "256K", &cpu_set_size }, + { MTAB_XTD | MTAB_VDV, 524288, NULL, "512K", &cpu_set_size }, + { MTAB_XTD | MTAB_VDV, 1048576, NULL, "1024K", &cpu_set_size }, { 0 } }; DEVICE cpu_dev = { @@ -1006,10 +1017,15 @@ case 0211: /* DST */ /* Extended instructions */ -case 0212: /* MAC0 ext */ -case 0203: /* MAC1 ext */ +case 0212: /* UIG 0 extension */ + reason = cpu_uig_0 (IR, intrq); /* extended opcode */ + dmarq = calc_dma (); /* recalc DMA masks */ + intrq = calc_int (); /* recalc interrupts */ + break; + +case 0203: /* UIG 1 extension */ case 0213: - reason = cpu_mac (IR, intrq); /* extended opcode */ + reason = cpu_uig_1 (IR, intrq); /* extended opcode */ dmarq = calc_dma (); /* recalc DMA masks */ intrq = calc_int (); /* recalc interrupts */ break; } /* end case IR */ @@ -1043,14 +1059,12 @@ pcq_r->qptr = pcq_p; /* update pc q ptr */ return reason; } -/* Effective address calculation */ +/* Resolve indirect addresses */ -t_stat Ea (uint32 IR, uint32 *addr, uint32 irq) +t_stat resolve (uint32 MA, uint32 *addr, uint32 irq) { -uint32 i, MA; +uint32 i; -MA = IR & (I_IA | I_DISP); /* ind + disp */ -if (IR & I_CP) MA = ((PC - 1) & I_PAGENO) | MA; /* current page? */ for (i = 0; (i < ind_max) && (MA & I_IA); i++) { /* resolve multilevel */ if (irq && /* int req? */ ((i >= 2) || (mp_unit.flags & UNIT_MP_INT)) && /* ind > 3 or W6 out? */ @@ -1062,23 +1076,15 @@ if (i >= ind_max) return STOP_IND; /* indirect loop? */ return SCPE_OK; } -/* Effective address, two words */ +/* Get effective address from IR */ -t_stat Ea1 (uint32 *addr, uint32 irq) +t_stat Ea (uint32 IR, uint32 *addr, uint32 irq) { -uint32 i, MA; +uint32 MA; -MA = ReadW (PC); /* get next address */ -PC = (PC + 1) & VAMASK; -for (i = 0; (i < ind_max) && (MA & I_IA); i++) { /* resolve multilevel */ - if (irq && /* int req? */ - ((i >= 2) || (mp_unit.flags & UNIT_MP_INT)) && /* ind > 3 or W6 out? */ - !(mp_unit.flags & DEV_DIS)) /* MP installed? */ - return STOP_INDINT; /* break out */ - MA = ReadW (MA & VAMASK); } -if (i >= ind_max) return STOP_IND; /* indirect loop? */ -*addr = MA; -return SCPE_OK; +MA = IR & (I_IA | I_DISP); /* ind + disp */ +if (IR & I_CP) MA = ((PC - 1) & I_PAGENO) | MA; /* current page? */ +return resolve (MA, addr, irq); /* resolve indirects */ } /* Shift micro operation */ @@ -1181,7 +1187,7 @@ return r; to request an interrupt. This is the masked under the result from #1 to determine the highest priority interrupt, if any. - */ +*/ uint32 calc_int (void) { @@ -1550,7 +1556,7 @@ case ioLIX: /* load */ dat = SR; break; case ioOTX: /* output */ - if (cpu_unit.flags & (UNIT_2100 | UNIT_21MX)) SR = dat; + if (UNIT_CPU_TYPE != UNIT_TYPE_211X) SR = dat; break; default: break; } @@ -1663,7 +1669,7 @@ case ioSFS: /* skip flag set */ case ioLIX: /* load */ dat = 0; case ioMIX: /* merge */ - if (cpu_unit.flags & UNIT_21MX) dat = DMASK; + if (UNIT_CPU_TYPE == UNIT_TYPE_21MX) dat = DMASK; break; case ioOTX: /* output */ dmac[ch].cw1 = dat; @@ -1748,7 +1754,8 @@ case ioSFC: /* skip flag clear */ case ioLIX: /* load */ dat = 0; case ioMIX: /* merge */ - if ((devd < VARDEV) && (cpu_unit.flags & UNIT_21MX)) dat = DMASK; + if ((devd < VARDEV) && (UNIT_CPU_TYPE == UNIT_TYPE_21MX)) + dat = DMASK; break; default: break; } @@ -1854,7 +1861,7 @@ int32 mc = 0; uint32 i; if ((val <= 0) || (val > PASIZE) || ((val & 07777) != 0) || - (!(uptr->flags & UNIT_21MX) && (val > VASIZE))) + ((UNIT_CPU_TYPE != UNIT_TYPE_21MX) && (val > VASIZE))) return SCPE_ARG; if (!(sim_switches & SWMASK ('F'))) { /* force truncation? */ for (i = val; i < MEMSIZE; i++) mc = mc | M[i]; @@ -1947,33 +1954,35 @@ return FALSE; /* Configuration validation - Memory is trimmed to 32K if 2116 or 2100 is selected. - Memory protect is enabled if 2100 or 21MX or DMS is selected. - DMA is enabled if 2116 or 2100 or 21MX is selected. */ + - Checks that the current CPU type supports the option selected. + - Ensures that FP/FFP and IOP are mutually exclusive if CPU is 2100. + - Disables memory protect if 2116 is selected. + - Enables memory protect if 2100 or 21MX or DMS is selected. + - Enables DMA if 2116 or 2100 or 21MX is selected. + - Memory is trimmed to 32K if 2116 or 2100 is selected. */ t_bool cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 opt = (int32) desc; -int32 mod, i; +int32 i; +uint32 mod; -mod = MOD_2116; -if (uptr->flags & UNIT_2100) mod = MOD_2100; -else if (uptr->flags & UNIT_21MX) mod = MOD_21MX; +mod = MOD_CURRENT; for (i = 0; opt_val[i].cpuf != 0; i++) { if ((opt == opt_val[i].optf) && (mod & opt_val[i].cpuf)) { - if ((mod == MOD_2100) && (val == UNIT_FP)) - uptr->flags = uptr->flags & ~UNIT_IOP; - if ((opt == UNIT_IOP) && val) { - if (mod == MOD_2100) - uptr->flags = (uptr->flags & ~UNIT_FP) | UNIT_IOP; - if (mod == MOD_21MX) uptr->flags |= UNIT_IOPX; } - if (opt == UNIT_2116) mp_dev.flags = mp_dev.flags | DEV_DIS; - else if ((val == UNIT_DMS) || (opt == UNIT_2100) || (opt == UNIT_21MX)) + if (mod == MOD_2100) + if ((opt == UNIT_FP) || (opt == UNIT_FFP)) + uptr->flags = uptr->flags & ~UNIT_IOP; + else if (opt == UNIT_IOP) + uptr->flags = uptr->flags & ~(UNIT_FP | UNIT_FFP); + if (opt == TYPE_211X) + mp_dev.flags = mp_dev.flags | DEV_DIS; + else if ((opt == UNIT_DMS) || (opt == TYPE_2100) || (opt == TYPE_21MX)) mp_dev.flags = mp_dev.flags & ~DEV_DIS; - if ((opt == UNIT_2116) || (opt == UNIT_2100) || (opt == UNIT_21MX)) { + if ((opt == TYPE_211X) || (opt == TYPE_2100) || (opt == TYPE_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 > VASIZE)) + if (((opt == TYPE_211X) || (opt == TYPE_2100)) && (MEMSIZE > VASIZE)) return cpu_set_size (uptr, VASIZE, cptr, desc); return SCPE_OK; } } return SCPE_NOFNC; diff --git a/HP2100/hp2100_cpu.h b/HP2100/hp2100_cpu.h index ff734158..6a39ebfd 100644 --- a/HP2100/hp2100_cpu.h +++ b/HP2100/hp2100_cpu.h @@ -23,37 +23,67 @@ 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. + 21-Jan-05 JDB Reorganized CPU option flags 14-Jan-05 RMS Cloned from hp2100_cpu.c + + CPU models are broken down into type and series to facilitate option + validation. Bits 3:2 encode the type, and bits 1:0 encode the series + within the type. */ #ifndef _HP2100_CPU_H_ #define _HP2100_CPU_H_ 0 +#define CPU_V_SERIES 0 +#define CPU_V_TYPE 2 + +#define TYPE_211X 0 /* 2114, 2115, 2116 */ +#define TYPE_2100 1 /* 2100A, 2100S */ +#define TYPE_21MX 2 /* 21MX-M, 21MX-E, 21MX-F */ +#define TYPE_1000A 3 /* A600, A700, A900, A990 */ + +#define CPU_2116 (TYPE_211X << CPU_V_TYPE | 0) +#define CPU_2100 (TYPE_2100 << CPU_V_TYPE | 0) +#define CPU_21MX_M (TYPE_21MX << CPU_V_TYPE | 0) +#define CPU_21MX_E (TYPE_21MX << CPU_V_TYPE | 1) + +#define UNIT_V_CPU (UNIT_V_UF + 0) /* CPU model bits 0-3 */ +#define UNIT_M_CPU 017 /* CPU model mask */ +#define UNIT_M_TYPE 014 /* CPU type mask */ +#define UNIT_V_EAU (UNIT_V_UF + 4) /* EAU installed */ +#define UNIT_V_FP (UNIT_V_UF + 5) /* FP installed */ +#define UNIT_V_IOP (UNIT_V_UF + 6) /* IOP installed */ +#define UNIT_V_DMS (UNIT_V_UF + 7) /* DMS installed */ +#define UNIT_V_FFP (UNIT_V_UF + 8) /* FFP installed */ + +#define UNIT_CPU_MASK (UNIT_M_CPU << UNIT_V_CPU) +#define UNIT_2116 (CPU_2116 << UNIT_V_CPU) +#define UNIT_2100 (CPU_2100 << UNIT_V_CPU) +#define UNIT_21MX_M (CPU_21MX_M << UNIT_V_CPU) +#define UNIT_21MX_E (CPU_21MX_E << UNIT_V_CPU) + +#define UNIT_TYPE_MASK (UNIT_M_TYPE << UNIT_V_CPU) +#define UNIT_TYPE_211X ((TYPE_211X << CPU_V_TYPE) << UNIT_V_CPU) +#define UNIT_TYPE_2100 ((TYPE_2100 << CPU_V_TYPE) << UNIT_V_CPU) +#define UNIT_TYPE_21MX ((TYPE_21MX << CPU_V_TYPE) << UNIT_V_CPU) + +#define UNIT_CPU_MODEL (cpu_unit.flags & UNIT_CPU_MASK) +#define UNIT_CPU_TYPE (cpu_unit.flags & UNIT_TYPE_MASK) +#define CPU_TYPE (UNIT_CPU_TYPE >> (UNIT_V_CPU + CPU_V_TYPE)) + +#define UNIT_EAU (1 << UNIT_V_EAU) +#define UNIT_FP (1 << UNIT_V_FP) +#define UNIT_IOP (1 << UNIT_V_IOP) +#define UNIT_DMS (1 << UNIT_V_DMS) +#define UNIT_FFP (1 << UNIT_V_FFP) + +#define UNIT_OPTS (UNIT_EAU | UNIT_FP | UNIT_IOP | UNIT_DMS | UNIT_FFP) + #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); +t_stat resolve (uint32 MA, uint32 *addr, uint32 irq); uint8 ReadB (uint32 addr); uint8 ReadBA (uint32 addr); uint16 ReadW (uint32 addr); diff --git a/HP2100/hp2100_cpu1.c b/HP2100/hp2100_cpu1.c index 6300159c..5958d41f 100644 --- a/HP2100/hp2100_cpu1.c +++ b/HP2100/hp2100_cpu1.c @@ -1,4 +1,4 @@ -/* hp2100_cpu.c: HP 2100 EAU and MAC simulator +/* hp2100_cpu1.c: HP 2100 EAU and UIG simulator Copyright (c) 2005, Robert M. Supnik @@ -23,16 +23,126 @@ 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 + CPU1 Extended arithmetic and optional microcode instructions - 22-Feb-05 JDB Fixed missing MPCK on JRS target + 22-Feb-05 JDB Fixed missing MPCK on JRS target Removed EXECUTE instruction (is NOP in actual microcode) + 18-Feb-05 JDB Add 2100/21MX Fast FORTRAN Processor instructions + 21-Jan-05 JDB Reorganized CPU option and operand processing flags + Split code along microcode modules 15-Jan-05 RMS Cloned from hp2100_cpu.c + + Primary references: + - HP 1000 M/E/F-Series Computers Technical Reference Handbook + (5955-0282, Mar-1980) + - HP 1000 M/E/F-Series Computers Engineering and Reference Documentation + (92851-90001, Mar-1981) + + Additional references are listed with the associated firmware + implementations, as are the HP option model numbers pertaining to the + applicable CPUs. + + This source file contains the Extended Arithmetic Unit and various optional + User Instruction Group (a.k.a. "Macro") instruction sets for the 2100 and + 21MX CPUs. Unit flags indicate which options are present in the current + system. + + The microcode address space of the 2100 encompassed four modules of 256 words + each. The 21MX M-series expanded that to sixteen modules, and the 21MX + E-series expanded that still further to sixty-four modules. Each CPU had its + own microinstruction set, although the micromachines of the various 21MX + models were similar internally. + + Regarding option instruction sets, there was some commonality across CPU + types. EAU instructions were identical across all models, and the floating + point set was the same on the 2100 and 21MX. Other options implemented + proper instruction supersets (e.g., the Fast FORTRAN Processor from 2100 to + 21MX-M to 21MX-E to 21MX-F) or functional equivalence with differing code + points (the 2000 I/O Processor from 2100 to 21MX). + + The 2100 decoded the EAU and UIG sets separately in hardware and supported + only the UIG 0 code points. Bits 7-4 of a UIG instruction decoded one of + sixteen entry points in the lowest-numbered module after module 0. Those + entry points could be used directly (as for the floating-point instructions), + or additional decoding based on bits 3-0 could be implemented. + + The 21MX generalized the instruction decoding to a series of microcoded + jumps, based on the bits in the instruction. Bits 15-8 indicated the group + of the current instruction: EAU (200, 201, 202, 210, and 211), UIG 0 (212), + or UIG 1 (203 and 213). UIG 0, UIG 1, and some EAU instructions were decoded + further by selecting one of sixteen modules within the group via bits 7-4. + Finally, each UIG module decoded up to sixteen instruction entry points via + bits 3-0. Jump tables for all firmware options were contained in the base + set, so modules needed only to be concerned with decoding their individual + entry points within the module. + + While the 2100 and 21MX hardware decoded these instruction sets differently, + the decoding mechanism of the simulation follows that of the 21MX E-series. + Where needed, CPU type- or model-specific behavior is simulated. + + The design of the 21MX microinstruction set was such that executing an + instruction for which no microcode was present (e.g., executing a FFP + instruction when the FFP firmware was not installed) resulted in a NOP. + Under simulation, such execution causes an undefined instruction stop. */ -#include "hp2100_defs.h" #include +#include "hp2100_defs.h" #include "hp2100_cpu.h" +#include "hp2100_fp1.h" + +/* Operand processing encoding */ + +#define OP_NUL 0 /* no operand */ +#define OP_CON 1 /* operand is a constant */ +#define OP_VAR 2 /* operand is a variable */ +#define OP_ADR 3 /* operand is an address */ +#define OP_ADK 4 /* op is addr of 1-word const */ +#define OP_ADF 5 /* op is addr of 2-word const */ +#define OP_ADX 6 /* op is addr of 3-word const */ +#define OP_ADT 7 /* op is addr of 4-word const */ + +#define OP_N_FLAGS 3 /* number of flag bits */ +#define OP_M_FLAGS ((1 << OP_N_FLAGS) - 1) /* mask for flag bits */ + +#define OP_N_F 4 /* number of op fields */ + +#define OP_V_F1 (0 * OP_N_FLAGS) /* 1st operand field */ +#define OP_V_F2 (1 * OP_N_FLAGS) /* 2nd operand field */ +#define OP_V_F3 (2 * OP_N_FLAGS) /* 3rd operand field */ +#define OP_V_F4 (3 * OP_N_FLAGS) /* 4th operand field */ + +/* Operand patterns */ + +#define OP_N (OP_NUL) +#define OP_C (OP_CON << OP_V_F1) +#define OP_V (OP_VAR << OP_V_F1) +#define OP_A (OP_ADR << OP_V_F1) +#define OP_K (OP_ADK << OP_V_F1) +#define OP_F (OP_ADF << OP_V_F1) +#define OP_CV ((OP_CON << OP_V_F1) | (OP_VAR << OP_V_F2)) +#define OP_AC ((OP_ADR << OP_V_F1) | (OP_CON << OP_V_F2)) +#define OP_AA ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2)) +#define OP_AK ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2)) +#define OP_AX ((OP_ADR << OP_V_F1) | (OP_ADX << OP_V_F2)) +#define OP_KV ((OP_ADK << OP_V_F1) | (OP_VAR << OP_V_F2)) +#define OP_KA ((OP_ADK << OP_V_F1) | (OP_ADR << OP_V_F2)) +#define OP_KK ((OP_ADK << OP_V_F1) | (OP_ADK << OP_V_F2)) +#define OP_CVA ((OP_CON << OP_V_F1) | (OP_VAR << OP_V_F2) | \ + (OP_ADR << OP_V_F3)) +#define OP_AAF ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ + (OP_ADF << OP_V_F3)) +#define OP_AAX ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ + (OP_ADX << OP_V_F3)) +#define OP_AXX ((OP_ADR << OP_V_F1) | (OP_ADX << OP_V_F2) | \ + (OP_ADX << OP_V_F3)) +#define OP_AAXX ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ + (OP_ADX << OP_V_F3) | (OP_ADX << OP_V_F4)) +#define OP_KKKK ((OP_ADK << OP_V_F1) | (OP_ADK << OP_V_F2) | \ + (OP_ADK << OP_V_F3) | (OP_ADK << OP_V_F4)) + +typedef uint32 OP_PAT; /* operand pattern */ +typedef uint32 OPS[OP_N_F * 2]; /* operand array */ extern uint16 ABREG[2]; extern uint32 PC; @@ -51,132 +161,98 @@ 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); +t_stat cpu_eau (uint32 IR, uint32 intrq); /* EAU group handler */ +t_stat cpu_uig_0 (uint32 IR, uint32 intrq); /* UIG group 0 handler */ +t_stat cpu_uig_1 (uint32 IR, uint32 intrq); /* UIG group 1 handler */ -/* Extended instruction decode tables */ +static t_stat cpu_fp (uint32 IR, uint32 intrq); /* Floating-point */ +static t_stat cpu_ffp (uint32 IR, uint32 intrq); /* Fast FORTRAN Processor */ +static t_stat cpu_iop (uint32 IR, uint32 intrq); /* 2000 I/O Processor */ +static t_stat cpu_dms (uint32 IR, uint32 intrq); /* Dynamic mapping system */ +static t_stat cpu_eig (uint32 IR, uint32 intrq); /* Extended instruction group */ +static t_stat get_ops (OP_PAT pattern, OPS op, uint32 irq); /* operand processor */ -#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 */ +extern uint32 f_as (uint32 op, t_bool sub); /* FAD/FSB */ +extern uint32 f_mul (uint32 op); /* FMP */ +extern uint32 f_div (uint32 op); /* FDV */ +extern uint32 f_fix (void); /* FIX */ +extern uint32 f_flt (void); /* FLT */ +extern uint32 f_pack (int32 expon); /* .PACK helper */ +extern void f_unpack (void); /* .FLUN helper */ +extern void f_pwr2 (int32 n); /* .PWR2 helper */ -/* Extended arithmetic +/* EAU - 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. + The Extended Arithmetic Unit (EAU) adds ten instructions with double-word + operands, including multiply, divide, shifts, and rotates. Option + implementation by CPU was as follows: - 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. */ + 2116 2100 21MX-M 21MX-E 21MX-F + ------ ------ ------ ------ ------ + 12579A std std std std + + The instruction codes are mapped to routines as follows: + + Instr. Bits + Code 15-8 7-4 2116 2100 21MX-M 21MX-E 21MX-F Note + ------ ---- --- ------ ------ ------ ------ ------ --------------------- + 100000 200 00 DIAG DIAG Unsupported + 100020 200 01 ASL ASL ASL ASL ASL Bits 3-0 encode shift + 100040 200 02 LSL LSL LSL LSL LSL Bits 3-0 encode shift + 100060 200 03 TIMER TIMER Unsupported + 100100 200 04 RRL RRL RRL RRL RRL Bits 3-0 encode shift + 100200 200 10 MPY MPY MPY MPY MPY + 100400 201 xx DIV DIV DIV DIV DIV + 101020 202 01 ASR ASR ASR ASR ASR Bits 3-0 encode shift + 101040 202 02 LSR LSR LSR LSR LSR Bits 3-0 encode shift + 101100 202 04 RRR RRR RRR RRR RRR Bits 3-0 encode shift + 104200 210 xx DLD DLD DLD DLD DLD + 104400 211 xx DST DST DST DST DST + + The remaining codes for bits 7-4 are undefined and will cause a simulator + stop if enabled. On a real 21MX-M, all undefined instructions in the 200 + group decode as MPY, and all in the 202 group decode as NOP. On a real + 21MX-E, instruction patterns 200/05 through 200/07 and 202/03 decode as NOP; + all others cause erroneous execution. + + EAU instruction decoding on the 21MX M-series is convoluted. The JEAU + microorder maps IR bits 11, 9-7 and 5-4 to bits 2-0 of the microcode jump + address. The map is detailed on page IC-84 of the ERD. + + The 21MX E/F-series add two undocumented instructions to the 200 group: + TIMER and DIAG. These are described in the ERD on page IA 5-5, paragraph + 5-7. The M-series executes these as MPY and RRL, respectively. A third + instruction, EXECUTE (100120), is also described but was never implemented, + and the E/F-series microcode execute a NOP for this instruction code. + + Under simulation, TIMER, DIAG, and EXECUTE cause undefined instruction stops + if the CPU is set to 2100 or 2116. DIAG and EXECUTE also cause stops on the + 21MX-M. TIMER does not, because it is used by several HP programs to + differentiate between M- and E/F-series machines. +*/ t_stat cpu_eau (uint32 IR, uint32 intrq) { t_stat reason = SCPE_OK; -uint32 MA, v1, v2, t; -uint32 rs, qs, sc; +OPS op; +uint32 rs, qs, sc, v1, v2, t; int32 sop1, sop2; if ((cpu_unit.flags & UNIT_EAU) == 0) return stop_inst; /* implemented? */ -switch ((IR >> 8) & 017) { /* case on IR<11:8> */ +switch ((IR >> 8) & 0377) { /* decode IR<15:8> */ - case 000: /* EAU group 0 */ +case 0200: /* EAU group 0 */ switch ((IR >> 4) & 017) { /* decode IR<7:4> */ - case 001: /* ASL */ + + case 000: /* DIAG 100000 */ + if (UNIT_CPU_MODEL != UNIT_21MX_E) /* must be 21MX-E */ + return stop_inst; /* trap if not */ + break; /* DIAG is NOP unless halted */ + + case 001: /* ASL 100020-100037 */ sc = (IR & 017)? (IR & 017): 16; /* get sc */ O = 0; /* clear ovflo */ while (sc-- != 0) { /* bit by bit */ @@ -185,49 +261,54 @@ switch ((IR >> 8) & 017) { /* case on IR<11:8> */ AR = (AR << 1) & DMASK; if ((BR ^ t) & SIGN) O = 1; } break; - case 002: /* LSL */ + + case 002: /* LSL 100040-100057 */ 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 */ + + case 003: /* TIMER 100060 */ + if (UNIT_CPU_TYPE != UNIT_TYPE_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) */ + if (UNIT_CPU_MODEL == UNIT_21MX_M) /* 21MX M-series? */ + goto MPY; /* decode as MPY */ + BR = (BR + 1) & DMASK; /* increment B */ + if (BR) PC = err_PC; /* if !=0, repeat */ + break; + + case 004: /* RRL 100100-100117 */ 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 */ + + case 010: /* MPY 100200 */ + MPY: + if (reason = get_ops (OP_K, op, intrq)) /* get operand */ + break; sop1 = SEXT (AR); /* sext AR */ - sop2 = SEXT (ReadW (MA)); /* sext mem */ + sop2 = SEXT (op[0]); /* sext mem */ sop1 = sop1 * sop2; /* signed mpy */ BR = (sop1 >> 16) & DMASK; /* to BR'AR */ AR = sop1 & DMASK; O = 0; /* no overflow */ break; - default: + + default: /* others undefined */ return stop_inst; } + break; - case 001: /* divide */ - if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */ +case 0201: /* DIV 100400 */ + if (reason = get_ops (OP_K, op, intrq)) /* get operand */ + break; 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 */ + v2 = op[0]; /* divr = mem */ if (v2 & SIGN) { /* neg? */ v2 = (~v2 + 1) & DMASK; /* make divr pos */ qs = qs ^ SIGN; } /* sign of quotient */ @@ -243,740 +324,1563 @@ switch ((IR >> 8) & 017) { /* case on IR<11:8> */ if (rs) BR = (~BR + 1) & DMASK; } /* apply rem sign */ break; - case 002: /* EAU group 2 */ +case 0202: /* EAU group 2 */ switch ((IR >> 4) & 017) { /* decode IR<7:4> */ - case 001: /* ASR */ + + case 001: /* ASR 101020-101037 */ 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 */ + + case 002: /* LSR 101040-101057 */ 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 */ + + case 004: /* RRR 101100-101117 */ 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: + + default: /* others undefined */ 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 */ +case 0210: /* DLD 104200 */ + if (reason = get_ops (OP_F, op, intrq)) /* get operand */ + break; + AR = (op[0] >> 16) & DMASK; /* load AR */ + BR = op[0] & DMASK; /* 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 */ +case 0211: /* DST 104400 */ + if (reason = get_ops (OP_A, op, intrq)) /* get operand */ + break; + WriteW (op[0], AR); /* store AR */ + op[0] = (op[0] + 1) & VAMASK; + WriteW (op[0], BR); /* store BR */ break; - default: /* should never get here */ +default: /* should never get here */ return SCPE_IERR; } + return reason; } -t_stat cpu_mac (uint32 IR, uint32 intrq) +/* UIG 0 + + The first User Instruction Group (UIG) encodes firmware options for the 2100 + and 21MX. Instruction codes 105000-105377 are assigned to microcode options + as follows: + + Instructions Option Name 2100 21MX-M 21MX-E 21MX-F + ------------- ------------------------- ------ ------ ------ ------ + 105000-105362 2000 I/O Processor opt - - - + 105000-105120 Floating Point opt std std std + 105200-105237 Fast FORTRAN Processor opt opt opt std + 105240-105257 RTE-IVA/B EMA - - opt opt + 105240-105257 RTE-6/VMA - - opt opt + 105300-105317 Distributed System - - opt opt + 105340-105357 RTE-6/VM Operating System - - opt opt + + Because the 2100 IOP microcode uses the same instruction range as the 2100 FP + and FFP options, it cannot coexist with them. To simplify simulation, the + 2100 IOP instructions are remapped to the equivalent 21MX instructions and + dispatched to the UIG 1 module. + + Note that if the 2100 IOP is installed, the only valid UIG instructions are + IOP instructions, as the IOP used the full 2100 microcode addressing space. +*/ + +t_stat cpu_uig_0 (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; +if ((cpu_unit.flags & UNIT_IOP) && (UNIT_CPU_TYPE == UNIT_TYPE_2100)) { + if ((IR >= 0105020) && (IR <= 0105057)) /* remap LAI */ + IR = 0105400 | (IR - 0105020); + else if ((IR >= 0105060) && (IR <= 0105117)) /* remap SAI */ + IR = 0101400 | (IR - 0105060); + else + switch (IR) { /* remap others */ + case 0105000: IR = 0105470; break; /* ILIST */ + case 0105120: IR = 0105765; break; /* MBYTE (maps to MBT) */ + case 0105150: IR = 0105460; break; /* CRC */ + case 0105160: IR = 0105467; break; /* TRSLT */ + case 0105200: IR = 0105777; break; /* MWORD (maps to MVW) */ + case 0105220: IR = 0105462; break; /* READF */ + case 0105221: IR = 0105473; break; /* PRFIO */ + case 0105222: IR = 0105471; break; /* PRFEI */ + case 0105223: IR = 0105472; break; /* PRFEX */ + case 0105240: IR = 0105464; break; /* ENQ */ + case 0105257: IR = 0105465; break; /* PENQ */ + case 0105260: IR = 0105466; break; /* DEQ */ + case 0105300: IR = 0105764; break; /* SBYTE (maps to SBT) */ + case 0105320: IR = 0105763; break; /* LBYTE (maps to LBT) */ + case 0105340: IR = 0105461; break; /* REST */ + case 0105362: IR = 0105474; break; /* SAVE */ + + default: /* all others invalid */ + return stop_inst; + } + if (IR >= 0105700) return cpu_eig (IR, intrq); /* dispatch to 21MX EIG */ + else return cpu_iop (IR, intrq); } /* or to 21MX IOP */ + +switch ((IR >> 4) & 017) { /* decode IR<7:4> */ + +case 000: /* 105000-105017 */ +case 001: /* 105020-105037 */ +case 002: /* 105040-105057 */ +case 003: /* 105060-105077 */ +case 004: /* 105100-105117 */ +case 005: /* 105120-105137 */ + return cpu_fp (IR, intrq); /* Floating Point */ + +case 010: /* 105200-105217 */ +case 011: /* 105220-105237 */ + return cpu_ffp (IR, intrq); /* Fast FORTRAN Processor */ + } + +return stop_inst; /* others undefined */ +} + +/* UIG 1 + + The second User Instruction Group (UIG) encodes firmware options for the + 21MX. Instruction codes 101400-101777 and 105400-105777 are assigned to + microcode options as follows ("x" is "1" or "5" below): + + Instructions Option Name 21MX-M 21MX-E 21MX-F + ------------- -------------------------- ------ ------ ------ + 10x400-10x437 2000 IOP opt opt - + 10x460-10x477 2000 IOP opt opt - + 10x700-10x737 Dynamic Mapping System opt opt std + 10x740-10x777 Extended Instruction Group std std std + + Only 21MX systems execute these instructions. +*/ + +t_stat cpu_uig_1 (uint32 IR, uint32 intrq) +{ +if (UNIT_CPU_TYPE != UNIT_TYPE_21MX) /* 21MX execution? */ + return stop_inst; /* no, so trap */ + +switch ((IR >> 4) & 017) { /* decode IR<7:4> */ + +case 000: /* 105400-105417 */ +case 001: /* 105420-105437 */ +case 003: /* 105460-105477 */ + return cpu_iop (IR, intrq); /* 2000 I/O Processor */ + +case 014: /* 105700-105717 */ +case 015: /* 105720-105737 */ + return cpu_dms (IR, intrq); /* Dynamic Mapping System */ + +case 016: /* 105740-105737 */ +case 017: /* 105760-105777 */ + return cpu_eig (IR, intrq); /* Extended Instruction Group */ + } + +return stop_inst; /* others undefined */ +} + +/* Floating Point + + The 2100 and 21MX CPUs share the single-precision (two word) floating point + instruction codes. Option implementation by CPU was as follows: + + 2116 2100 21MX-M 21MX-E 21MX-F + ------ ------ ------ ------ ------ + N/A 12901A std std std + + The instruction codes are mapped to routines as follows: + + Instr. 2100/21MX-M/E/F + ------ --------------- + 105000 FAD + 105020 FSB + 105040 FMP + 105060 FDV + 105100 FIX + 105120 FLT + + Bits 3-0 are not decoded by these instructions, so FAD (e.g.) would be + executed by any instruction in the range 105000-105017. +*/ + +static const OP_PAT op_fp[6] = { + OP_F, OP_F, OP_F, OP_F, /* FAD FSB FMP FDV */ + OP_N, OP_N }; /* FIX FLT --- --- */ + +static t_stat cpu_fp (uint32 IR, uint32 intrq) +{ +t_stat reason = SCPE_OK; +OPS op; +uint32 entry; + +if ((cpu_unit.flags & UNIT_FP) == 0) /* FP option installed? */ + return stop_inst; + +entry = (IR >> 4) & 017; /* mask to entry point */ + +if (op_fp[entry] != OP_N) + if (reason = get_ops (op_fp[entry], op, intrq)) /* get instruction operands */ + return reason; + +switch (entry) { /* decode IR<7:4> */ + +case 000: /* FMP 105000 */ + O = f_as (op[0], 0); /* add, upd ovflo */ + break; + +case 001: /* FMP 105020 */ + O = f_as (op[0], 1); /* sub, upd ovflo */ + break; + +case 002: /* FMP 105040 */ + O = f_mul (op[0]); /* mul, upd ovflo */ + break; + +case 003: /* FDV 105060 */ + O = f_div (op[0]); /* div, upd ovflo */ + break; + +case 004: /* FIX 105100 */ + O = f_fix (); /* fix, upd ovflo */ + break; + +case 005: /* FLT 105120 */ + O = f_flt (); /* float, upd ovflo */ + break; + +default: /* should be impossible */ + return SCPE_IERR; + } + +return reason; +} + +/* Fast FORTRAN Processor + + The Fast FORTRAN Processor (FFP) is a set of FORTRAN language accelerators + and extended-precision (three-word) floating point routines. Although the + FFP is an option for the 2100 and later CPUs, each implements the FFP in a + slightly different form. + + Option implementation by CPU was as follows: + + 2116 2100 21MX-M 21MX-E 21MX-F + ------ ------ ------ ------ ------ + N/A 12907A 12977B 13306B std + + The instruction codes are mapped to routines as follows: + + Instr. 2100 21MX-M 21MX-E 21MX-F Instr. 2100 21MX-M 21MX-E 21MX-F + ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ + 105200 -- -- -- [test] 105220 .XFER .XFER .XFER .XFER + 105201 DBLE DBLE DBLE DBLE 105221 .GOTO .GOTO .GOTO .GOTO + 105202 SNGL SNGL SNGL SNGL 105222 ..MAP ..MAP ..MAP ..MAP + 105203 .XMPY .XMPY .XMPY -- 105223 .ENTR .ENTR .ENTR .ENTR + 105204 .XDIV .XDIV .XDIV -- 105224 .ENTP .ENTP .ENTP .ENTP + 105205 .DFER .DFER .DFER .DFER 105225 -- .PWR2 .PWR2 .PWR2 + 105206 -- .XPAK .XPAK .XPAK 105226 -- .FLUN .FLUN .FLUN + 105207 -- XADD XADD .BLE 105227 $SETP $SETP $SETP $SETP + + 105210 -- XSUB XSUB -- 105230 -- .PACK .PACK .PACK + 105211 -- XMPY XMPY -- 105231 -- -- .CFER .CFER + 105212 -- XDIV XDIV -- 105232 -- -- -- ..FCM + 105213 .XADD .XADD .XADD -- 105233 -- -- -- ..TCM + 105214 .XSUB .XSUB .XSUB .NGL 105234 -- -- -- -- + 105215 -- .XCOM .XCOM .XCOM 105235 -- -- -- -- + 105216 -- ..DCM ..DCM ..DCM 105236 -- -- -- -- + 105217 -- DDINT DDINT DDINT 105237 -- -- -- -- + + Notes: + + 1. The "$SETP" instruction is sometimes listed as ".SETP" in the + documentation. + + 2. Extended-precision arithmetic routines (e.g., .XMPY) exist on the + 21MX-F, but they are assigned instruction codes in the single-precision + floating-point module. + + 3. The software implementation of ..MAP supports 1-, 2-, or 3-dimensional + arrays, designated by setting A = -1, 0, and +1, respectively. The + firmware implementation supports only 2- and 3-dimensional access. + + 4. The documentation for ..MAP for the 2100 FFP shows A = 0 or -1 for two + or three dimensions, respectively, but the 21MX FFP shows A = 0 or +1. + The firmware actually only checks the LSB of A. + + 5. The .DFER and .XFER implementations for the 2100 FFP return X+4 and Y+4 + in the A and B registers, whereas the 21MX FFP returns X+3 and Y+3. + + 6. The .XFER implementation for the 2100 FFP returns to P+2, whereas the + 21MX implementation returns to P+1. + + Additional references: + - DOS/RTE Relocatable Library Reference Manual (24998-90001, Oct-1981) + - Implementing the HP 2100 Fast FORTRAN Processor (12907-90010, Nov-1974) +*/ + +static const OP_PAT op_ffp[32] = { + OP_N, OP_AAF, OP_AX, OP_AXX, /* --- DBLE SNGL .XMPY */ + OP_AXX, OP_AA, OP_A, OP_AAXX, /* .XDIV .DFER .XPAK XADD */ + OP_AAXX, OP_AAXX, OP_AAXX, OP_AXX, /* XSUB XMPY XDIV .XADD */ + OP_AXX, OP_A, OP_A, OP_AAX, /* .XSUB .XCOM ..DCM DDINT */ + OP_N, OP_AK, OP_KKKK, OP_A, /* .XFER .GOTO ..MAP .ENTR */ + OP_A, OP_K, OP_N, OP_K, /* .ENTP .PWR2 .FLUN $SETP */ + OP_C, OP_AA, OP_N, OP_N, /* .PACK .CFER --- --- */ + OP_N, OP_N, OP_N, OP_N }; /* --- --- --- --- */ + +static t_stat cpu_ffp (uint32 IR, uint32 intrq) +{ +t_stat reason = SCPE_OK; +OPS op, op2; +uint32 entry; +uint32 j, sa, sb, sc, da, dc, ra, MA; +int32 i; +XPN xop; + +if ((cpu_unit.flags & UNIT_FFP) == 0) /* FFP option installed? */ + return stop_inst; + +entry = IR & 037; /* mask to entry point */ + +if (op_ffp[entry] != OP_N) + if (reason = get_ops (op_ffp[entry], op, intrq))/* get instruction operands */ + return reason; + +switch (entry) { /* decode IR<3:0> */ + +/* FFP module 1 */ + +case 001: /* DBLE 105201 (OP_AAF) */ + WriteW (op[1]++, (op[2] >> 16) & DMASK); /* transfer high mantissa */ + WriteW (op[1]++, op[2] & 0177400); /* convert low mantissa */ + WriteW (op[1], op[2] & 0377); /* convert exponent */ + break; + +case 002: /* SNGL 105202 (OP_AX) */ + BR = op[2] >> 16; /* move LSB and expon to B */ + f_unpack (); /* unpack B into A/B */ + sa = AR; /* save exponent */ + AR = (op[1] >> 16) & DMASK; /* move MSB to A */ + BR = (op[1] & DMASK) | (BR != 0); /* move mid to B with carry */ + O = f_pack (SEXT (sa)); /* pack into A/B */ + break; + +#if defined (HAVE_INT64) + +case 003: /* .XMPY 105203 (OP_AXX) */ + i = 0; /* params start at op[0] */ + goto XMPY; /* process as XMPY */ + +case 004: /* .XDIV 105204 (OP_AXX) */ + i = 0; /* params start at op[0] */ + goto XDIV; /* process as XDIV */ + +#endif + +case 005: /* .DFER 105205 (OP_AA) */ + BR = op[0]; /* get destination address */ + AR = op[1]; /* get source address */ + goto XFER; /* do transfer */ + +#if defined (HAVE_INT64) + +case 006: /* .XPAK 105206 (OP_A) */ + if (UNIT_CPU_TYPE != UNIT_TYPE_21MX) /* must be 21MX */ + return stop_inst; /* trap if not */ + if (intrq) { /* interrupt pending? */ + PC = err_PC; /* restart instruction */ + break; } + xop = ReadX (op[0]); /* read unpacked */ + O = x_pak (&xop, xop, SEXT (AR)); /* pack mantissa, exponent */ + WriteX (op[0], xop); /* write back */ + break; + +case 007: /* XADD 105207 (OP_AAXX) */ + i = 1; /* params start at op[1] */ +XADD: /* enter here from .XADD */ + if (intrq) { /* interrupt pending? */ + PC = err_PC; /* restart instruction */ + break; } + O = x_add (&xop, AS_XPN (op [i + 1]), AS_XPN (op [i + 3])); /* add ops */ + WriteX (op[i], xop); /* write sum */ + break; + +case 010: /* XSUB 105210 (OP_AAXX) */ + i = 1; /* params start at op[1] */ +XSUB: /* enter here from .XSUB */ + if (intrq) { /* interrupt pending? */ + PC = err_PC; /* restart instruction */ + break; } + O = x_sub (&xop, AS_XPN (op [i + 1]), AS_XPN (op [i + 3])); /* subtract */ + WriteX (op[i], xop); /* write difference */ + break; + +case 011: /* XMPY 105211 (OP_AAXX) */ + i = 1; /* params start at op[1] */ +XMPY: /* enter here from .XMPY */ + if (intrq) { /* interrupt pending? */ + PC = err_PC; /* restart instruction */ + break; } + O = x_mpy (&xop, AS_XPN (op [i + 1]), AS_XPN (op [i + 3])); /* multiply */ + WriteX (op[i], xop); /* write product */ + break; + +case 012: /* XDIV 105212 (OP_AAXX) */ + i = 1; /* params start at op[1] */ +XDIV: /* enter here from .XDIV */ + if (intrq) { /* interrupt pending? */ + PC = err_PC; /* restart instruction */ + break; } + O = x_div (&xop, AS_XPN (op [i + 1]), AS_XPN (op [i + 3])); /* divide */ + WriteX (op[i], xop); /* write quotient */ + break; + +case 013: /* .XADD 105213 (OP_AXX) */ + i = 0; /* params start at op[0] */ + goto XADD; /* process as XADD */ + +case 014: /* .XSUB 105214 (OP_AXX) */ + i = 0; /* params start at op[0] */ + goto XSUB; /* process as XSUB */ + +case 015: /* .XCOM 105215 (OP_A) */ + if (UNIT_CPU_TYPE != UNIT_TYPE_21MX) /* must be 21MX */ + return stop_inst; /* trap if not */ + xop = ReadX (op[0]); /* read operand */ + AR = x_com (&xop); /* neg and rtn exp adj */ + WriteX (op[0], xop); /* write result */ + break; + +case 016: /* ..DCM 105216 (OP_A) */ + if (UNIT_CPU_TYPE != UNIT_TYPE_21MX) /* must be 21MX */ + return stop_inst; /* trap if not */ + if (intrq) { /* interrupt pending? */ + PC = err_PC; /* restart instruction */ + break; } + xop = ReadX (op[0]); /* read operand */ + O = x_dcm (&xop); /* negate */ + WriteX (op[0], xop); /* write result */ + break; + +case 017: /* DDINT 105217 (OP_AAX) */ + if (UNIT_CPU_TYPE != UNIT_TYPE_21MX) /* must be 21MX */ + return stop_inst; /* trap if not */ + if (intrq) { /* interrupt pending? */ + PC = err_PC; /* restart instruction */ + break; } + x_trun (&xop, AS_XPN (op [2])); /* truncate operand */ + WriteX (op[1], xop); /* write result */ + break; + +#endif + +/* FFP module 2 */ + +case 020: /* .XFER 105220 (OP_N) */ + if (UNIT_CPU_TYPE == UNIT_TYPE_2100) + PC = (PC + 1) & VAMASK; /* 2100 .XFER returns to P+2 */ +XFER: /* enter here from .DFER */ + sc = 3; /* set count for 3-wd xfer */ + goto CFER; /* do transfer */ + +case 021: /* .GOTO 105221 (OP_AK) */ + if ((op[1] == 0) || (op[1] & SIGN)) /* index < 1? */ + op[1] = 1; /* reset min */ + sa = PC + op[1] - 1; /* point to jump target */ + if (sa >= op[0]) /* must be <= last target */ + sa = op[0] - 1; + da = ReadW (sa); /* get jump target */ + if (reason = resolve (da, &MA, intrq)) { /* resolve indirects */ + PC = err_PC; /* irq restarts instruction */ + break; } + mp_dms_jmp (MA); /* validate jump addr */ + PCQ_ENTRY; /* record last PC */ + PC = MA; /* jump */ + BR = op[0]; /* (for 2100 FFP compat) */ + break; + +case 022: /* ..MAP 105222 (OP_KKKK) */ + op[1] = op[1] - 1; /* decrement 1st subscr */ + if ((AR & 1) == 0) /* 2-dim access? */ + op[1] = op[1] + (op[2] - 1) * op[3]; /* compute element offset */ + else { /* 3-dim access */ + if (reason = get_ops (OP_KK, op2, intrq)) { /* get 1st, 2nd ranges */ + PC = err_PC; /* irq restarts instruction */ + break; } + op[1] = op[1] + ((op[3] - 1) * op2[1] + op[2] - 1) * op2[0]; } /* offset */ + AR = (op[0] + op[1] * BR) & DMASK; /* return element address */ + break; + +case 023: /* .ENTR 105223 (OP_A) */ + MA = PC - 3; /* get addr of entry point */ +ENTR: /* enter here from .ENTP */ + da = op[0]; /* get addr of 1st formal */ + dc = MA - da; /* get count of formals */ + sa = ReadW (MA); /* get addr of return point */ + ra = ReadW (sa++); /* get rtn, ptr to 1st actual */ + WriteW (MA, ra); /* stuff rtn into caller's ent */ + sc = ra - sa; /* get count of actuals */ + if (sc > dc) sc = dc; /* use min (actuals, formals) */ + for (j = 0; j < sc; j++) { + MA = ReadW (sa++); /* get addr of actual */ + if (reason = resolve (MA, &MA, intrq)) { /* resolve indirect */ + PC = err_PC; /* irq restarts instruction */ + break; } + WriteW (da++, MA); } /* put addr into formal */ + AR = ra; /* return address */ + BR = da; /* addr of 1st unused formal */ + break; + +case 024: /* .ENTP 105224 (OP_A) */ + MA = PC - 5; /* get addr of entry point */ + goto ENTR; + +case 025: /* .PWR2 105225 (OP_K) */ + if (UNIT_CPU_TYPE != UNIT_TYPE_21MX) /* must be 21MX */ + return stop_inst; /* trap if not */ + f_pwr2 (SEXT (op[0])); /* calc result into A/B */ + break; + +case 026: /* .FLUN 105226 (OP_N) */ + if (UNIT_CPU_TYPE != UNIT_TYPE_21MX) /* must be 21MX */ + return stop_inst; /* trap if not */ + f_unpack (); /* unpack into A/B */ + break; + +case 027: /* $SETP 105227 (OP_K) */ + j = sa = AR; /* save initial value */ + sb = BR; /* save initial address */ + AR = 0; /* AR will return = 0 */ + BR = BR & VAMASK; /* addr must be direct */ + do { + WriteW (BR, j); /* write value to address */ + j = (j + 1) & DMASK; /* incr value */ + BR = (BR + 1) & VAMASK; /* incr address */ + op[0] = op[0] - 1; /* decr count */ + if (op[0] && intrq) { /* more and intr? */ + AR = sa; /* restore A */ + BR = sb; /* restore B */ + PC = err_PC; /* restart instruction */ + break; } } + while (op[0] != 0); /* loop until count exhausted */ + break; + +case 030: /* .PACK 105230 (OP_C) */ + if (UNIT_CPU_TYPE != UNIT_TYPE_21MX) /* must be 21MX */ + return stop_inst; /* trap if not */ + O = f_pack (SEXT (op[0])); /* calc A/B and overflow */ + break; + +case 031: /* .CFER 105231 (OP_AA) */ + if (UNIT_CPU_MODEL != UNIT_21MX_E) /* must be 21MX E-series */ + return stop_inst; /* trap if not */ + BR = op[0]; /* get destination address */ + AR = op[1]; /* get source address */ + sc = 4; /* set for 4-wd xfer */ +CFER: /* enter here from .XFER */ + for (j = 0; j < sc; j++) { /* xfer loop */ + WriteW (BR, ReadW (AR)); /* transfer word */ + AR = (AR + 1) & VAMASK; /* bump source addr */ + BR = (BR + 1) & VAMASK; } /* bump destination addr */ + E = 0; /* routine clears E */ + if (UNIT_CPU_TYPE == UNIT_TYPE_2100) { /* 2100 (and .DFER/.XFER)? */ + AR = (AR + 1) & VAMASK; /* 2100 FFP returns X+4, Y+4 */ + BR = (BR + 1) & VAMASK; } + break; + +default: /* others undefined */ + reason = stop_inst; } + +return reason; +} + +/* 2000 I/O Processor + + The IOP accelerates certain operations of the HP 2000 Time-Share BASIC system + I/O processor. Most 2000 systems were delivered with 2100 CPUs, although IOP + microcode was developed for the 21MX-M and 21MX-E. As the I/O processors + were specific to the 2000 system, general compatibility with other CPU + microcode options was unnecessary, and indeed no other options were possible + for the 2100. + + Option implementation by CPU was as follows: + + 2116 2100 21MX-M 21MX-E 21MX-F + ------ ------ ------ ------ ------ + N/A 13206A 13207A 22702A N/A + + The routines are mapped to instruction codes as follows: + + Instr. 2100 21MX-M/E Description + ------ ---------- ---------- -------------------------------------------- + SAI 105060-117 101400-037 Store A indexed by B (+/- offset in IR<4:0>) + LAI 105020-057 105400-037 Load A indexed by B (+/- offset in IR<4:0>) + CRC 105150 105460 Generate CRC + REST 105340 105461 Restore registers from stack + READF 105220 105462 Read F register (stack pointer) + INS -- 105463 Initialize F register (stack pointer) + ENQ 105240 105464 Enqueue + PENQ 105257 105465 Priority enqueue + DEQ 105260 105466 Dequeue + TRSLT 105160 105467 Translate character + ILIST 105000 105470 Indirect address list (similar to $SETP) + PRFEI 105222 105471 Power fail exit with I/O + PRFEX 105223 105472 Power fail exit + PRFIO 105221 105473 Power fail I/O + SAVE 105362 105474 Save registers to stack + + MBYTE 105120 105765 Move bytes (MBT) + MWORD 105200 105777 Move words (MVW) + SBYTE 105300 105764 Store byte (SBT) + LBYTE 105320 105763 Load byte (LBT) + + The INS instruction was not required in the 2100 implementation because the + stack pointer was actually the memory protect fence register and so could be + loaded directly with an OTA/B 05. Also, the 21MX implementation did not + offer the MBYTE, MWORD, SBYTE, and LBYTE instructions because the equivalent + instructions from the standard Extended Instruction Group were used instead. + + Additional reference: + - HP 2000 Computer System Sources and Listings Documentation + (22687-90020, undated), section 3, pages 2-74 through 2-91. +*/ + +static const OP_PAT op_iop[16] = { + OP_V, OP_N, OP_N, OP_N, /* CRC RESTR READF INS */ + OP_N, OP_N, OP_N, OP_V, /* ENQ PENQ DEQ TRSLT */ + OP_AC, OP_CVA, OP_A, OP_CV, /* ILIST PRFEI PRFEX PRFIO */ + OP_N, OP_N, OP_N, OP_N }; /* SAVE --- --- --- */ + +static t_stat cpu_iop (uint32 IR, uint32 intrq) +{ +t_stat reason = SCPE_OK; +OPS op; +uint32 entry; +uint32 hp, tp, i, t, wc, MA; + +if ((cpu_unit.flags & UNIT_IOP) == 0) /* IOP option installed? */ + return stop_inst; + +entry = IR & 077; /* mask to entry point */ + +if (entry <= 037) { /* LAI/SAI 10x400-437 */ + MA = ((entry - 020) + BR) & VAMASK; /* +/- offset */ + if (IR & I_AB) AR = ReadW (MA); /* AB = 1 -> LAI */ + else WriteW (MA, AR); /* AB = 0 -> SAI */ + return reason; } +else if (entry <= 057) /* IR = 10x440-457? */ + return stop_inst; /* not part of IOP */ + +entry = entry - 060; /* offset 10x460-477 */ + +if (op_iop[entry] != OP_N) + if (reason = get_ops (op_iop[entry], op, intrq))/* get instruction operands */ + return reason; + +switch (entry) { /* decode IR<5:0> */ + +case 000: /* CRC 105460 (OP_V) */ + t = ReadW (op[0]) ^ (AR & 0377); /* xor prev CRC and char */ + 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 (op[0], t); /* rewrite CRC */ + break; + +case 001: /* RESTR 105461 (OP_N) */ + iop_sp = (iop_sp - 1) & VAMASK; /* decr stack ptr */ + t = ReadW (iop_sp); /* get E and O */ + O = ((t >> 1) ^ 1) & 1; /* restore O */ + E = t & 1; /* restore E */ + iop_sp = (iop_sp - 1) & VAMASK; /* decr sp */ + BR = ReadW (iop_sp); /* restore B */ + iop_sp = (iop_sp - 1) & VAMASK; /* decr sp */ + AR = ReadW (iop_sp); /* restore A */ + if (UNIT_CPU_MODEL == UNIT_2100) + mp_fence = iop_sp; /* 2100 keeps sp in MP FR */ + break; + +case 002: /* READF 105462 (OP_N) */ + AR = iop_sp; /* copy stk ptr */ + break; + +case 003: /* INS 105463 (OP_N) */ + iop_sp = AR; /* init stk ptr */ + break; + +case 004: /* ENQ 105464 (OP_N) */ + 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 005: /* PENQ 105465 (OP_N) */ + 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 006: /* DEQ 105466 (OP_N) */ + 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 007: /* TRSLT 105467 (OP_V) */ + wc = ReadW (op[0]); /* get count */ + 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 (op[0], wc); /* save count */ + PC = err_PC; /* stop for now */ + break; } } + break; + +case 010: /* ILIST 105470 (OP_AC) */ + do { /* for count */ + WriteW (op[0], AR); /* write AR to mem */ + AR = (AR + 1) & DMASK; /* incr AR */ + op[0] = (op[0] + 1) & VAMASK; /* incr MA */ + op[1] = (op[1] - 1) & DMASK; } /* decr count */ + while (op[1] != 0); + break; + +case 011: /* PRFEI 105471 (OP_CVA) */ + WriteW (op[1], 1); /* set flag */ + reason = iogrp (op[0], 0); /* execute I/O instr */ + op[0] = op[2]; /* set rtn and fall through */ + +case 012: /* PRFEX 105472 (OP_A) */ + PCQ_ENTRY; + PC = ReadW (op[0]) & VAMASK; /* jump indirect */ + WriteW (op[0], 0); /* clear exit */ + break; + +case 013: /* PRFIO 105473 (OP_CV) */ + WriteW (op[1], 1); /* set flag */ + reason = iogrp (op[0], 0); /* execute instr */ + break; + +case 014: /* SAVE 105474 (OP_N) */ + WriteW (iop_sp, AR); /* save A */ + iop_sp = (iop_sp + 1) & VAMASK; /* incr stack ptr */ + WriteW (iop_sp, BR); /* save B */ + iop_sp = (iop_sp + 1) & VAMASK; /* incr stack ptr */ + t = ((O ^ 1) << 1) | E; /* merge E and O */ + WriteW (iop_sp, t); /* save E and O */ + iop_sp = (iop_sp + 1) & VAMASK; /* incr stack ptr */ + if (UNIT_CPU_TYPE == UNIT_TYPE_2100) + mp_fence = iop_sp; /* 2100 keeps sp in MP FR */ + break; + +default: /* instruction undefined */ + return stop_inst; + } + +return reason; +} + +/* Dynamic Mapping System + + The 21MX Dynamic Mapping System (DMS) consisted of the 12731A Memory + Expansion Module (MEM) card and 38 instructions to expand the basic 32K + logical address space to a 1024K physical space. The MEM provided four maps + of 32 mapping registers each: a system map, a user map, and two DCPC maps. + DMS worked in conjunction with memory protect to provide a "protected mode" + in which memory read and write violations could be trapped, and that + inhibited "privileged" instruction execution that attempted to alter the + memory mapping. + + Option implementation by CPU was as follows: + + 2116 2100 21MX-M 21MX-E 21MX-F + ------ ------ ------ ------ ------ + N/A N/A 12976B 13307B std + + The instruction codes are mapped to routines as follows: + + Instr. 21MX-M 21MX-E/F Instr. 21MX-M 21MX-E/F + ------ ------ -------- ------ ------ -------- + 10x700 [xmm] [xmm] 10x720 XMM XMM + 10x701 [nop] [test] 10x721 XMS XMS + 10x702 MBI MBI 10x722 XM* XM* + 10x703 MBF MBF 10x723 [nop] [nop] + 10x704 MBW MBW 10x724 XL* XL* + 10x705 MWI MWI 10x725 XS* XS* + 10x706 MWF MWF 10x726 XC* XC* + 10x707 MWW MWW 10x727 LF* LF* + 10x710 SY* SY* 10x730 RS* RS* + + 10x711 US* US* 10x731 RV* RV* + 10x712 PA* PA* 10x732 DJP DJP + 10x713 PB* PB* 10x733 DJS DJS + 10x714 SSM SSM 10x734 SJP SJP + 10x715 JRS JRS 10x735 SJS SJS + 10x716 [nop] [nop] 10x736 UJP UJP + 10x717 [nop] [nop] 10x737 UJS UJS + + Instructions that use IR bit 9 to select the A or B register are designated + with a * above (e.g., 101710 is SYA, and 105710 is SYB). For those that do + not use this feature, either the 101xxx or 105xxx code will execute the + corresponding instruction, although the 105xxx form is the documented + instruction code. + + Notes: + + 1. Instruction code 10x700 will execute the XMM instruction, although + 10x720 is the documented instruction value. + + 2. The DMS privilege violation rules are: + - load map and CTL5 set (XMM, XMS, XM*, SY*, US*, PA*, PB*) + - load state or fence and UMAP set (JRS, DJP, DJS, SJP, SJS, UJP, UJS, LF*) + + 3. The 21MX manual is incorrect in stating that M*I, M*W, XS* are + privileged. +*/ + +static const OP_PAT op_dms[32] = { + OP_N, OP_N, OP_N, OP_N, /* xmm test MBI MBF */ + OP_N, OP_N, OP_N, OP_N, /* MBW MWI MWF MWW */ + OP_N, OP_N, OP_N, OP_N, /* SYA/B USA/B PAA/B PBA/B */ + OP_A, OP_KA, OP_N, OP_N, /* SSM JRS nop nop */ + OP_N, OP_N, OP_N, OP_N, /* XMM XMS XMA/B nop */ + OP_A, OP_A, OP_A, OP_N, /* XLA/B XSA/B XCA/B LFA/B */ + OP_N, OP_N, OP_A, OP_A, /* RSA/B RVA/B DJP DJS */ + OP_A, OP_A, OP_A, OP_A }; /* SJP SJS UJP UJS */ + +static t_stat cpu_dms (uint32 IR, uint32 intrq) +{ +t_stat reason = SCPE_OK; +OPS op; +uint32 entry, absel; +uint32 i, t, mapi, mapj; + +if ((cpu_unit.flags & UNIT_DMS) == 0) /* DMS option installed? */ + return stop_inst; 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; } +entry = IR & 037; /* mask to entry point */ -switch (eop) { /* decode IR<8:0> */ - -/* Floating point instructions */ +if (op_dms[entry] != OP_N) + if (reason = get_ops (op_dms[entry], op, intrq))/* get instruction operands */ + return reason; - 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 */ +switch (entry) { /* decode IR<3:0> */ - 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; +/* DMS module 1 */ - 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 +case 000: /* [undefined] 105700 (OP_N) */ + goto XMM; /* decodes as XMM */ - 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 001: /* [self test] 105701 (OP_N) */ + ABREG[absel] = ABREG[absel] ^ DMASK; /* CMA or CMB */ + break; - 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 002: /* MBI 105702 (OP_N) */ + 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 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 003: /* MBF 105703 (OP_N) */ + 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 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; +case 004: /* MBW 105704 (OP_N) */ + 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 005: /* MWI 105705 (OP_N) */ + 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 006: /* MWF 105706 (OP_N) */ + 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 007: /* MWW 105707 (OP_N) */ + 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; + +case 010: /* SYA, SYB 10x710 (OP_N) */ +case 011: /* USA, USB 10x711 (OP_N) */ +case 012: /* PAA, PAB 10x712 (OP_N) */ +case 013: /* PBA, PBB 10x713 (OP_N) */ + 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); /* 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 */ + 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 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 014: /* SSM 105714 (OP_A) */ + WriteW (op[0], dms_upd_sr ()); /* store stat */ + break; - 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; +case 015: /* JRS 105715 (OP_KA) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + dms_enb = 0; /* assume off */ + dms_ump = SMAP; + if (op[0] & 0100000) { /* set enable? */ + dms_enb = 1; + if (op[0] & 0040000) dms_ump = UMAP; } /* set/clr usr */ + mp_dms_jmp (op[1]); /* mpck jmp target */ + PCQ_ENTRY; /* save old PC */ + PC = op[1]; /* jump */ + ion_defer = 1; /* defer intr */ + break; -/* Byte instructions */ +/* DMS module 2 */ - 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 */ +case 020: /* XMM 105720 (OP_N) */ +XMM: + if (XR == 0) break; /* nop? */ + while (XR != 0) { /* loop */ + if (XR & SIGN) { /* store? */ + t = dms_rmap (AR); /* map to mem */ 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 */ + XR = (XR + 1) & DMASK; } + else { /* load */ + dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + 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 & 017) == 017)) { /* intr, grp of 16? */ + PC = err_PC; /* stop for now */ + break; } } + break; + +case 021: /* XMS 105721 (OP_N) */ + if ((XR & SIGN) || (XR == 0)) break; /* nop? */ + dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + 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 & 017) == 017)) { /* intr, grp of 16? */ + PC = err_PC; + break; } } + break; + +case 022: /* XMA, XMB 10x722 (OP_N) */ + dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + 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 024: /* XLA, XLB 10x724 (OP_A) */ + ABREG[absel] = ReadWA (op[0]); /* load alt */ + break; + +case 025: /* XSA, XSB 10x725 (OP_A) */ + WriteWA (op[0], ABREG[absel]); /* store alt */ + break; + +case 026: /* XCA, XCB 10x726 (OP_A) */ + if (ABREG[absel] != ReadWA (op[0])) /* compare alt */ + PC = (PC + 1) & VAMASK; + break; + +case 027: /* LFA, LFB 10x727 (OP_N) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + dms_sr = (dms_sr & ~(MST_FLT | MST_FENCE)) | + (ABREG[absel] & (MST_FLT | MST_FENCE)); + break; + +case 030: /* RSA, RSB 10x730 (OP_N) */ + ABREG[absel] = dms_upd_sr (); /* save stat */ + break; + +case 031: /* RVA, RVB 10x731 (OP_N) */ + ABREG[absel] = dms_vr; /* save viol */ + break; + +case 032: /* DJP 105732 (OP_A) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + mp_dms_jmp (op[0]); /* validate jump addr */ + PCQ_ENTRY; /* save curr PC */ + PC = op[0]; /* new PC */ + dms_enb = 0; /* disable map */ + dms_ump = SMAP; + ion_defer = 1; + break; + +case 033: /* DJS 105733 (OP_A) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + WriteW (op[0], PC); /* store ret addr */ + PCQ_ENTRY; /* save curr PC */ + PC = (op[0] + 1) & VAMASK; /* new PC */ + dms_enb = 0; /* disable map */ + dms_ump = SMAP; + ion_defer = 1; /* defer intr */ + break; + +case 034: /* SJP 105734 (OP_A) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + mp_dms_jmp (op[0]); /* validate jump addr */ + PCQ_ENTRY; /* save curr PC */ + PC = op[0]; /* jump */ + dms_enb = 1; /* enable system */ + dms_ump = SMAP; + ion_defer = 1; /* defer intr */ + break; + +case 035: /* SJS 105735 (OP_A) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + t = PC; /* save retn addr */ + PCQ_ENTRY; /* save curr PC */ + PC = (op[0] + 1) & VAMASK; /* new PC */ + dms_enb = 1; /* enable system */ + dms_ump = SMAP; + WriteW (op[0], t); /* store ret addr */ + ion_defer = 1; /* defer intr */ + break; + +case 036: /* UJP 105736 (OP_A) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + mp_dms_jmp (op[0]); /* validate jump addr */ + PCQ_ENTRY; /* save curr PC */ + PC = op[0]; /* jump */ + dms_enb = 1; /* enable user */ + dms_ump = UMAP; + ion_defer = 1; /* defer intr */ + break; + +case 037: /* UJS 105737 (OP_A) */ + if (dms_ump) dms_viol (err_PC, MVI_PRV); /* priv viol if prot */ + t = PC; /* save retn addr */ + PCQ_ENTRY; /* save curr PC */ + PC = (op[0] + 1) & VAMASK; /* new PC */ + dms_enb = 1; /* enable user */ + dms_ump = UMAP; + WriteW (op[0], t); /* store ret addr */ + ion_defer = 1; /* defer intr */ + break; + +default: /* others NOP */ + break; } + +return reason; +} + +/* Extended Instruction Group + + The Extended Instruction Group (EIG) adds 32 index and 10 bit/byte/word + manipulation instructions to the 21MX base set. These instructions + use the new X and Y index registers that were added to the 21MX. + + Option implementation by CPU was as follows: + + 2116 2100 21MX-M 21MX-E 21MX-F + ------ ------ ------ ------ ------ + N/A N/A std std std + + The instruction codes are mapped to routines as follows: + + Instr. 21MX-M/E/F Instr. 21MX-M/E/F + ------ ---------- ------ ---------- + 10x740 S*X 10x760 ISX + 10x741 C*X 10x761 DSX + 10x742 L*X 10x762 JLY + 10x743 STX 10x763 LBT + 10x744 CX* 10x764 SBT + 10x745 LDX 10x765 MBT + 10x746 ADX 10x766 CBT + 10x747 X*X 10x767 SFB + + 10x750 S*Y 10x770 ISY + 10x751 C*Y 10x771 DSY + 10x752 L*Y 10x772 JPY + 10x753 STY 10x773 SBS + 10x754 CY* 10x774 CBS + 10x755 LDY 10x775 TBS + 10x756 ADY 10x776 CMW + 10x757 X*Y 10x777 MVW + + Instructions that use IR bit 9 to select the A or B register are designated + with a * above (e.g., 101740 is SAX, and 105740 is SBX). For those that do + not use this feature, either the 101xxx or 105xxx code will execute the + corresponding instruction, although the 105xxx form is the documented + instruction code. + + Notes: + + 1. The LBT, SBT, MBT, and MVW instructions are used as part of the 2100 IOP + implementation. When so called, the MBT and MVW instructions have the + additional restriction that the count must be positive. +*/ + +static const OP_PAT op_eig[32] = { + OP_A, OP_N, OP_A, OP_A, /* S*X C*X L*X STX */ + OP_N, OP_K, OP_K, OP_N, /* CX* LDX ADX X*X */ + OP_A, OP_N, OP_A, OP_A, /* S*Y C*Y L*Y STY */ + OP_N, OP_K, OP_K, OP_N, /* CY* LDY ADY X*Y */ + OP_N, OP_N, OP_A, OP_N, /* ISX DSX JLY LBT */ + OP_N, OP_KV, OP_KV, OP_N, /* SBT MBT CBT SFB */ + OP_N, OP_N, OP_C, OP_KA, /* ISY DSY JPY SBS */ + OP_KA, OP_KK, OP_KV, OP_KV }; /* CBS TBS CMW MVW */ + +static t_stat cpu_eig (uint32 IR, uint32 intrq) +{ +t_stat reason = SCPE_OK; +OPS op; +uint32 entry, absel; +uint32 t, v1, v2, wc; +int32 sop1, sop2; + +absel = (IR & I_AB)? 1: 0; /* get A/B select */ +entry = IR & 037; /* mask to entry point */ + +if (op_eig[entry] != OP_N) + if (reason = get_ops (op_eig[entry], op, intrq))/* get instruction operands */ + return reason; + +switch (entry) { /* decode IR<4:0> */ + +/* EIG module 1 */ + +case 000: /* SAX, SBX 10x740 (OP_A) */ + op[0] = (op[0] + XR) & VAMASK; /* indexed addr */ + WriteW (op[0], ABREG[absel]); /* store */ + break; + +case 001: /* CAX, CBX 10x741 (OP_N) */ + XR = ABREG[absel]; /* copy to XR */ + break; + +case 002: /* LAX, LBX 10x742 (OP_A) */ + op[0] = (op[0] + XR) & VAMASK; /* indexed addr */ + ABREG[absel] = ReadW (op[0]); /* load */ + break; + +case 003: /* STX 105743 (OP_A) */ + WriteW (op[0], XR); /* store XR */ + break; + +case 004: /* CXA, CXB 10x744 (OP_N) */ + ABREG[absel] = XR; /* copy from XR */ + break; + +case 005: /* LDX 105745 (OP_K)*/ + XR = op[0]; /* load XR */ + break; + +case 006: /* ADX 105746 (OP_K) */ + t = XR + op[0]; /* add to XR */ + if (t > DMASK) E = 1; /* set E, O */ + if (((~XR ^ op[0]) & (XR ^ t)) & SIGN) O = 1; + XR = t & DMASK; + break; + +case 007: /* XAX, XBX 10x747 (OP_N) */ + t = XR; /* exchange XR */ + XR = ABREG[absel]; + ABREG[absel] = t; + break; + +case 010: /* SAY, SBY 10x750 (OP_A) */ + op[0] = (op[0] + YR) & VAMASK; /* indexed addr */ + WriteW (op[0], ABREG[absel]); /* store */ + break; + +case 011: /* CAY, CBY 10x751 (OP_N) */ + YR = ABREG[absel]; /* copy to YR */ + break; + +case 012: /* LAY, LBY 10x752 (OP_A) */ + op[0] = (op[0] + YR) & VAMASK; /* indexed addr */ + ABREG[absel] = ReadW (op[0]); /* load */ + break; + +case 013: /* STY 105753 (OP_A) */ + WriteW (op[0], YR); /* store YR */ + break; + +case 014: /* CYA, CYB 10x754 (OP_N) */ + ABREG[absel] = YR; /* copy from YR */ + break; + +case 015: /* LDY 105755 (OP_K) */ + YR = op[0]; /* load YR */ + break; + +case 016: /* ADY 105756 (OP_K) */ + t = YR + op[0]; /* add to YR */ + if (t > DMASK) E = 1; /* set E, O */ + if (((~YR ^ op[0]) & (YR ^ t)) & SIGN) O = 1; + YR = t & DMASK; + break; + +case 017: /* XAY, XBY 10x757 (OP_N) */ + t = YR; /* exchange YR */ + YR = ABREG[absel]; + ABREG[absel] = t; + break; + +/* EIG module 2 */ + +case 020: /* ISX 105760 (OP_N) */ + XR = (XR + 1) & DMASK; /* incr XR */ + if (XR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ + break; + +case 021: /* DSX 105761 (OP_N) */ + XR = (XR - 1) & DMASK; /* decr XR */ + if (XR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ + break; + +case 022: /* JLY 105762 (OP_A) */ + mp_dms_jmp (op[0]); /* validate jump addr */ + PCQ_ENTRY; + YR = PC; /* ret addr to YR */ + PC = op[0]; /* jump */ + break; + +case 023: /* LBT 105763 (OP_N) */ + AR = ReadB (BR); /* load byte */ + BR = (BR + 1) & DMASK; /* incr ptr */ + break; + +case 024: /* SBT 105764 (OP_N) */ + WriteB (BR, AR); /* store byte */ + BR = (BR + 1) & DMASK; /* incr ptr */ + break; + +case 025: /* MBT 105765 (OP_KV) */ + wc = ReadW (op[1]); /* get continuation count */ + if (wc == 0) wc = op[0]; /* none? get initiation count */ + if ((wc & SIGN) && (UNIT_CPU_TYPE == UNIT_TYPE_2100)) + break; /* < 0 is NOP for 2100 IOP */ + while (wc != 0) { /* while count */ + WriteW (op[1], wc); /* for MP 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 (op[1], wc); /* clean up inline */ + break; + +case 026: /* CBT 105766 (OP_KV) */ + wc = ReadW (op[1]); /* get continuation count */ + if (wc == 0) wc = op[0]; /* none? get initiation count */ + while (wc != 0) { /* while count */ + WriteW (op[1], wc); /* for MP 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 (op[1], wc); /* clean up inline */ + break; + +case 027: /* SFB 105767 (OP_N) */ + 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; + +case 030: /* ISY 105770 (OP_N) */ + YR = (YR + 1) & DMASK; /* incr YR */ + if (YR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ + break; + +case 031: /* DSY 105771 (OP_N) */ + YR = (YR - 1) & DMASK; /* decr YR */ + if (YR == 0) PC = (PC + 1) & VAMASK; /* skip if zero */ + break; + +case 032: /* JPY 105772 (OP_C) */ + op[0] = (op[0] + YR) & VAMASK; /* index, no indir */ + mp_dms_jmp (op[0]); /* validate jump addr */ + PCQ_ENTRY; + PC = op[0]; /* jump */ + break; + +case 033: /* SBS 105773 (OP_KA) */ + WriteW (op[1], ReadW (op[1]) | op[0]); /* set bits */ + break; + +case 034: /* CBS 105774 (OP_KA) */ + WriteW (op[1], ReadW (op[1]) & ~op[0]); /* clear bits */ + break; + +case 035: /* TBS 105775 (OP_KK) */ + if ((op[1] & op[0]) != op[0]) /* test bits */ + PC = (PC + 1) & VAMASK; + break; + +case 036: /* CMW 105776 (OP_KV) */ + wc = ReadW (op[1]); /* get continuation count */ + if (wc == 0) wc = op[0]; /* none? get initiation count */ + while (wc != 0) { /* while count */ + WriteW (op[1], 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 (op[1], wc); /* clean up inline */ + break; + +case 037: /* MVW 105777 (OP_KV) */ + wc = ReadW (op[1]); /* get continuation count */ + if (wc == 0) wc = op[0]; /* none? get initiation count */ + if ((wc & SIGN) && (UNIT_CPU_TYPE == UNIT_TYPE_2100)) + break; /* < 0 is NOP for 2100 IOP */ + while (wc != 0) { /* while count */ + WriteW (op[1], 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 (op[1], wc); /* clean up inline */ + break; + +default: /* all others NOP */ + break; } + +return reason; +} + +/* Get instruction operands + + Operands for a given instruction are specifed by an "operand pattern" + consisting of flags indicating the types and storage methods. The pattern + directs how each operand is to be retrieved and whether the operand value or + address is returned in the operand array. + + Eight operand encodings are defined: + + Code Operand Description Example Return + ------ ----------------------------- ----------- ------------ + OP_NUL No operand present [inst] None + + OP_CON Inline constant [inst] Value of C + C DEC 0 + + OP_VAR Inline variable [inst] Address of V + V BSS 1 + + OP_ADR Address [inst] Address of A + DEF A + ... + A EQU * + + OP_ADK Address of a 1-word constant [instr] Value of K + DEF K + ... + K DEC 0 + + OP_ADF Address of a 2-word constant [inst] Value of F + DEF F + ... + F DEC 0.0 + + OP_ADX Address of a 3-word constant [inst] Value of X + DEF X + ... + X DEX 0.0 + + OP_ADT Address of a 4-word constant [inst] Value of T + DEF T + ... + T DEY 0.0 + + Address operands, i.e., those having a DEF to the operand, will be resolved + to direct addresses. If an interrupt is pending and more than three levels + of indirection are used, the routine returns without completing operand + retrieval (the instruction will be retried after interrupt servicing). + Addresses are always resolved in the current DMS map. + + An operand pattern consists of one or more operand encodings, corresponding + to the operands required by a given instruction. Values are returned in + sequence to the operand array. Addresses and one-word values are returned in + the lower half of the 32-bit array element. Two-word values are packed into + one array element, with the first word in the upper 16 bits. Three- and + four-word values are packed into two consecutive elements, with the last word + of a three-word value in the upper 16 bits of of the second element. + + IMPLEMENTATION NOTE: OP_ADT is not currently supported. +*/ + +static t_stat get_ops (OP_PAT pattern, OPS op, uint32 irq) +{ +t_stat reason = SCPE_OK; +OP_PAT flags; +uint32 i, MA; +XPN xop; + +for (i = 0; i < OP_N_F; i++) { + flags = pattern & OP_M_FLAGS; /* get operand pattern */ + + if (flags >= OP_ADR) /* address operand? */ + if (reason = resolve (ReadW (PC), &MA, irq))/* resolve indirects */ + return reason; + + switch (flags) { + case OP_NUL: /* null operand */ + return reason; /* no more, so quit */ + + case OP_CON: /* constant operand */ + *op++ = ReadW (PC); /* get value */ + break; + + case OP_VAR: /* variable operand */ + *op++ = PC; /* get pointer to variable */ + break; + + case OP_ADR: /* address operand */ + *op++ = MA; /* get address */ + break; + + case OP_ADK: /* address of 1-word constant */ + *op++ = ReadW (MA); /* get value */ + break; + + case OP_ADF: /* address of 2-word constant */ + *op++ = ReadF (MA); /* get value */ + break; + + case OP_ADX: /* address of 3-word constant */ + xop = ReadX (MA); + *op++ = xop.high; /* get first two words of value */ + *op++ = xop.low; /* get third word of value */ + break; + + case OP_ADT: /* address of 4-word constant */ + + default: + return SCPE_IERR; /* not implemented */ + } + + PC = (PC + 1) & VAMASK; + pattern = pattern >> OP_N_FLAGS; } /* move next pattern into place */ return reason; } diff --git a/HP2100/hp2100_defs.h b/HP2100/hp2100_defs.h index 64239252..289412cb 100644 --- a/HP2100/hp2100_defs.h +++ b/HP2100/hp2100_defs.h @@ -63,7 +63,7 @@ #define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) #define VA_N_SIZE 15 /* virtual addr size */ #define VASIZE (1 << VA_N_SIZE) -#define VAMASK (VASIZE - 1) /* virt addr mask */ +#define VAMASK 077777 /* virt addr mask */ #define PA_N_SIZE 20 /* phys addr size */ #define PASIZE (1 << PA_N_SIZE) #define PAMASK (PASIZE - 1) /* phys addr mask */ diff --git a/HP2100/hp2100_diag.txt b/HP2100/hp2100_diag.txt index 967ef06d..256eef0d 100644 --- a/HP2100/hp2100_diag.txt +++ b/HP2100/hp2100_diag.txt @@ -1,6 +1,6 @@ SIMH/HP 21XX DIAGNOSTICS PERFORMANCE ==================================== - Last update: 2004-12-29 + Last update: 2005-03-22 The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation. @@ -12,7 +12,7 @@ The test system configuration is the default SIMH configuration with these alterations (except where noted in the individual diagnostic reports): * All I/O devices are enabled. - * The CPU is configured as a 21MX with 128KW of memory. + * The CPU is configured as a 21MX-E with 128KW of memory. Detailed diagnostic configuration, operation, and results are given after the summary table. These may be used to duplicate the diagnostic results. @@ -42,9 +42,9 @@ The results of the diagnostic runs are summarized below: 101011 Extended Instruction Group (Index) 1432 3.2-3 Passed 101112 Extended Instruction Group (Word, Byte) 1728 3.2-3 Passed -101110 2100 Fast FORTRAN Package 1632 - No simulation -101213 M/E-Series Fast FORTRAN Package 1 1822 - No simulation -101115 M/E-Series Fast FORTRAN Package 2 1632 - No simulation +101110 2100 Fast FORTRAN Package 1632 3.4-0 Partial +101213 M/E-Series Fast FORTRAN Package 1 1822 3.4-0 Passed +101114 M/E-Series Fast FORTRAN Package 2 1632 3.4-0 Passed 101121 F-Series FPP/SIS/FFP 1926 - No simulation 102103 Memory Expansion Unit 1830 3.2-3 Passed @@ -492,7 +492,7 @@ TEST RESULT: Passed. DSN 101011 - Extended Instruction Group (Index) ----------------------------------------------- -TESTED DEVICE: CPU (hp2100_cpu.c) +TESTED DEVICE: CPU (hp2100_cpu1.c) CONFIGURATION: sim> deposit S 000000 sim> reset @@ -511,7 +511,7 @@ TEST RESULT: Passed. DSN 101112 - Extended Instruction Group (Word, Byte, Bit) --------------------------------------------------------- -TESTED DEVICE: CPU (hp2100_cpu.c) +TESTED DEVICE: CPU (hp2100_cpu1.c) CONFIGURATION: sim> set LPS diag sim> deposit S 000014 @@ -533,6 +533,148 @@ TEST RESULT: Passed. +-------------------------------------- +DSN 101110 - 2100 Fast FORTRAN Package +-------------------------------------- + +TESTED DEVICE: CPU (hp2100_cpu1.c) + +CONFIGURATION: sim> set CPU 2100 + sim> set CPU 32K + sim> set CPU FFP + + sim> deposit S 000013 + sim> reset + sim> go 100 + + HALT instruction 102074 + + sim> deposit S 000000 + sim> reset + sim> go + +TEST REPORT: START 2100A-S FFP DIAGNOSTIC + H030 .GOTO TEST + H050 .ENTR TEST + H060 .ENTP TEST + H100 .SETP TEST + H110 ..MAP TEST + H120 SNGL TEST + H130 DBLE TEST + H140 .XADD TEST + + TEST 07 + E142 NOT INTERRUPTIBLE + + HALT instruction 106042 + + sim> go + + H150 .XSUB TEST + H160 .XMPY TEST + + TEST 11 + E162 NOT INTERRUPTIBLE + + HALT instruction 106062 + + sim> go + + H200 .XDIV TEST + H210 .DFER TEST + H220 .XFER TEST + PASS 000001 + + HALT instruction 102077 + +TEST RESULT: Partially passed. + +TEST NOTES: Tests 07 and 11 test the interruptibility of the .XADD and .XMPY + instructions. These features are not simulated. + + + +---------------------------------------------- +DSN 101213 - M/E-Series Fast FORTRAN Package 1 +---------------------------------------------- + +TESTED DEVICE: CPU (hp2100_cpu1.c) + +CONFIGURATION: sim> set CPU FFP + sim> set LPS diag + + sim> deposit S 000014 + sim> reset + sim> go 100 + + HALT instruction 102074 + + sim> deposit S 000000 + sim> reset + sim> go + +TEST REPORT: START 21MX FFP DIAGNOSTIC 1 + H110 ..MAP TEST + H120 SNGL TEST + H130 DBLE TEST + H210 .DFER TEST + H220 .XFER TEST + H230 PWR2 TEST + H240 .PACK TEST + H250 FLUN TEST + H260 .XPAK TEST + H300 .XCOM TEST + H310 ..DCM TEST + H320 DDINT TEST + H330 .CFER TEST + PASS 000001 + + HALT instruction 102077 + +TEST RESULT: Passed. + + + +---------------------------------------------- +DSN 101115 - M/E-Series Fast FORTRAN Package 2 +---------------------------------------------- + +TESTED DEVICE: CPU (hp2100_cpu1.c) + +CONFIGURATION: sim> set CPU FFP + sim> set LPS diag + + sim> deposit S 000014 + sim> reset + sim> go 100 + + HALT instruction 102074 + + sim> deposit S 000000 + sim> reset + sim> go + +TEST REPORT: START 21MX FFP DIAGNOSTIC 2 + H030 .GOTO TEST + H050 .ENTR TEST + H060 .ENTP TEST + H100 .SETP TEST + H115 XADD TEST + H125 XSUB TEST + H135 XMPY TEST + H140 .XADD TEST + H150 .XSUB TEST + H160 .XMPY TEST + H200 .XDIV TEST + H215 XDIV TEST + PASS 000001 + + HALT instruction 102077 + +TEST RESULT: Passed. + + + ---------------------------------- DSN 102103 - Memory Expansion Unit ---------------------------------- @@ -933,7 +1075,7 @@ TEST REPORT: H0 7900/7901 CARTRIDGE DISC MEMORY DIAGNOSTIC HALT instruction 102002 - sim> detach DPC0 + sim> set DPC0 unloaded sim> go H40 PROTECT U/D THEN READY UNIT 0 @@ -942,7 +1084,7 @@ TEST REPORT: H0 7900/7901 CARTRIDGE DISC MEMORY DIAGNOSTIC Simulation stopped sim> set DPC0 locked - sim> attach DPC0 scratch.U0.7900.disc + sim> set DPC0 loaded sim> go H41 CLEAR U/D PROTECT,LOAD,PUSH RUN @@ -1113,7 +1255,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN HALT instruction 102002 - sim> set DS0 FORMAT + sim> set DS0 format sim> go H46 READ IN STEP 04 @@ -1142,7 +1284,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN HALT instruction 102002 - sim> set DS0 NOFORMAT + sim> set DS0 noformat sim> go H46 READ IN STEP 07 @@ -1171,7 +1313,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN HALT instruction 102002 - sim> set DS0 FORMAT + sim> set DS0 format sim> go H45 WRITE IN STEP 10 @@ -1189,7 +1331,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN HALT instruction 102002 - sim> detach DS0 + sim> set DS0 unloaded sim> go H107 READY UNIT 0 @@ -1197,21 +1339,21 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN [CTRL+E] Simulation stopped - sim> attach DS0 scratch.U0.7905.disc + sim> set DS0 loaded sim> go H142 PROTECT U/D,PUSH RUN HALT instruction 102002 - sim> set DS0 LOCKED + sim> set DS0 locked sim> go H143 CLEAR U/D PROTECT,PUSH RUN HALT instruction 102002 - sim> set DS0 WRITEENABLED + sim> set DS0 writeenabled sim> go H110 PRESS PRESET(S),PRESS RUN @@ -1323,12 +1465,14 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN sim> go H46 READ IN STEP 43 + E47 DATA WORD 0000 IS 156164 SHOULD BE 144300 + E47 DATA WORD 0001 IS 023302 SHOULD BE 117306 + E47 DATA WORD 0002 IS 114642 SHOULD BE 045322 H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B - E64 STATUS IS 0 0 0 00111 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0 + E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0 SHOULD BE 1 0 0 00000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0 - H137 TERMINATION STATUS IS "CYL CMP ERROR " SHOULD BE "NORMAL COMPLET" - E13 0000 WORDS TRANSFERRED 0128 EXPECTED - START 0016/00/33-LAST 0016/00/33 WORD COUNT 00128,OLD CYL 0016,UNIT 00 + H137 TERMINATION STATUS IS "NORMAL COMPLET" + START 0016/00/33-LAST 0016/00/34 WORD COUNT 00128,OLD CYL 0016,UNIT 00 HALT instruction 102001 @@ -1462,28 +1606,28 @@ TEST REPORT: 7970-13181 DIAG. HALT instruction 106037 - sim> attach MSC0 scratch.U0.7970.tape + sim> set MSC0 online sim> go H137 PUT TAPE UNIT ON-LINE HALT instruction 106037 - sim> attach MSC1 scratch.U1.7970.tape + sim> set MSC1 online sim> go H137 PUT TAPE UNIT ON-LINE HALT instruction 106037 - sim> attach MSC2 scratch.U2.7970.tape + sim> set MSC2 online sim> go H137 PUT TAPE UNIT ON-LINE HALT instruction 106037 - sim> attach MSC3 scratch.U3.7970.tape + sim> set MSC3 online sim> go PASS 000001 @@ -1599,28 +1743,28 @@ TEST REPORT: 7970-13183 DIAG. HALT instruction 106037 - sim> attach MSC0 scratch.U0.7970.tape + sim> set MSC0 online sim> go H137 PUT TAPE UNIT ON-LINE HALT instruction 106037 - sim> attach MSC1 scratch.U1.7970.tape + sim> set MSC1 online sim> go H137 PUT TAPE UNIT ON-LINE HALT instruction 106037 - sim> attach MSC2 scratch.U2.7970.tape + sim> set MSC2 online sim> go H137 PUT TAPE UNIT ON-LINE HALT instruction 106037 - sim> attach MSC3 scratch.U3.7970.tape + sim> set MSC3 online sim> go PASS 000001 @@ -2257,7 +2401,7 @@ TEST REPORT: H0 HP2100A CARTRIDGE DISC MEMORY DIAGNOSTIC HALT instruction 102002 - sim> detach DPC0 + sim> set DPC0 unloaded sim> go H40 READY UNIT 0 @@ -2265,7 +2409,7 @@ TEST REPORT: H0 HP2100A CARTRIDGE DISC MEMORY DIAGNOSTIC [CTRL+E] Simulation stopped - sim> attach DPC0 scratch.U0.2871.disc + sim> set DPC0 loaded sim> go H71 PRESS PRESET THEN PRESS RUN @@ -2446,7 +2590,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN HALT instruction 102002 - sim> detach DQC0 + sim> set DQC0 unloaded sim> go H40 ENABLE UNIT 0 @@ -2454,7 +2598,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN [CTRL+E] Simulation stopped - sim> attach DQC0 scratch.U0.2883.disc + sim> set DQC0 loaded sim> go H71 PRESS PRESET THEN PRESS RUN @@ -2497,7 +2641,7 @@ CONFIGURATION: sim> reset HALT instruction 107001 sim> set DRC 180K - sim> set DRC TRACKPROT=8 + sim> set DRC trackprot=8 sim> attach DRC0 scratch.U0.2770.disc sim> deposit S 002611 sim> go @@ -2516,14 +2660,14 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS HALT instruction 102002 - sim> set DRC UNPROTECTED + sim> set DRC unprotected sim> go H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN HALT instruction 102002 - sim> set DRC PROTECTED + sim> set DRC protected sim> go H14 DEVICE HAS 0032 TRACKS,THE FOLLOWING ARE PROTECTED: @@ -2532,7 +2676,7 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS HALT instruction 102002 - sim> set DRC UNPROTECTED + sim> set DRC unprotected sim> go H36 PASS 0001 @@ -2560,7 +2704,7 @@ CONFIGURATION: sim> reset HALT instruction 107001 sim> set DRC 720K - sim> set DRC TRACKPROT=32 + sim> set DRC trackprot=32 sim> attach DRC0 scratch.U0.2771.disc sim> deposit S 002611 sim> go @@ -2579,14 +2723,14 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS HALT instruction 102002 - sim> set DRC UNPROTECTED + sim> set DRC unprotected sim> go H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN HALT instruction 102002 - sim> set DRC PROTECTED + sim> set DRC protected sim> go H14 DEVICE HAS 0128 TRACKS,THE FOLLOWING ARE PROTECTED: @@ -2595,7 +2739,7 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS HALT instruction 102002 - sim> set DRC UNPROTECTED + sim> set DRC unprotected sim> go H36 PASS 0001 @@ -2623,7 +2767,7 @@ CONFIGURATION: sim> reset HALT instruction 107001 sim> set DRC 384K - sim> set DRC TRACKPROT=16 + sim> set DRC trackprot=16 sim> attach DRC0 scratch.U0.2773.disc sim> deposit S 002611 sim> go @@ -2642,14 +2786,14 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS HALT instruction 102002 - sim> set DRC UNPROTECTED + sim> set DRC unprotected sim> go H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN HALT instruction 102002 - sim> set DRC PROTECTED + sim> set DRC protected sim> go H14 DEVICE HAS 0192 TRACKS,THE FOLLOWING ARE PROTECTED: @@ -2658,7 +2802,7 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS HALT instruction 102002 - sim> set DRC UNPROTECTED + sim> set DRC unprotected sim> go H36 PASS 0001 @@ -2686,7 +2830,7 @@ CONFIGURATION: sim> reset HALT instruction 107001 sim> set DRC 1536K - sim> set DRC TRACKPROT=64 + sim> set DRC trackprot=64 sim> attach DRC0 scratch.U0.2775.disc sim> deposit S 002611 sim> go @@ -2705,14 +2849,14 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS HALT instruction 102002 - sim> set DRC UNPROTECTED + sim> set DRC unprotected sim> go H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN HALT instruction 102002 - sim> set DRC PROTECTED + sim> set DRC protected sim> go H14 DEVICE HAS 0768 TRACKS,THE FOLLOWING ARE PROTECTED: @@ -2721,7 +2865,7 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS HALT instruction 102002 - sim> set DRC UNPROTECTED + sim> set DRC unprotected sim> go H36 PASS 0001 diff --git a/HP2100/hp2100_doc.txt b/HP2100/hp2100_doc.txt index 50f57550..d3174ca5 100644 --- a/HP2100/hp2100_doc.txt +++ b/HP2100/hp2100_doc.txt @@ -55,9 +55,11 @@ sim/ scp.h sim/hp2100/ hp2100_cpu.h hp2100_defs.h + hp2100_fp1.h hp2100_cpu.c hp2100_cpu1.c hp2100_fp.c + hp2100_fp1.c hp2100_dp.c hp2100_dq.c hp2100_dr.c @@ -78,9 +80,10 @@ The HP2100 simulator is configured as follows: device simulates name(s) -CPU 2116 CPU with 32KW memory - 2100 CPU with 32KW memory, FP or IOP instructions - 21MX-M/E CPU with 1024KW memory, FP, DMS, and/or IOP instructions +CPU 2116 CPU with up to 32KW of memory + 2100 CPU with up to 32KW of memory + 21MX-M or -E CPU with up to 1024KW of memory + EAU, FP, FFP, IOP, and/or DMS microcode extensions MP 12892B memory protect DMA0, DMA1 12895A/12897B direct memory access/dual channel port controller PTR 12597A duplex register interface with 2748 paper tape reader @@ -110,13 +113,21 @@ The HP2100 simulator implements several unique stop conditions: - more than INDMAX indirect references are detected during memory reference address decoding -The HP2100 loader supports standard absolute binary format. The DUMP +The HP2100 LOAD command supports standard absolute binary format. The DUMP command is not implemented. 2.1 CPU -CPU options include choice of instruction set and memory size. The -general command form is: +CPU options include choice of model, memory size, and instruction sets. +Several microcode options are simulated: + + EAU Extended Arithmetic Unit + FP Single-Precision Floating Point + FFP Fast FORTRAN Processor + IOP 2000/Access I/O Processor + DMS Dynamic Mapping System + +The general command form is: SET {-F} CPU