| /* pdq3_defs.h: PDQ3 simulator definitions | |
| Work derived from Copyright (c) 2004-2012, Robert M. Supnik | |
| Copyright (c) 2013 Holger Veit | |
| Permission is hereby granted, free of charge, to any person obtaining a | |
| copy of this software and associated documentation files (the "Software"), | |
| to deal in the Software without restriction, including without limitation | |
| the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| and/or sell copies of the Software, and to permit persons to whom the | |
| Software is furnished to do so, subject to the following conditions: | |
| The above copyright notice and this permission notice shall be included in | |
| all copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
| IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
| CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| Except as contained in this notice, the names of Robert M Supnik and Holger Veit | |
| shall not be used in advertising or otherwise to promote the sale, use or other dealings | |
| in this Software without prior written authorization from Robert M Supnik and Holger Veit. | |
| 20131103 hv INT_CONR/CONT assignments incorrect in docs, must be swapped | |
| 20141003 hv recommended warnings from VC++ and gcc added | |
| */ | |
| #ifndef _PDQ3_DEFS_H_ | |
| #define _PDQ3_DEFS_H_ 0 | |
| #include "sim_defs.h" /* simulator defns */ | |
| #include "sim_sock.h" | |
| #include "sim_tmxr.h" | |
| /* constants */ | |
| #define NIL 0xfc00 /* Pascal Microengine NIL value */ | |
| #define MSCW_SZ 4 /* size of MSCW */ | |
| #define REAL_SZ 2 /* size of real number (REAL*4) */ | |
| #define BSET_SZ 4080 /* usable size of set in bits */ | |
| #define ISET_SZ 255 /* size of set in words */ | |
| #define WORD_SZ 16 /* size of machine word in bits */ | |
| #define OFF_SEGBASE 0 /* offsets into SIB entry */ | |
| #define OFF_SEGLENG 1 | |
| #define OFF_SEGREFS 2 | |
| #define OFF_SEGADDR 3 | |
| #define OFF_SEGUNIT 4 | |
| #define OFF_PREVSP 5 | |
| #define OFF_SEGNAME 6 | |
| #define OFF_SEGLINK 10 | |
| #define OFF_SEGGLOBAL 11 | |
| #define OFF_SEGINIT 12 | |
| #define OFF_SEG13 13 | |
| #define OFF_SEGBACK 14 | |
| #define OFF_MSSTAT 0 /* offsets into MSCW */ | |
| #define OFF_MSDYNL 1 | |
| #define OFF_MSIPC 2 | |
| #define OFFB_MSSEG 3 | |
| #define OFFB_MSFLAG 3 | |
| #define OFF_WAITQ 0 /* offset into TIB */ | |
| #define OFF_QLINK 0 | |
| #define OFFB_PRIOR 1 | |
| #define OFFB_FLAGS 1 | |
| #define OFF_SPLOW 2 | |
| #define OFF_SPUPR 3 | |
| #define OFF_SP 4 | |
| #define OFF_MP 5 | |
| #define OFF_BP 6 | |
| #define OFF_IPC 7 | |
| #define OFF_SEGB 8 | |
| #define OFF_HANGP 9 | |
| #define OFF_IORSLT 10 | |
| #define OFF_SIBS 11 | |
| #define OFF_SEMCOUNT 0 /* offset into SEMA variable */ | |
| #define OFF_SEMWAITQ 1 | |
| #define SSR_BERR 0x01 /* bits of system status register */ | |
| #define SSR_TICK 0x02 | |
| #define SSR_INTVL 0x04 | |
| #define SSR_BIT3 0x08 | |
| #define SSR_PWRF 0x10 | |
| #define SSR_PRNT 0x20 | |
| #define SSR_INTEN 0x40 | |
| #define SSR_INIT 0x80 | |
| /* fixed interrupts */ | |
| #define INT_BERR 0 /* interrupt levels */ | |
| #define INT_PWRF 1 | |
| #define INT_DMAFD 2 | |
| #define INT_CONR 3 /* Appendix B.0.1 has CONT and CONR swapped, see Errata */ | |
| #define INT_CONT 4 | |
| #define INT_PRNT 5 | |
| #define INT_TICK 6 | |
| #define INT_INTVL 7 | |
| /* assignable QBUS interrupts, daisy-chained - highest prio = 8, lowest = 31 */ | |
| #define INT_QBUS8 8 | |
| #define INT_QBUS9 9 | |
| #define INT_QBUS10 10 | |
| #define INT_QBUS11 11 | |
| #define INT_QBUS12 12 | |
| #define INT_QBUS13 13 | |
| #define INT_QBUS14 14 | |
| #define INT_QBUS15 15 | |
| #define INT_QBUS16 16 | |
| #define INT_QBUS17 17 | |
| #define INT_QBUS18 18 | |
| #define INT_QBUS19 19 | |
| #define INT_QBUS20 20 | |
| #define INT_QBUS21 21 | |
| #define INT_QBUS22 22 | |
| #define INT_QBUS23 23 | |
| #define INT_QBUS24 24 | |
| #define INT_QBUS25 25 | |
| #define INT_QBUS26 26 | |
| #define INT_QBUS27 27 | |
| #define INT_QBUS28 28 | |
| #define INT_QBUS29 29 | |
| #define INT_QBUS30 30 | |
| #define INT_QBUS31 31 | |
| /* common unit user-defined attributes */ | |
| #define u_unitno u3 | |
| /* Memory */ | |
| #define MEMSIZE 65536 /* memory size in bytes */ | |
| #define MAXMEMSIZE (65535 * 2) /* maximum memory size in bytes */ | |
| #define memorysize uptr->capac | |
| /* CPU Unit flags */ | |
| #define UNIT_V_PDQ3 (UNIT_V_UF + 0) | |
| #define UNIT_V_MSIZE (UNIT_V_UF + 1) | |
| #define UNIT_V_PASEXC (UNIT_V_UF + 2) | |
| #define UNIT_PDQ3 (1u << UNIT_V_PDQ3) | |
| #define UNIT_MSIZE (1u << UNIT_V_MSIZE) | |
| #define UNIT_PASEXC (1u << UNIT_V_PASEXC) | |
| #define Q_PDQ3 (cpu_unit.flags & UNIT_PDQ3) | |
| #define Q_MSIZE (cpu_unit.flags & UNIT_MSIZE) | |
| #define Q_PASEXC (cpu_unit.flags & UNIT_PASEXC) | |
| #define setbit(reg,val) reg |= (val) | |
| #define clrbit(reg,val) reg &= ~(val) | |
| #define isbitset(reg, val) (reg & (val)) | |
| #define isbitclr(reg, val) ((reg & (val)) == 0) | |
| /* debug flags */ | |
| #define DBG_NONE 0x0000 | |
| #define DBG_FD_CMD 0x0001 | |
| #define DBG_FD_READ 0x0002 | |
| #define DBG_FD_WRITE 0x0004 | |
| #define DBG_FD_SVC 0x0008 | |
| #define DBG_FD_IMD 0x0010 | |
| #define DBG_FD_IMD2 0x0020 /* deep inspection */ | |
| #define DBG_FD_DMA 0x0040 | |
| #define DBG_FD_DMA2 0x0080 /* deep inspection */ | |
| //define DBG_CPU_TRACE 0x0001 unused | |
| #define DBG_CPU_INT 0x0001 | |
| #define DBG_CPU_INT2 0x0002 /* deep inspection */ | |
| #define DBG_CPU_READ 0x0004 | |
| #define DBG_CPU_WRITE 0x0008 | |
| #define DBG_CPU_FETCH 0x0010 | |
| #define DBG_CPU_PUSH 0x0020 | |
| #define DBG_CPU_POP 0x0040 | |
| #define DBG_CPU_PICK 0x0080 | |
| #define DBG_CPU_STACK (DBG_CPU_PUSH|DBG_CPU_POP|DBG_CPU_PICK) | |
| #define DBG_CPU_CONC 0x0100 | |
| #define DBG_CPU_CONC2 0x0200 /* deep inspection */ | |
| #define DBG_CPU_CONC3 0x0400 /* even deeper inspection */ | |
| #define DBG_CON_READ 0x0001 | |
| #define DBG_CON_WRITE 0x0002 | |
| #define DBG_CON_SVC 0x0004 | |
| #define DBG_TIM_READ 0x0001 | |
| #define DBG_TIM_WRITE 0x0002 | |
| #define DBG_TIM_SVC 0x0004 | |
| #define DBG_PCFORMAT0 "[%04x:%04x] " | |
| #define DBG_PCFORMAT1 " [%04x:%04x] " | |
| #define DBG_PCFORMAT2 " [%04x:%04x] " | |
| #define DBG_PC reg_segb,ADDR_OFF(PCX) | |
| #define DBG_PC2 reg_segb,reg_ipc | |
| /* calibration timers */ | |
| #define TMR_CONPOLL 1 | |
| /* IDLE timer. This is supposed to run at 100 Hz; the CPU runs at | |
| * 1.25MHz, i.e. the interval is 12500. */ | |
| #define TMR_IDLE 0 | |
| #define TMR_IDLECNT 12500 | |
| /* console sio data rates */ | |
| #define CON_POLLUNIT 0 | |
| #define CON_TERMUNIT 1 | |
| #define CON_POLLFIRST 1 /* immediate */ | |
| #define CON_POLLRATE 100 | |
| #define CON_TPS 100 | |
| #define CON_TERMRATE 100 | |
| /* floppy size */ | |
| #define FDC_MAX_TRACKS 77 | |
| /* IMD anachronism */ | |
| #ifndef MAX_COMMENT_LEN | |
| #define MAX_COMMENT_LEN 256 | |
| #endif | |
| /* XXX @TODO Pascal error codes (Raise()) */ | |
| #define PASERROR_SYSTEM 0 | |
| #define PASERROR_VALRANGE 1 | |
| #define PASERROR_NOSEG 2 | |
| #define PASERROR_PROCERR 3 | |
| #define PASERROR_STKOVFL 4 | |
| #define PASERROR_INTOVFL 5 | |
| #define PASERROR_DIVZERO 6 | |
| #define PASERROR_MEMERR 7 | |
| #define PASERROR_USERBRK 8 | |
| #define PASERROR_SYSIO 9 | |
| #define PASERROR_USERIO 10 | |
| #define PASERROR_UNIMPL 11 | |
| #define PASERROR_FPERR 12 | |
| #define PASERROR_STRINGOVFL 13 | |
| #define PASERROR_HALT 14 | |
| /* simh error codes */ | |
| #define STOP_IBKPT 1 | |
| #define STOP_MEM 2 | |
| #define STOP_ERROP 3 | |
| #define STOP_ERRADR 4 | |
| #define STOP_ERRIO 5 | |
| #define STOP_IMPL 6 | |
| #define STOP_BPT 7 | |
| #define STOP_DBGPRE 8 | |
| #define STOP_DBGPOST 9 | |
| #define STOP_PASEXC 10 | |
| /* IO addresses and vectors */ | |
| #define CON_IOBASE 0xfc10 | |
| #define CON_RCV_VEC 0x0012 | |
| #define CON_XMT_VEC 0x000e | |
| #define CON_PRT_VEC 0x0016 | |
| #define SES_IOBASE 0xfc18 | |
| #define SES_BERR_VEC 0x0002 | |
| #define SES_PWRF_VEC 0x0006 | |
| #define SSR_IOBASE 0xfc24 | |
| #define TIM_IOBASE 0xfc20 | |
| #define TIM_TICK_VEC 0x001a | |
| #define TIM_INTVL_VEC 0x001e | |
| #define FDC_IOBASE 0xfc30 | |
| #define FDC_VEC 0x000a | |
| #define CPU_SERIALNO 0xf5ff /* is part of ROM */ | |
| #define ROM_BASE 0xfc68 | |
| #define ROM 0xf400 | |
| #define ROM_SIZE 0x01ff /* excluding serial number */ | |
| /* address calculations */ | |
| #define ADDRMASK_SEG 0xffff0000 | |
| #define ADDRMASK_OFF 0x0000ffff | |
| #define ADDR_16bit(a) ((a) & 0x0000ffff) | |
| #define ADDR_SEG(a) (((a)>>16) & ADDRMASK_OFF) | |
| #define ADDR_OFF(a) ((a) & ADDRMASK_OFF) | |
| #define MAKE_BADDR(s,o) ((ADDR_16bit(s)<<16) | ADDR_16bit(o)) | |
| #define MAKE_WADDR(a) MAKE_BADDR(NIL,ADDR_OFF(a)) | |
| #define ADDR_ISWORD(a) (ADDR_SEG(a) == NIL) | |
| /* opcode table */ | |
| #define OP_ERROR -1 | |
| #define OP_NULL 0 | |
| #define OP_UB 1 | |
| #define OP_W 2 | |
| #define OP_B 3 | |
| #define OP_DBB 4 | |
| #define OP_UBB 5 | |
| #define OP_BUB 6 | |
| #define OP_SB 7 | |
| #define OP_DBUB 8 | |
| #define OP_UBUB 9 | |
| #define OP_UBDBUB 10 | |
| #define OP_DB 11 | |
| #define OP_SW 12 | |
| #define OP_AB 13 | |
| typedef struct _optable { | |
| char* name; | |
| int16 flags; | |
| } OPTABLE; | |
| extern OPTABLE optable[]; | |
| /* debug support */ | |
| #define DEBUG_OPDBGFILE "opcode.dbg" | |
| #define DEBUG_MINOPCODE 0 | |
| #define DEBUG_MAXOPCODE 0xe8 | |
| #define DEBUG_VALIDOP(op) (optable[op].flags >= 0) | |
| #define DEBUG_PRE 0x01 | |
| #define DEBUG_POST 0x02 | |
| extern t_stat dbg_init(); | |
| extern t_stat dbg_check(t_value data,uint8 prepost); | |
| extern t_stat dbg_dump_tib(FILE* fd, uint16 base); | |
| extern t_stat dbg_dump_queue(FILE* fd, const char* qname, uint16 q); | |
| extern t_stat dbg_dump_mscw(FILE* fd, uint16 base); | |
| extern t_stat dbg_dump_seg(FILE* fd, uint16 segptr); | |
| extern t_stat dbg_dump_segtbl(FILE* fd); | |
| extern t_stat dbg_segtrack(uint16 segbase); | |
| extern t_stat dbg_procenter(uint16 segbase, uint16 procno, uint16 mscw, uint16 osegb); | |
| extern t_stat dbg_procleave(); | |
| extern void dbg_enable(); | |
| extern t_stat dbg_calltree(FILE* fd); | |
| extern t_stat dbg_enteralias(const char* key, const char* value); | |
| extern t_stat dbg_listalias(FILE*); | |
| /* floating point */ | |
| typedef union flcvt { | |
| float f; | |
| uint16 i[2]; | |
| } T_FLCVT; | |
| /* externals */ | |
| extern DEVICE cpu_dev; | |
| extern UNIT cpu_unit; | |
| extern DEVICE con_dev; | |
| extern UNIT con_unit[]; | |
| extern DEVICE fdc_dev; | |
| extern UNIT fdc_unit[]; | |
| extern DEVICE timer_dev; | |
| extern UNIT timer_unit[]; | |
| extern t_addr PCX; /* PC at the begin of execution */ | |
| extern uint16 reg_segb; | |
| extern uint32 reg_dmabase; | |
| extern uint16 reg_mp; | |
| extern uint16 reg_bp; | |
| extern uint16 reg_sp; | |
| extern uint16 reg_splow; | |
| extern uint16 reg_spupr; | |
| extern uint16 reg_ctp; | |
| extern uint16 reg_rq; | |
| extern uint16 reg_ipc; | |
| extern uint16 reg_fc68; | |
| extern uint16 reg_romsize; | |
| extern uint16 reg_ssv; | |
| extern uint16 reg_ssr; | |
| extern uint16 reg_cpuserial; | |
| extern uint32 reg_intpending; | |
| extern t_stat Read(t_addr base, t_addr woffset, uint16 *data, uint32 dctrl); | |
| extern t_stat Write(t_addr base, t_addr boffset, uint16 data, uint32 dctrl); | |
| extern t_stat ReadB(t_addr base, t_addr boffset, uint16 *data, uint32 dctrl); | |
| extern t_stat WriteB(t_addr base, t_addr boffset, uint16 data, uint32 dctrl); | |
| extern t_stat ReadEx(t_addr base, t_addr woffset, uint16 *data); | |
| extern t_stat ReadBEx(t_addr base, t_addr boffset, uint16 *data); | |
| extern t_stat rom_read(t_addr base, uint16 *data); | |
| extern t_stat rom_write(t_addr base, uint16 data); | |
| extern t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw); | |
| extern t_stat con_read(t_addr ioaddr, uint16 *data); | |
| extern t_stat con_write(t_addr ioaddr, uint16 data); | |
| extern t_stat con_binit(); | |
| extern t_stat fdc_boot(int32 unitnum, DEVICE *dptr); | |
| extern t_stat fdc_read(t_addr ioaddr, uint16 *data); | |
| extern t_stat fdc_write(t_addr ioaddr, uint16 data); | |
| extern t_stat fdc_autoload(); | |
| extern t_stat fdc_binit(); | |
| extern t_stat tim_read(t_addr ioaddr, uint16 *data); | |
| extern t_stat tim_write(t_addr ioaddr, uint16 data); | |
| extern void cpu_assertInt(int level, t_bool tf); | |
| extern t_stat cpu_raiseInt(int level); | |
| extern t_stat cpu_setIntVec(uint16 vector,int level); | |
| extern void cpu_setRegs(uint16 ctp, uint16 ssv, uint16 rq); | |
| extern void cpu_finishAutoload(); | |
| extern t_stat cpu_buserror(); | |
| typedef t_stat (*IOREAD)(t_addr ioaddr, uint16 *data); | |
| typedef t_stat (*IOWRITE)(t_addr ioaddr, uint16 data); | |
| typedef struct _ioinfo { | |
| struct _ioinfo* next; | |
| uint16 iobase; | |
| uint16 iosize; | |
| uint16 qvector; | |
| uint16 qprio; | |
| IOREAD read; | |
| IOWRITE write; | |
| } IOINFO; | |
| typedef struct _devctxt { | |
| IOINFO* ioi; | |
| } DEVCTXT; | |
| extern t_stat pdq3_ioinit(); | |
| extern t_stat add_ioh(IOINFO* ioi); | |
| extern t_stat del_ioh(IOINFO* ioi); | |
| extern t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc); | |
| extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc); | |
| extern t_stat set_iovec(UNIT *uptr, int32 val, char *cptr, void *desc); | |
| extern t_stat show_iovec(FILE *st, UNIT *uptr, int value, void *desc); | |
| extern t_stat set_ioprio(UNIT *uptr, int32 val, char *cptr, void *desc); | |
| extern t_stat show_ioprio(FILE *st, UNIT *uptr, int value, void *desc); | |
| #endif |