From 66f4cc4c830274cfec83a9d9bb4a050c8febbece Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Wed, 17 Jul 2019 21:39:18 -0400 Subject: [PATCH] SEL32: More instructions. --- SEL32/sel32_cpu.c | 207 ++++++++++++++++++++++----------------------- SEL32/sel32_defs.h | 113 +++++++++++++++++++++++-- 2 files changed, 210 insertions(+), 110 deletions(-) diff --git a/SEL32/sel32_cpu.c b/SEL32/sel32_cpu.c index dc89e7b..cc0f0b0 100644 --- a/SEL32/sel32_cpu.c +++ b/SEL32/sel32_cpu.c @@ -1,6 +1,7 @@ /* sel32_cpu.c: Sel 32 CPU simulator - Copyright (c) 2017, Richard Cornwell + Copyright (c) 2018, Richard Cornwell + Copyright (c) 2018, James C. Bevier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -15,9 +16,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + RICHARD CORNWELL OR JAMES BEVIER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ @@ -30,15 +32,6 @@ #define UNIT_MSIZE (0x1F << UNIT_V_MSIZE) #define MEMAMOUNT(x) (x << UNIT_V_MSIZE) -#define MODEL_55 0 /* 512K Mode Only */ -#define MODEL_75 1 /* Extended */ -#define MODEL_27 2 /* */ -#define MODEL_67 3 /* */ -#define MODEL_87 4 /* */ -#define MODEL_97 5 /* */ -#define MODEL_V6 6 /* V6 CPU */ -#define MODEL_V9 7 /* V9 CPU */ - #define TMR_RTC 1 #define HIST_MIN 64 @@ -52,33 +45,20 @@ uint32 BR[8]; /* Base registers */ uint32 PC; /* Program counter */ uint8 CC: /* Condition code register */ uint32 SPAD[256]; /* Scratch pad memory */ -#define CC1 0x40 -#define CC2 0x20 -#define CC3 0x10 -#define CC4 0x08 -#define AEXP 0x01 /* Arithmetic exception PSD 1 bit 7 */ - /* Held in CC */ - uint8 modes; /* Operating modes */ -#define PRIV 0x80 /* Privileged mode PSD 1 bit 0 */ -#define EXTD 0x04 /* Extended Addressing PSD 1 bit 5 */ -#define BASE 0x02 /* Base Mode PSD 1 bit 6 */ -#define MAP 0x40 /* Map mode, PSD 2 bit 0 */ -#define RET 0x20 /* Retain current map, PSD 2 bit 15 */ - uint8 irq_flags; /* Interrupt control flags PSD 2 bits 16&17 */ uint16 cpix; /* Current Process index */ uint16 bpix; /* Base process index */ struct InstHistory { - uint32 pc; - uint32 inst; - uint32 ea; - uint64 dest; - uint64 source; - uint64 res; - uint8 cc; + uint32 pc; /* Program counter */ + uint32 inst; /* Instruction register */ + uint32 ea; /* Effective address */ + uint64 dest; /* Destination value */ + uint64 source; /* Source value */ + uint64 res; /* Result value */ + uint8 cc; /* Condition codes */ }; t_stat cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr, @@ -113,41 +93,25 @@ struct InstHistory *hst = NULL; /* History stack */ UNIT cpu_unit = { UDATA(rtc_srv, UNIT_BINK | MODEL(MODEL_27) | MEMAMOUNT(0), MAXMEMSIZE ), 120 }; +uint32 GPR[8]; /* General Purpose Registers */ +uint32 BR[8]; /* Base registers */ +uint32 PC; /* Program counter */ +uint8 CC: /* Condition code register */ +uint32 SPAD[256]; /* Scratch pad memory */ +uint8 modes; /* Operating modes */ +uint8 irq_flags; /* Interrupt control flags PSD 2 bits 16&17 */ +uint16 cpix; /* Current Process index */ +uint16 bpix; /* Base process index */ +uint32 tlb[2048]; /* Translation look asside buffer */ REG cpu_reg[] = { - {ORDATAD(IC, IC, 15, "Instruction Counter"), REG_FIT}, - {ORDATAD(AC, AC, 38, "Accumulator"), REG_FIT, 0}, - {ORDATAD(MQ, MQ, 36, "Multiplier Quotent"), REG_FIT, 0}, - {BRDATAD(XR, XR, 8, 15, 8, "Index registers"), REG_FIT}, - {ORDATAD(ID, ID, 36, "Indicator Register")}, -#ifdef EXTRA_SL - {ORDATAD(SL, SL, 8, "Sense Lights"), REG_FIT}, -#else - {ORDATAD(SL, SL, 4, "Sense Lights"), REG_FIT}, -#endif -#ifdef EXTRA_SW - {ORDATAD(SW, SW, 12, "Sense Switches"), REG_FIT}, -#else - {ORDATAD(SW, SW, 6, "Sense Switches"), REG_FIT}, -#endif -#endif - {ORDATAD(KEYS, KEYS, 36, "Console Key Register"), REG_FIT}, - {ORDATAD(MTM, MTM, 1, "Multi Index registers"), REG_FIT}, - {ORDATAD(TM, TM, 1, "Trap mode"), REG_FIT}, - {ORDATAD(STM, STM, 1, "Select trap mode"), REG_FIT}, - {ORDATAD(CTM, CTM, 1, "Copy Trap Mode"), REG_FIT}, - {ORDATAD(FTM, FTM, 1, "Floating trap mode"), REG_FIT}, - {ORDATAD(NMODE, nmode, 1, "Storage null mode"), REG_FIT}, - {ORDATAD(ACOVF, acoflag, 1, "AC Overflow Flag"), REG_FIT}, - {ORDATAD(MQOVF, mqoflag, 1, "MQ Overflow Flag"), REG_FIT}, - {ORDATAD(IOC, iocheck, 1, "I/O Check flag"), REG_FIT}, - {ORDATAD(DVC, dcheck, 1, "Divide Check flag"), REG_FIT}, - {ORDATAD(RELOC, relocaddr, 14, "Relocation offset"), REG_FIT}, - {ORDATAD(BASE, baseaddr, 14, "Relocation base"), REG_FIT}, - {ORDATAD(LIMIT, limitaddr, 14, "Relocation limit"), REG_FIT}, - {ORDATAD(ENB, ioflags, 36, "I/O Trap Flags"), REG_FIT}, - {FLDATA(INST_BASE, bcore, 0), REG_FIT}, - {FLDATA(DATA_BASE, bcore, 1), REG_FIT}, + {HRDATAD(PC, PC, 24, "Program Counter Counter"), REG_FIT}, + {BRDATAD(GPR, GPR, 8, 32, 16, "General Purpose Registers"), REG_FIT, 0}, + {BRDATAD(BR, BR, 8, 32, 16, "Base Registers"), REG_FIT, 0}, + {HRDATAD(CC, CC, 4, "Condition codes"), REG_FIT}, + {BRDATAD(SPAD, SPAD, 256, 32, 16, "Scratch Pad Registers"), REG_FIT}, + {HRDATAD(CPIX, cpix, 16, "Current process index"), REG_FIT}, + {HRDATAD(BPIX, bpix, 16, "Base process index"), REG_FIT}, {NULL} }; @@ -304,7 +268,35 @@ int base_mode[] = { ADR, RR|SR|WRD, ADR, IMM, }; +/* System 70 PTE: + * + * Bit 0 - NU + * Bit 1 - Valid Entry + * Bit 2 - Write Protect + * Bit 3 - 15 Address. + * + * System 67 PTR: + * Bit 0 - Valid Entry + * Bit 1 - 0000-7ff Write Protected + * Bit 2 - 0800-fff Write Protected + * Bit 3 - 1000-7ff Write Protected + * Bit 4 - 1800-fff Write Protected + * Bit 5 - 15 Address. + * + * System V6&V9 + * Bit 0 - Valid Entry + * Bit 1 - No Access + * Bit 2 - Write protect + * Bit 3 - Modified Block + * Bit 4 - Access Block + * Bit 5-15 Address. + */ + int page_lookup(uint32 addr, uint32 *loc, int wr) { + int page = addr >> 12; + if (tlb[page] != 0) { + } else { + } } int Mem_read(uint32 addr, uint32 *data) { @@ -336,8 +328,10 @@ t_stat sim_instr(void) { t_stat reason; - uint64 dest; /* Holds destination/source register */ - uint64 source; /* Holds source or memory data */ + uint64 d_dest; /* Holds double length destination/source register */ + uint32 dest; /* Holds destination/source register */ + uint64 d_source; /* Holds double length source or memory data */ + uint32 source; /* Holds source or memory data */ uint32 addr; /* Holds address of last access */ uint32 temp; /* General holding place for stuff */ uint32 IR; /* Instruction register */ @@ -385,7 +379,7 @@ exec: op = (opr >> 26) & 03F; FC = (IR & F_BIT) ? 0x4 : 0; reg = (opr >> 23) & 0x7; - dest = (uint64)IR; + dest = IR; dbl = 0; ovr = 0; if (mode & BASE) { @@ -464,7 +458,7 @@ exec: /* Fault */ } addr = temp & 0xFF07FFFF; - dest = (uint64)temp; + dest = temp; ix = (temp >> 21) & 3; if (ix != 0) addr += GPR[ix]; @@ -499,7 +493,7 @@ exec: } if (Mem_read(addr + 4, &temp)) { } - source |= ((uint64)temp) << 32; + d_source = ((uint64)temp) << 32 | source; dbl = 1; break; case 4: @@ -513,33 +507,33 @@ exec: /* Read in if from register */ if (i_flags & RR) { - dest = (uint64)GPR[reg]; + dest = GPR[reg]; if (dbl) { if (reg & 1) { /* Spec fault */ } - dest |= ((uint64)GPR[reg|1]) << 32; + d_dest = ((uint64)GPR[reg|1]) << 32 | dest; } else { - dest |= (dest & FSIGN) ? 0xFFFFFFFF << 32: 0; + d_dest |= ((dest & FSIGN) ? 0xFFFFFFFFLL << 32: 0) | dest; } } /* For Base mode */ if (i_flags & RB) { - dest = (uint64)BR[reg]; + dest = BR[reg]; } /* For register instructions */ if (i_flags & R1) { int r = (IR >> 20) & 07; - source = (uint64)GPR[r]; + source = GPR[r]; if (dbl) { if (r & 1) { /* Spec fault */ } - source |= ((uint64)GPR[r|1]) << 32; + d_source = ((uint64)GPR[reg|1]) << 32 | source; } else { - source |= (source & FSIGN) ? 0xFFFFFFFF << 32: 0; + d_source |= ((source & FSIGN) ? 0xFFFFFFFFLL << 32: 0) | source; } } @@ -638,17 +632,6 @@ exec: break; case 0x04: /* 0x10 */ /* CAR or (basemode SACZ ) */ if (modes & BASE) { - temp = GPR[reg]; - t = (IR >> 20) & 7; - temp = temp - GPR[t]; - CC &= AEXP; - else if (temp & FSIGN) - CC |= CC3; - else if (temp == 0) - CC |= CC4; - else - CC |= CC2; - } else { scaz: temp = GPR[reg]; t = 0; @@ -662,7 +645,18 @@ scaz: } else { CC |= CC4; } + } else { GPR[(IR >> 20) & 7] = t; + temp = GPR[reg]; + t = (IR >> 20) & 7; + temp = temp - GPR[t]; + CC &= AEXP; + else if (temp & FSIGN) + CC |= CC3; + else if (temp == 0) + CC |= CC4; + else + CC |= CC2; } break; @@ -1307,8 +1301,8 @@ scaz: if (reg & 1) { /* Spec fault */ } - dest = (uint64)temp | (temp & FSIGN) ? FMASK << 32: 0; - source = (uint64)addr | (addr & FSIGN) ? FMASK << 32: 0; + d_dest = (uint64)temp | (temp & FSIGN) ? FMASK << 32: 0; + d_source = (uint64)addr | (addr & FSIGN) ? FMASK << 32: 0; GPR[reg] = (uint32)(dest & FMASK); GPR[reg|1] = (uint32)((dest >> 32) & FMASK); CC &= AEXP; @@ -1324,24 +1318,24 @@ scaz: if (reg & 1) { /* Spec fault */ } - source = (uint64)addr | (addr & FSIGN) ? FMASK << 32: 0; - if (source == 0) { + d_source = (uint64)addr | (addr & FSIGN) ? FMASK << 32: 0; + if (d_source == 0) { ovr = 1; break; } - dest = (uint64)GPR[reg]; - dest |= ((uint64)GPR[reg|1]) << 32; - t = (int64)dest % (int64)source; + d_dest = (uint64)GPR[reg]; + d_dest |= ((uint64)GPR[reg|1]) << 32; + t = (int64)d_dest % (int64)d_source; dbl = (t < 0); - if ((t ^ (dest & MSIGN)) != 0) /* Fix sign if needed */ + if ((t ^ (d_dest & MSIGN)) != 0) /* Fix sign if needed */ t = -t; - dest = (int64)dest / (int64)source; - if ((dest & LMASK) != 0 && (dest & LMASK) != LMASK) + d_dest = (int64)d_dest / (int64)d_source; + if ((d_dest & LMASK) != 0 && (d_dest & LMASK) != LMASK) ovr = 1; GPR[reg] = (uint32)t; - GPR[reg|1] = (uint32)(dest & FMASK); + GPR[reg|1] = (uint32)(d_dest & FMASK); CC &= AEXP; - if (dest & MSIGN) + if (d_dest & MSIGN) CC |= CC3; else if (dest == 0) CC |= CC4; @@ -1503,9 +1497,12 @@ scaz: /* Store result to register */ if (i_flags & SD) { - if (dbl) - GPR[reg|1] = (uint32)(dest>>32); - GPR[reg] = (uint32)(dest & FMASK); + if (dbl) { + GPR[reg|1] = (uint32)(d_dest>>32); + GPR[reg] = (uint32)(d_dest & FMASK); + } else { + GPR[reg] = dest; + } } /* Store result to base register */ @@ -1513,7 +1510,7 @@ scaz: if (dbl) { /* Fault */ } - BR[reg] = (uint32)(dest & FMASK); + BR[reg] = dest; } /* Store result to memory */ diff --git a/SEL32/sel32_defs.h b/SEL32/sel32_defs.h index 5df8bc8..28ad50e 100644 --- a/SEL32/sel32_defs.h +++ b/SEL32/sel32_defs.h @@ -1,6 +1,7 @@ /* sel32_defs.h: Gould Concept/32 (orignal SEL32) simulator definitions - Copyright (c) 2017, Richard Cornwell + Copyright (c) 2018, Richard Cornwell + Copyright (c) 2018, James C. Bevier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -15,9 +16,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + RICHARD CORNWELL OR JAMES BEVIER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ @@ -255,5 +257,106 @@ typedef struct dib { extern DEBTAB dev_debug[]; +/* defines for all programs */ +#define RMASK 0x0000FFFF /* right hw 16 bit mask */ +#define LMASK 0xFFFF0000 /* left hw 16 bit mask */ +#define FMASK 0xFFFFFFFF /* 32 bit mask */ +#define DMASK 0xFFFFFFFFFFFFFFFFLL /* 64 bit all bits mask */ +#define D48LMASK 0xFFFFFFFFFFFF0000LL /* 64 bit left 48 bits mask */ +#define D32LMASK 0xFFFFFFFF00000000LL /* 64 bit left 32 bits mask */ +#define D32RMASK 0x00000000FFFFFFFFLL /* 64 bit right 32 bits mask */ +#define MSIGN 0x80000000 /* 32 bit minus sign */ +#define DMSIGN 0x8000000000000000LL /* 64 bit minus sign */ +#define FSIGN 0x80000000 /* 32 bit minus sign */ +/* sign extend 16 bit value to uint32 */ +#define SEXT16(x) (x&MSIGN?(uint32)(((uint32)x&RMASK)|LMASK):(uint32)x) +/* sign extend 16 bit value to uint64 */ +#define DSEXT16(x) (x&MSIGN?(l_uint64)(((l_uint64)x&RMASK)|D48LMASK):(t_uint64)x) +/* sign extend 32 bit value to uint64 */ +#define DSEXT32(x) (x&MSIGN?(l_uint64)(((l_uint64)x&D32RMASK)|D32LMASK):(t_uint64)x) + +#define UNIT_V_MODEL (UNIT_V_UF + 0) +#define UNIT_MODEL (7 << UNIT_V_MODEL) +#define MODEL(x) (x << UNIT_V_MODEL) +#define UNIT_V_MSIZE (UNIT_V_MODEL + 3) +#define UNIT_MSIZE (0x1F << UNIT_V_MSIZE) +#define MEMAMOUNT(x) (x << UNIT_V_MSIZE) +#define CPU_MODEL ((cpu_unit.flags >> UNIT_V_MODEL) & 0x7) /* cpu model 0-7 */ + +#define MODEL_55 0 /* 512K Mode Only */ +#define MODEL_75 1 /* Extended */ +#define MODEL_27 2 /* */ +#define MODEL_67 3 /* */ +#define MODEL_87 4 /* */ +#define MODEL_97 5 /* */ +#define MODEL_V6 6 /* V6 CPU */ +#define MODEL_V9 7 /* V9 CPU */ + + DEVICEC1 0x40 /* CC1 in CC */ +#define CC2 0x20 /* CC2 in CC */ +#define CC3 0x10 /* CC3 in CC */ +#define CC4 0x08 /* CC4 in CC */ + +#define CC1BIT 0x40000000 /* CC1 in PSD1 */ +#define CC2BIT 0x20000000 /* CC2 in PSD1 */ +#define CC3BIT 0x10000000 /* CC3 in PSD1 */ +#define CC4BIT 0x08000000 /* CC4 in PSD1 */ + +/* PSD mode bits in 'modes' variable */ +#define PRIV 0x80 /* Privileged mode PSD 1 bit 0 */ +#define EXTD 0x04 /* Extended Addressing PSD 1 bit 5 */ +#define BASE 0x02 /* Base Mode PSD 1 bit 6 */ +#define AEXP 0x01 /* Arithmetic exception PSD 1 bit 7 */ + +#define MAP 0x40 /* Map mode, PSD 2 bit 0 */ +#define RET 0x20 /* Retain current maps, PSD 2 bit 15 */ +#define BLKED 0x10 /* Set blocked mode, PSD 2 bit 17 */ +#define BLKRET 0x08 /* Set retain blocked mode, PSD 2 bit 16 */ + +/* PSD mode bits in PSD words 1&2 variable */ +#define PRIVBIT 0x80000000 /* Privileged mode PSD 1 bit 0 */ +#define EXTDBIT 0x04000000 /* Extended Addressing PSD 1 bit 5 */ +#define BASEBIT 0x02000000 /* Base Mode PSD 1 bit 6 */ +#define AEXPBIT 0x01000000 /* Arithmetic exception PSD 1 bit 7 */ + +#define BLKEDBIT 0x00004000 /* Set blocked mode, PSD 2 bit 17 */ +#define RETBIT 0x00010000 /* Retain current maps, PSD 2 bit 15 */ +#define MAPBIT 0x80000000 /* Map mode, PSD 2 bit 0 */ + +/* Trap Table Address in memory is pointed to by SPAD 0xF0 */ +#define POWERFAIL_TRAP 0x80 /* Power fail trap */ +#define POWERON_TRAP 0x84 /* Power-On trap */ +#define MEMPARITY_TRAP 0x88 /* Memory Parity Error trap */ +#define NONPRESMEM_TRAP 0x8C /* Non Present Memory trap */ +#define UNDEFINSTR_TRAP 0x90 /* Undefined Instruction Trap */ +#define PRIVVIOL_TRAP 0x94 /* Privlege Violation Trap */ +#define SVCCALL_TRAP 0x98 /* Supervisor Call Trap */ +#define MACHINECHK_TRAP 0x9C /* Machine Check Trap */ +#define SYSTEMCHK_TRAP 0xA0 /* System Check Trap */ +#define MAPFAULT_TRAP 0xA4 /* Map Fault Trap */ +#define IPUUNDEFI_TRAP 0xA8 /* IPU Undefined Instruction Trap */ +#define SIGNALIPU_TRAP 0xAC /* Signal IPU/CPU Trap */ +#define ADDRSPEC_TRAP 0xB0 /* Address Specification Trap */ +#define CONSOLEATN_TRAP 0xB4 /* Console Attention Trap */ +#define PRIVHALT_TRAP 0xB8 /* Privlege Mode Halt Trap */ +#define AEXPCEPT_TRAP 0xBC /* Arithmetic Exception Trap */ + + +/* Errors returned from various functions */ +#define ALLOK 0x0000 /* no error, all is OK */ +#define MAPFLT MAPFAULT_TRAP /* map fault error */ +#define NPMEM NONPRESMEM_TRAP /* non present memory */ +#define MPVIOL PRIVVIOL_TRAP /* memory protection violation */ + +/* general instruction decode equates */ +#define IND 0x00100000 /* indirect bit in instruction, bit 11 */ +#define F_BIT 0x00080000 /* byte flag addressing bit 11 in instruction */ +#define C_BITS 0x00000003 /* byte number or hw, dw, dw flags bits 20 & 31 */ +#define BIT0 0x80000000 /* general use for bit 0 testing */ +#define BIT1 0x40000000 /* general use for bit 1 testing */ +#define MASK16 0x0000FFFF /* 16 bit address mask */ +#define MASK19 0x0007FFFF /* 19 bit address mask */ +#define MASK20 0x000FFFFF /* 20 bit address mask */ +#define MASK24 0x00FFFFFF /* 24 bit address mask */ +#define MASK32 0xFFFFFFFF /* 32 bit address mask */ -extern DEVICE cpu_dev;