/* 3b2_defs.h: AT&T 3B2 Model 400 Simulator Definitions | |
Copyright (c) 2017, Seth J. Morabito | |
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 THE AUTHORS OR COPYRIGHT HOLDERS | |
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 name of the author shall | |
not be used in advertising or otherwise to promote the sale, use or | |
other dealings in this Software without prior written authorization | |
from the author. | |
*/ | |
#ifndef _3B2_DEFS_H_ | |
#define _3B2_DEFS_H_ | |
#include "sim_defs.h" | |
#include "sim_tmxr.h" | |
#include <setjmp.h> | |
#define FALSE 0 | |
#define TRUE 1 | |
#if defined (__GNUC__) | |
#define noret void __attribute__((noreturn)) | |
#else | |
#define noret void | |
#endif | |
#if defined(__GLIBC__) && !defined(__cplusplus) | |
/* use glibc internal longjmp to bypass fortify checks */ | |
noret __libc_longjmp (jmp_buf buf, int val); | |
#define longjmp __libc_longjmp | |
#endif | |
/* -t flag: Translate a virtual address */ | |
#define EX_T_FLAG 1 << 19 | |
/* -v flag for examine routine */ | |
#define EX_V_FLAG 1 << 21 | |
#define MAX_HIST_SIZE 10000000 | |
#define MIN_HIST_SIZE 64 | |
#define MAXMEMSIZE (1 << 22) /* 4 MB */ | |
#define MEM_SIZE (cpu_unit.capac) /* actual memory size */ | |
#define UNIT_V_MSIZE (UNIT_V_UF) | |
#define UNIT_MSIZE (1 << UNIT_V_MSIZE) | |
#define WD_MSB 0x80000000 | |
#define HW_MSB 0x8000 | |
#define BT_MSB 0x80 | |
#define WORD_MASK 0xffffffff | |
#define HALF_MASK 0xffffu | |
#define BYTE_MASK 0xff | |
/* | |
* | |
* Physical memory in the 3B2 is arranged as follows: | |
* | |
* 0x00000000 - 0x0000FFFF: 64KB ROM (32K used) | |
* 0x00040000 - 0x0004FFFF: IO | |
* 0x02000000 - 0x023FFFFF: 4MB RAM ("Mainstore"), | |
* | |
*/ | |
#define PHYS_MEM_BASE 0x2000000 | |
#define ROM_BASE 0 | |
/* IO area */ | |
#define IO_BOTTOM 0x40000 | |
#define IO_TOP 0x50000 | |
/* Register numbers */ | |
#define NUM_FP 9 | |
#define NUM_AP 10 | |
#define NUM_PSW 11 | |
#define NUM_SP 12 | |
#define NUM_PCBP 13 | |
#define NUM_ISP 14 | |
#define NUM_PC 15 | |
/* System board interrupt priority levels */ | |
#define CPU_PIR8_IPL 8 | |
#define CPU_PIR9_IPL 9 | |
#define CPU_ID_IF_IPL 11 | |
#define CPU_IU_DMA_IPL 13 | |
#define CPU_TMR_IPL 15 | |
#define CPU_CM (cpu_km ? L_KERNEL : ((R[NUM_PSW] >> PSW_CM) & 3)) | |
/* Simulator stop codes */ | |
#define STOP_RSRV 1 | |
#define STOP_IBKPT 2 /* Breakpoint encountered */ | |
#define STOP_OPCODE 3 /* Invalid opcode */ | |
#define STOP_IRQ 4 /* Interrupt */ | |
#define STOP_EX 5 /* Exception */ | |
#define STOP_ESTK 6 /* Exception stack too deep */ | |
#define STOP_MMU 7 /* Unimplemented MMU Feature */ | |
#define STOP_POWER 8 /* System power-off */ | |
#define STOP_ERR 9 /* Other error */ | |
/* Exceptional conditions handled within the instruction loop */ | |
#define ABORT_EXC 1 /* CPU exception */ | |
#define ABORT_TRAP 2 /* CPU trap */ | |
/* Contexts for aborts */ | |
#define C_NONE 0 /* No context. Normal handling. */ | |
#define C_NORMAL_GATE_VECTOR 1 | |
#define C_PROCESS_GATE_PCB 2 | |
#define C_PROCESS_OLD_PCB 3 | |
#define C_PROCESS_NEW_PCB 4 | |
#define C_RESET_GATE_VECTOR 5 | |
#define C_RESET_INT_STACK 6 | |
#define C_RESET_NEW_PCB 7 | |
#define C_RESET_SYSTEM_DATA 8 | |
#define C_STACK_FAULT 9 | |
/* Debug flags */ | |
#define READ_MSG 0x001 | |
#define WRITE_MSG 0x002 | |
#define DECODE_MSG 0x004 | |
#define EXECUTE_MSG 0x008 | |
#define INIT_MSG 0x010 | |
#define IRQ_MSG 0x020 | |
#define IO_DBG 0x040 | |
#define TRACE_DBG 0x080 | |
#define ERR_MSG 0x100 | |
/* Data types operated on by instructions. NB: These integer values | |
have meaning when decoding instructions, so this is not just an | |
enum. Please don't change them. */ | |
#define UW 0 /* Unsigned Word */ | |
#define UH 2 /* Unsigned Halfword */ | |
#define BT 3 /* Unsigned Byte */ | |
#define WD 4 /* Signed Word */ | |
#define HW 6 /* Signed Halfword */ | |
#define SB 7 /* Signed Byte */ | |
#define NA -1 | |
/* | |
* Exceptions are described on page 2-66 of the WE32100 manual | |
*/ | |
/* Exception Types */ | |
#define RESET_EXCEPTION 0 | |
#define PROCESS_EXCEPTION 1 | |
#define STACK_EXCEPTION 2 | |
#define NORMAL_EXCEPTION 3 | |
/* Reset Exceptions */ | |
#define OLD_PCB_FAULT 0 | |
#define SYSTEM_DATA_FAULT 1 | |
#define INTERRUPT_STACK_FAULT 2 | |
#define EXTERNAL_RESET 3 | |
#define NEW_PCB_FAULT 4 | |
#define GATE_VECTOR_FAULT 6 | |
/* Processor Exceptions */ | |
#define GATE_PCB_FAULT 1 | |
/* Stack Exceptions */ | |
#define STACK_BOUND 0 | |
#define STACK_FAULT 1 | |
#define INTERRUPT_ID_FETCH 3 | |
/* Normal Exceptions */ | |
#define INTEGER_ZERO_DIVIDE 0 | |
#define TRACE_TRAP 1 | |
#define ILLEGAL_OPCODE 2 | |
#define RESERVED_OPCODE 3 | |
#define INVALID_DESCRIPTOR 4 | |
#define EXTERNAL_MEMORY_FAULT 5 | |
#define N_GATE_VECTOR 6 | |
#define ILLEGAL_LEVEL_CHANGE 7 | |
#define RESERVED_DATATYPE 8 | |
#define INTEGER_OVERFLOW 9 | |
#define PRIVILEGED_OPCODE 10 | |
#define BREAKPOINT_TRAP 14 | |
#define PRIVILEGED_REGISTER 15 | |
#define PSW_ET 0 | |
#define PSW_TM 2u | |
#define PSW_ISC 3u | |
#define PSW_I 7 | |
#define PSW_R 8 | |
#define PSW_PM 9 | |
#define PSW_CM 11 | |
#define PSW_IPL 13 | |
#define PSW_TE 17 | |
#define PSW_C 18 | |
#define PSW_V 19 | |
#define PSW_Z 20 | |
#define PSW_N 21 | |
#define PSW_OE 22 | |
#define PSW_CD 23 | |
#define PSW_QIE 24 | |
#define PSW_CFD 25 | |
/* Access Request types */ | |
#define ACC_MT 0 /* Move Translated */ | |
#define ACC_SPW 1 /* Support processor write */ | |
#define ACC_SPF 3 /* Support processor fetch */ | |
#define ACC_IR 7 /* Interlocked read */ | |
#define ACC_AF 8 /* Address fetch */ | |
#define ACC_OF 9 /* Operand fetch */ | |
#define ACC_W 10 /* Write */ | |
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */ | |
#define ACC_IF 13 /* Instruction fetch */ | |
#define L_KERNEL 0 | |
#define L_EXEC 1 | |
#define L_SUPER 2 | |
#define L_USER 3 | |
#define PSW_ET_MASK 3u | |
#define PSW_TM_MASK (1u << PSW_TM) | |
#define PSW_ISC_MASK (15u << PSW_ISC) | |
#define PSW_I_MASK (1u << PSW_I) | |
#define PSW_R_MASK (1u << PSW_R) | |
#define PSW_PM_MASK (3u << PSW_PM) | |
#define PSW_CM_MASK (3u << PSW_CM) | |
#define PSW_IPL_MASK (15u << PSW_IPL) | |
#define PSW_TE_MASK (1u << PSW_TE) | |
#define PSW_C_MASK (1u << PSW_C) | |
#define PSW_V_MASK (1u << PSW_V) | |
#define PSW_N_MASK (1u << PSW_N) | |
#define PSW_Z_MASK (1u << PSW_Z) | |
#define PSW_OE_MASK (1u << PSW_OE) | |
#define PSW_CD_MASK (1u << PSW_CD) | |
#define PSW_QIE_MASK (1u << PSW_QIE) | |
#define PSW_CFD_MASK (1u << PSW_CFD) | |
#define PSW_CUR_IPL (((R[NUM_PSW] & PSW_IPL_MASK) >> PSW_IPL) & 0xf) | |
#define TODBASE 0x41000 | |
#define TODSIZE 0x40 | |
#define TIMERBASE 0x42000 | |
#define TIMERSIZE 0x20 | |
#define NVRAMBASE 0x43000 | |
#define NVRAMSIZE 0x1000 | |
#define CSRBASE 0x44000 | |
#define CSRSIZE 0x100 | |
#define CSRTIMO 0x8000 /* Bus Timeout Error */ | |
#define CSRPARE 0x4000 /* Memory Parity Error */ | |
#define CSRRRST 0x2000 /* System Reset Request */ | |
#define CSRALGN 0x1000 /* Memory Alignment Fault */ | |
#define CSRLED 0x0800 /* Failure LED */ | |
#define CSRFLOP 0x0400 /* Floppy Motor On */ | |
#define CSRRES 0x0200 /* Reserved */ | |
#define CSRITIM 0x0100 /* Inhibit Timers */ | |
#define CSRIFLT 0x0080 /* Inhibit Faults */ | |
#define CSRCLK 0x0040 /* Clock Interrupt */ | |
#define CSRPIR8 0x0020 /* Programmed Interrupt 8 */ | |
#define CSRPIR9 0x0010 /* Programmed Interrupt 9 */ | |
#define CSRUART 0x0008 /* UART Interrupt */ | |
#define CSRDISK 0x0004 /* Floppy Interrupt */ | |
#define CSRDMA 0x0002 /* DMA Interrupt */ | |
#define CSRIOF 0x0001 /* I/O Board Fail */ | |
#define TIMER_REG_DIVA 0x03 | |
#define TIMER_REG_DIVB 0x07 | |
#define TIMER_REG_DIVC 0x0b | |
#define TIMER_REG_CTRL 0x0f | |
#define TIMER_CLR_LATCH 0x13 | |
/* Clock state bitmasks */ | |
#define CLK_MD 0x0E /* Mode mask */ | |
#define CLK_RW 0x30 /* RW mask */ | |
#define CLK_SC 0xC0 /* SC mask */ | |
#define CLK_LAT 0x00 | |
#define CLK_LSB 0x10 | |
#define CLK_MSB 0x20 | |
#define CLK_LMB 0x30 | |
#define CLK_MD0 0x00 | |
#define CLK_MD1 0x02 | |
#define CLK_MD2 0x04 | |
#define CLK_MD3 0x06 | |
#define CLK_MD4 0x08 | |
#define CLK_MD5 0x0a | |
/* IO area */ | |
#define MEMSIZE_REG 0x4C003 | |
#define CIO_BOTTOM 0x200000 | |
#define CIO_TOP 0x2000000 | |
#define CIO_SLOTS 12 | |
#define CIO_CMDSTAT 0x80 | |
#define CIO_SEQBIT 0x40 | |
#define CIO_INT_DELAY 8000 | |
/* Timer definitions */ | |
#define TMR_CLK 0 /* The clock responsible for IPL 15 interrupts */ | |
#define TPS_CLK 100 /* 100 ticks per second */ | |
/* global symbols from the CPU */ | |
extern jmp_buf save_env; | |
extern uint32 *ROM; | |
extern uint32 *RAM; | |
extern uint32 R[16]; | |
extern REG cpu_reg[]; | |
extern DEVICE cpu_dev; | |
extern UNIT cpu_unit; | |
extern uint8 fault; | |
extern DEBTAB sys_deb_tab[]; | |
extern t_bool cpu_km; | |
/* global symbols from the DMAC */ | |
typedef struct { | |
uint8 page; | |
uint16 addr; /* Original addr */ | |
uint16 wcount; /* Original wcount */ | |
uint16 addr_c; /* Current addr */ | |
int32 wcount_c; /* Current word-count */ | |
uint16 ptr; /* Pointer into memory */ | |
} dma_channel; | |
typedef struct { | |
/* Byte (high/low) flip-flop */ | |
uint8 bff; | |
/* Address and count registers for channels 0-3 */ | |
dma_channel channels[4]; | |
/* DMAC programmable registers */ | |
uint8 command; | |
uint8 mode; | |
uint8 request; | |
uint8 mask; | |
uint8 status; | |
} DMA_STATE; | |
extern DMA_STATE dma_state; | |
static SIM_INLINE uint32 dma_address(uint8 channel, uint32 offset, t_bool r) { | |
uint32 addr; | |
addr = (PHYS_MEM_BASE + dma_state.channels[channel].addr + offset); | |
/* The top bit of the page address is a R/W bit, so we mask it here */ | |
addr |= (uint32) (((uint32)dma_state.channels[channel].page & 0x7f) << 16); | |
return addr; | |
} | |
extern DEVICE dmac_dev; | |
/* global symbols from the CSR */ | |
extern uint16 csr_data; | |
/* global symbols from the timer */ | |
extern int32 tmxr_poll; | |
/* global symbols from the IU */ | |
extern t_bool iu_increment_a; | |
extern t_bool iu_increment_b; | |
extern void increment_modep_a(); | |
extern void increment_modep_b(); | |
/* global symbols from the MMU */ | |
extern t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); | |
extern void mmu_enable(); | |
extern void mmu_disable(); | |
extern uint8 read_b(uint32 va, uint8 acc); | |
extern uint16 read_h(uint32 va, uint8 acc); | |
extern uint32 read_w(uint32 va, uint8 acc); | |
extern void write_b(uint32 va, uint8 val); | |
extern void write_h(uint32 va, uint16 val); | |
extern void write_w(uint32 va, uint32 val); | |
/* Globally scoped CPU functions */ | |
extern void cpu_abort(uint8 et, uint8 isc); | |
extern void cpu_set_irq(uint8 ipl, uint8 id, uint16 csr_flags); | |
extern void cpu_clear_irq(uint8 ipl, uint16 csr_flags); | |
/* global symbols from the IO system */ | |
extern uint32 io_read(uint32 pa, size_t size); | |
extern void io_write(uint32 pa, uint32 val, size_t size); | |
extern void cio_clear(uint8 cid); | |
extern void cio_xfer(); | |
extern uint8 cio_int; | |
extern uint16 cio_ipl; | |
/* Future Use: Global symbols from the PORTS card */ | |
/* extern void ports_express(uint8 cid); */ | |
/* extern void ports_full(uint8 cid); */ | |
/* extern void ports_xfer(uint8 cid); */ | |
#endif |