/* 9900.H ====== */ #ifndef __9900_H__ #define __9900_H__ #include "centry.h" extern uaddr pc,wp; extern u16 *wpptr; extern uword status; // active interrupt pins enum { INTPIN_RESET = 1, INTPIN_LOAD = 2, INTPIN_INTREQ = 4 }; extern u8 intpins9900; void hold9900pin(u8 mask); // interrupt mask from LIMI extern u8 intlevel9900; #define ST_L 0x8000 #define ST_A 0x4000 #define ST_E 0x2000 #define ST_C 0x1000 #define ST_O 0x800 #define ST_P 0x400 #define ST_X 0x200 #define ST_INTLEVEL 0xf /* Fake opcodes for emulation */ enum { OP_DSR = 0xC00, /* if this changes, fix asm equate */ OP_KEYSLOW = 0xD40, OP_DBG = 0xDE0, }; extern void set9900wp(u16 wp); void init9900(void); void emulateloop(void); void setup_status(void); void change9900intmask(u16 mask); u16 fetch(void); void execute(uop op); void contextswitch(uaddr addr); bool verifypc(uaddr addr); bool verifywp(uaddr addr); void setandverifypc(uaddr addr); void setandverifywp(uaddr addr); /******************************************/ #define register(reg) (wpptr[reg]) /* wchange -- change a word in memory at 'addr'. 'prewhat' is done to the word before the operation. 'what' is the operation. 'expr' is the operand, 'status' is the function that deciphers the answer. */ #define wchange(addr,prewhat,what,expr,status) { \ register u16 answer=prewhat (memory_read_word(addr)) what##expr; \ memory_write_word(addr,answer); \ status(answer); \ } /* rchange -- change register 'reg'. 'prewhat' is done to the word before the operation. 'what' is the operation. 'expr' is the operand, 'status' is the function that deciphers the answer. This assumes 'wp' is in range. */ #define rchange(reg,prewhat,what,expr,status) { \ register u16 *raddr=wpptr+reg; \ register int answer=(prewhat (*raddr)) what expr; \ *raddr= answer; status(answer); } \ #define wadd(addr,expr) { \ memory_write_word(addr,setst_add_laeco(memory_read_word(addr),expr)); \ } #define radd(reg,expr) { \ register u16 *raddr = wpptr+reg; \ *raddr=setst_add_laeco(*raddr,expr); } #include "cexit.h" #endif