/* 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 { | |
const 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(int unitnum); | |
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, CONST char *cptr, void *desc); | |
extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, CONST void *desc); | |
extern t_stat set_iovec(UNIT *uptr, int32 val, CONST char *cptr, void *desc); | |
extern t_stat show_iovec(FILE *st, UNIT *uptr, int value, CONST void *desc); | |
extern t_stat set_ioprio(UNIT *uptr, int32 val, CONST char *cptr, void *desc); | |
extern t_stat show_ioprio(FILE *st, UNIT *uptr, int value, CONST void *desc); | |
#endif |