blob: 3833cf982ac33c8f819df56b7cdf1fd4843cba0f [file] [log] [blame] [raw]
/* 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
*/
#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 0
/* console sio data rates */
#define CON_POLLUNIT 0
#define CON_TERMUNIT 1
#define CON_POLLFIRST 1 /* immediate */
#define CON_POLLRATE 100
#define CON_POLLWAIT 12500
//#define CON_TERMRATE 1300
#define CON_TERMRATE 300
/* 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;
/* wrapper structure for terminal multiplexer,
pointer to pointer stored in device->ctxt */
typedef struct {
int pfirst, prate; /* pollrate first time, later */
TMLN ldsc;
TMXR desc;
UNIT* term;
UNIT* poll;
} SERMUX;
extern t_stat mux_attach(UNIT*, char*, SERMUX*);
extern t_stat mux_detach(UNIT*, SERMUX*);
/* 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_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