diff options
author | 2008-05-22 03:09:01 +0000 | |
---|---|---|
committer | 2008-05-22 03:09:01 +0000 | |
commit | 98a8e739479b1339c5de45a1b1c9da3b8060ee15 (patch) | |
tree | d1634d73984bd8b4bec0abe78e6a6c032aefef74 /src/emu/cpu/saturn | |
parent | bb9fec0f865ca0aad2aae637ee379e412dd0399d (diff) |
From: Antoine Mine [mailto:Antoine.Mine@ens.fr]
Subject: saturn CPU patch
Dear MAMEDev,
The attached patch corrects several bugs in the emulation of the saturn
CPU. These corrections are needed to make new HP48 drivers (to be
submitted to MESS imminently) work.
AFAIK, MESS is the only place where this CPU is used, so, the patch
should
not cause any regression in MAME.
The patch is against 0125u1.
Best regards,
-
Antoine Mine
Diffstat (limited to 'src/emu/cpu/saturn')
-rw-r--r-- | src/emu/cpu/saturn/sat.h | 22 | ||||
-rw-r--r-- | src/emu/cpu/saturn/satops.c | 979 | ||||
-rw-r--r-- | src/emu/cpu/saturn/sattable.c | 260 | ||||
-rw-r--r-- | src/emu/cpu/saturn/saturn.c | 308 | ||||
-rw-r--r-- | src/emu/cpu/saturn/saturn.h | 38 | ||||
-rw-r--r-- | src/emu/cpu/saturn/saturnds.c | 250 |
6 files changed, 967 insertions, 890 deletions
diff --git a/src/emu/cpu/saturn/sat.h b/src/emu/cpu/saturn/sat.h deleted file mode 100644 index 8632468dc04..00000000000 --- a/src/emu/cpu/saturn/sat.h +++ /dev/null @@ -1,22 +0,0 @@ -enum { - SATURN_A=1, SATURN_B, SATURN_C, SATURN_D, - SATURN_R0, SATURN_R1, SATURN_R2, SATURN_R3, SATURN_R4, - SATURN_RSTK0, SATURN_RSTK1, SATURN_RSTK2, SATURN_RSTK3, - SATURN_RSTK4, SATURN_RSTK5, SATURN_RSTK6, SATURN_RSTK7, - SATURN_PC, SATURN_D0, SATURN_D1, - - SATURN_P, - SATURN_IN, - SATURN_OUT, - SATURN_CARRY, - SATURN_ST, - SATURN_HST, - - SATURN_EA, - SATURN_NMI_STATE, - SATURN_IRQ_STATE -}; - -#define PEEK_OP(pc) cpu_readop(pc) -#define PEEK_NIBBLE(adr) cpu_readmem_20(adr) - diff --git a/src/emu/cpu/saturn/satops.c b/src/emu/cpu/saturn/satops.c index 578e3036994..da75169565f 100644 --- a/src/emu/cpu/saturn/satops.c +++ b/src/emu/cpu/saturn/satops.c @@ -1,61 +1,86 @@ #define IRQ_ADDRESS 0xf +#define saturn_assert(x) \ + do { if (!(x)) logerror("SATURN%d assertion failed: %s at %s:%i, pc=%05x\n", cpu_getactivecpu(), #x, __FILE__, __LINE__, saturn.pc); } while (0) + INLINE int READ_OP(void) { + UINT8 data; saturn_ICount-=3; - return cpu_readop(saturn.pc++); + data=cpu_readop(saturn.pc); + saturn_assert(data<0x10); + saturn.pc=(saturn.pc+1)&0xfffff; + return data; } INLINE int READ_OP_ARG(void) { + UINT8 data; saturn_ICount-=3; - return cpu_readop_arg(saturn.pc++); + data=cpu_readop_arg(saturn.pc); + saturn_assert(data<0x10); + saturn.pc=(saturn.pc+1)&0xfffff; + return data; } INLINE int READ_OP_ARG8(void) { - return READ_OP_ARG()|(READ_OP_ARG()<<4); + int n0=READ_OP_ARG(); + int n1=READ_OP_ARG(); + return n0|(n1<<4); } INLINE INT8 READ_OP_DIS8(void) { - return READ_OP_ARG()|(READ_OP_ARG()<<4); + return (INT8)READ_OP_ARG8(); } INLINE int READ_OP_ARG12(void) { - return READ_OP_ARG()|(READ_OP_ARG()<<4)|(READ_OP_ARG()<<8); + int n0=READ_OP_ARG(); + int n1=READ_OP_ARG(); + int n2=READ_OP_ARG(); + return n0|(n1<<4)|(n2<<8); } INLINE int READ_OP_DIS12(void) { - int temp=READ_OP_ARG()|(READ_OP_ARG()<<4)|(READ_OP_ARG()<<8); - if (temp&0x800) return -0x1000+temp; - else return temp; + int temp=READ_OP_ARG12(); + if (temp&0x800) temp-=0x1000; + return temp; } INLINE int READ_OP_ARG16(void) { - return READ_OP_ARG()|(READ_OP_ARG()<<4)|(READ_OP_ARG()<<8)|(READ_OP_ARG()<<12); + int n0=READ_OP_ARG(); + int n1=READ_OP_ARG(); + int n2=READ_OP_ARG(); + int n3=READ_OP_ARG(); + return n0|(n1<<4)|(n2<<8)|(n3<<12); } INLINE INT16 READ_OP_DIS16(void) { - return READ_OP_ARG()|(READ_OP_ARG()<<4)|(READ_OP_ARG()<<8)|(READ_OP_ARG()<<12); + return (INT16)READ_OP_ARG16(); } INLINE int READ_OP_ARG20(void) { - return READ_OP_ARG()|(READ_OP_ARG()<<4)|(READ_OP_ARG()<<8) - |(READ_OP_ARG()<<12)|(READ_OP_ARG()<<16); + int n0=READ_OP_ARG(); + int n1=READ_OP_ARG(); + int n2=READ_OP_ARG(); + int n3=READ_OP_ARG(); + int n4=READ_OP_ARG(); + return n0|(n1<<4)|(n2<<8)|(n3<<12)|(n4<<16); } INLINE int READ_NIBBLE(SaturnAdr adr) { - int data; + UINT8 data; saturn_ICount-=3; - data = program_read_byte(adr); - if (saturn.config&&saturn.config->crc) saturn.config->crc(adr, data); + data=program_read_byte(adr&0xfffff); + saturn_assert(data<0x10); + if (saturn.config&&saturn.config->crc) saturn.config->crc(Machine, adr&0xfffff, data); return data; } @@ -71,34 +96,21 @@ INLINE int READ_12(SaturnAdr adr) INLINE int READ_16(SaturnAdr adr) { - return READ_NIBBLE(adr)|(READ_NIBBLE(adr+1)<<4) - |(READ_NIBBLE(adr+2)<<8)|(READ_NIBBLE(adr+3)<<12); + return READ_NIBBLE(adr)|(READ_NIBBLE(adr+1)<<4)|(READ_NIBBLE(adr+2)<<8)|(READ_NIBBLE(adr+3)<<12); } INLINE int READ_20(SaturnAdr adr) { - return READ_NIBBLE(adr)|(READ_NIBBLE(adr+1)<<4) - |(READ_NIBBLE(adr+2)<<8)|(READ_NIBBLE(adr+3)<<12)|(READ_NIBBLE(adr+4)<<16); + return READ_NIBBLE(adr)|(READ_NIBBLE(adr+1)<<4)|(READ_NIBBLE(adr+2)<<8)|(READ_NIBBLE(adr+3)<<12)|(READ_NIBBLE(adr+4)<<16); } INLINE void WRITE_NIBBLE(SaturnAdr adr, SaturnNib nib) { - saturn_ICount -= 3; - program_write_byte(adr, nib); + saturn_ICount-=3; + saturn_assert(nib<0x10); + program_write_byte(adr&0xfffff,nib); } -#ifdef LSB_FIRST -#define S64_BYTE(r, x) saturn.reg[r].b[x] -#define S64_WORD(r, x) saturn.reg[r].w[x] -#define S64_DOUBLE(r, x) saturn.reg[r].d[x] -#else -#define S64_BYTE(r, x) saturn.reg[r].b[7-x] -#define S64_WORD(r, x) saturn.reg[r].w[3-x] -#define S64_DOUBLE(r, x) saturn.reg[r].d[1-x] -#endif - -#define S64_QUAD(r) saturn.reg[r].q - #define BEGIN_B 0 #define COUNT_B 2 #define BEGIN_X 0 @@ -114,46 +126,55 @@ INLINE void WRITE_NIBBLE(SaturnAdr adr, SaturnNib nib) #define BEGIN_W 0 #define COUNT_W 16 -#define S64_READ_NIBBLE(r, x) (((x)&1) ? (S64_BYTE(r, ((x)>>1))>>4) : (S64_BYTE(r, ((x)>>1))&0xf) ) -#define S64_WRITE_NIBBLE(r, x, v) \ - (S64_BYTE(r, ((x)>>1)) = ((x)&1) \ - ?(S64_BYTE(r, ((x)>>1))&0xf)|((v)<<4) \ - :(S64_BYTE(r, ((x)>>1))&0xf0)|(v) ) -#define S64_READ_B(r) S64_BYTE(r,0) -#define S64_WRITE_B(r,v) (S64_BYTE(r,0)=v) +INLINE int S64_READ_X(int r) +{ + return saturn.reg[r][0]|(saturn.reg[r][1]<<4)|(saturn.reg[r][2]<<8); +} -#define S64_READ_XS(r) S64_READ_NIBBLE(r,2) -#define S64_WRITE_XS(r,v) S64_WRITE_NIBBLE(r,2,v) +INLINE int S64_READ_WORD(int r) +{ + return saturn.reg[r][0]|(saturn.reg[r][1]<<4)|(saturn.reg[r][2]<<8)|(saturn.reg[r][3]<<12); +} + +INLINE int S64_READ_A(int r) +{ + return saturn.reg[r][0]|(saturn.reg[r][1]<<4)|(saturn.reg[r][2]<<8)|(saturn.reg[r][3]<<12)|(saturn.reg[r][4]<<16); +} -#define S64_READ_S(r) S64_READ_NIBBLE(r,15) -#define S64_WRITE_S(r,v) S64_WRITE_NIBBLE(r,15,v) +INLINE void S64_WRITE_X(int r, int v) +{ + saturn.reg[r][0]=v&0xf; + saturn.reg[r][1]=(v>>4)&0xf; + saturn.reg[r][2]=(v>>8)&0xf; +} -#define S64_READ_P(r) S64_READ_NIBBLE(r,saturn.p) -#define S64_WRITE_P(r,v) S64_WRITE_NIBBLE(r,saturn.p,v) +INLINE void S64_WRITE_WORD(int r, int v) +{ + saturn.reg[r][0]=v&0xf; + saturn.reg[r][1]=(v>>4)&0xf; + saturn.reg[r][2]=(v>>8)&0xf; + saturn.reg[r][3]=(v>>12)&0xf; +} -#define S64_READ_X(r) (S64_WORD(r,0)&0xfff) -#define S64_WRITE_X(r,v) (S64_WORD(r,0)=(S64_WORD(r,0)&~0xfff)|(v)) +INLINE void S64_WRITE_A(int r, int v) +{ + saturn.reg[r][0]=v&0xf; + saturn.reg[r][1]=(v>>4)&0xf; + saturn.reg[r][2]=(v>>8)&0xf; + saturn.reg[r][3]=(v>>12)&0xf; + saturn.reg[r][4]=(v>>16)&0xf; +} -// for address reg operations -#define S64_READ_WORD(r,nr) S64_WORD(r,nr) -#define S64_WRITE_WORD(r,nr,v) (S64_WORD(r,nr)=v) -#define S64_READ_A(r) (S64_DOUBLE(r,0)&0xfffff) -#define S64_WRITE_A(r,v) (S64_DOUBLE(r,0)=(S64_DOUBLE(r,0)&~0xfffff)|(v)) -#define S64_READ_M(r) ((S64_QUAD(r)>>12)&0xffffffffffffULL) -#define S64_WRITE_M(r,v) (S64_QUAD(r)=(S64_QUAD(r)&~0xffffffffffff000ULL)|((v)<<12)) -#define S64_READ_W(r) S64_QUAD(r) -#define S64_WRITE_W(r,v) (S64_QUAD(r)=(v)) INLINE SaturnAdr saturn_pop(void) { SaturnAdr temp=saturn.rstk[0]; memmove(saturn.rstk, saturn.rstk+1, sizeof(saturn.rstk)-sizeof(saturn.rstk[0])); saturn.rstk[7]=0; - saturn.stackpointer--; return temp; } @@ -161,79 +182,107 @@ INLINE void saturn_push(SaturnAdr adr) { memmove(saturn.rstk+1, saturn.rstk, sizeof(saturn.rstk)-sizeof(saturn.rstk[0])); saturn.rstk[0]=adr; - saturn.stackpointer++; } INLINE void saturn_interrupt_on(void) { - + LOG(( "SATURN#%d at %05x: INTON\n", cpu_getactivecpu(), saturn.pc-4 )); + saturn.irq_enable=1; + if (saturn.irq_state) + { + LOG(( "SATURN#%d set_irq_line(ASSERT)\n", cpu_getactivecpu())); + saturn.pending_irq=1; + } } INLINE void saturn_interrupt_off(void) { - + LOG(( "SATURN#%d at %05x: INTOFF\n", cpu_getactivecpu(), saturn.pc-4 )); + saturn.irq_enable=0; } INLINE void saturn_reset_interrupt(void) { - + LOG(( "SATURN#%d at %05x: RSI\n", cpu_getactivecpu(), saturn.pc-5 )); + if (saturn.config&&saturn.config->rsi) saturn.config->rsi(Machine); } INLINE void saturn_mem_reset(void) { - if (saturn.config->reset) saturn.config->reset(); + if (saturn.config&&saturn.config->reset) saturn.config->reset(Machine); } INLINE void saturn_mem_config(void) { - if (saturn.config->config) saturn.config->config(S64_READ_A(C)); + if (saturn.config&&saturn.config->config) saturn.config->config(Machine, S64_READ_A(C)); } INLINE void saturn_mem_unconfig(void) { - if (saturn.config->unconfig) saturn.config->unconfig(S64_READ_A(C)); + if (saturn.config&&saturn.config->unconfig) saturn.config->unconfig(Machine, S64_READ_A(C)); } -INLINE int saturn_mem_id(void) +int monitor_id; + +INLINE void saturn_mem_id(void) { - if (saturn.config->id) return saturn.config->id(); - return 0; + int id=0; + if (saturn.config&&saturn.config->id) id=saturn.config->id(Machine); + S64_WRITE_A(C,id); + monitor_id = id; } INLINE void saturn_shutdown(void) { + saturn.sleeping=1; + saturn.irq_enable=1; + LOG(( "SATURN#%d at %05x: SHUTDN\n", cpu_getactivecpu(), saturn.pc-3 )); } INLINE void saturn_bus_command_b(void) { + logerror( "SATURN#%d at %05x: BUSCB opcode not handled\n", cpu_getactivecpu(), saturn.pc-4 ); } INLINE void saturn_bus_command_c(void) { + logerror( "SATURN#%d at %05x: BUSCC opcode not handled\n", cpu_getactivecpu(), saturn.pc-3 ); } INLINE void saturn_bus_command_d(void) { + logerror( "SATURN#%d at %05x: BUSCD opcode not handled\n", cpu_getactivecpu(), saturn.pc-4 ); } INLINE void saturn_serial_request(void) { + logerror( "SATURN#%d at %05x: SREQ? opcode not handled\n", cpu_getactivecpu(), saturn.pc-3 ); } INLINE void saturn_out_c(void) { - if (saturn.config&&saturn.config->out) saturn.config->out(S64_READ_X(C)); + saturn.out=S64_READ_X(C); + if (saturn.config&&saturn.config->out) saturn.config->out(Machine, saturn.out); } INLINE void saturn_out_cs(void) { - if (saturn.config&&saturn.config->out) - saturn.config->out(S64_READ_NIBBLE(C,0)|(saturn.out&0xff0)); + saturn.out=(saturn.out&0xff0)|saturn.reg[C][0]; + if (saturn.config&&saturn.config->out) saturn.config->out(Machine, saturn.out); } +int monitor_in; + INLINE void saturn_in(int reg) { - if (saturn.config&&saturn.config->in) S64_WORD(reg,0)=saturn.config->in(); + int in = 0; + saturn_assert(reg>=0 && reg<9); + if (!(saturn.pc&1)) + logerror( "SATURN#%d at %05x: reg=IN opcode at odd addresse\n", + cpu_getactivecpu(), saturn.pc-3 ); + if (saturn.config&&saturn.config->in) in = saturn.config->in(Machine); + S64_WRITE_WORD(reg,in); + monitor_in = in; } INLINE void saturn_sethex(void) { saturn.decimal=0; } @@ -242,142 +291,69 @@ INLINE void saturn_setdec(void) { saturn.decimal=1; } /* st related */ INLINE void saturn_clear_st(void) { - saturn.st=0; + saturn.st&=0xf000; } INLINE void saturn_st_to_c(void) { - S64_WRITE_X(C, saturn.st&0xfff); + S64_WRITE_X(C,saturn.st); } INLINE void saturn_c_to_st(void) { - saturn.st=(saturn.st&~0xfff)|S64_READ_X(C); + saturn.st=(saturn.st&0xf000)|(S64_READ_X(C)); } INLINE void saturn_exchange_c_st(void) { - int t=saturn.st&0xfff; - saturn.st=(saturn.st&~0xfff)|S64_READ_X(C); - S64_WRITE_X(C, t); + int t=saturn.st; + saturn.st=(t&0xf000)|(S64_READ_X(C)); + S64_WRITE_X(C,t); } -INLINE void saturn_st_clear_bit(void) +INLINE void saturn_jump_after_test(void) { - switch(READ_OP_ARG()) { - case 0: saturn.st&=~1;break; - case 1: saturn.st&=~2;break; - case 2: saturn.st&=~4;break; - case 3: saturn.st&=~8;break; - case 4: saturn.st&=~0x10;break; - case 5: saturn.st&=~0x20;break; - case 6: saturn.st&=~0x40;break; - case 7: saturn.st&=~0x80;break; - case 8: saturn.st&=~0x100;break; - case 9: saturn.st&=~0x200;break; - case 0xa: saturn.st&=~0x400;break; - case 0xb: saturn.st&=~0x800;break; - case 0xc: saturn.st&=~0x1000;break; - case 0xd: saturn.st&=~0x2000;break; - case 0xe: saturn.st&=~0x4000;break; - case 0xf: saturn.st&=~0x8000;break; + int adr=READ_OP_DIS8(); + if (saturn.carry) { + if (adr==0) { + saturn.pc=saturn_pop(); + } else { + saturn.pc=(saturn.pc+adr-2)&0xfffff; + } + change_pc(saturn.pc); } } +INLINE void saturn_st_clear_bit(void) +{ + saturn.st &= ~(1<<(READ_OP_ARG())); +} INLINE void saturn_st_set_bit(void) { - switch(READ_OP_ARG()) { - case 0: saturn.st|=1;break; - case 1: saturn.st|=2;break; - case 2: saturn.st|=4;break; - case 3: saturn.st|=8;break; - case 4: saturn.st|=0x10;break; - case 5: saturn.st|=0x20;break; - case 6: saturn.st|=0x40;break; - case 7: saturn.st|=0x80;break; - case 8: saturn.st|=0x100;break; - case 9: saturn.st|=0x200;break; - case 0xa: saturn.st|=0x400;break; - case 0xb: saturn.st|=0x800;break; - case 0xc: saturn.st|=0x1000;break; - case 0xd: saturn.st|=0x2000;break; - case 0xe: saturn.st|=0x4000;break; - case 0xf: saturn.st|=0x8000;break; - } + saturn.st |= (1<<(READ_OP_ARG())); } INLINE void saturn_st_jump_bit_clear(void) { - int adr; - switch(READ_OP_ARG()) { - case 0: saturn.carry=!saturn.st&1;break; - case 1: saturn.carry=!saturn.st&2;break; - case 2: saturn.carry=!saturn.st&4;break; - case 3: saturn.carry=!saturn.st&8;break; - case 4: saturn.carry=!saturn.st&0x10;break; - case 5: saturn.carry=!saturn.st&0x20;break; - case 6: saturn.carry=!saturn.st&0x40;break; - case 7: saturn.carry=!saturn.st&0x80;break; - case 8: saturn.carry=!saturn.st&0x100;break; - case 9: saturn.carry=!saturn.st&0x200;break; - case 0xa: saturn.carry=!saturn.st&0x400;break; - case 0xb: saturn.carry=!saturn.st&0x800;break; - case 0xc: saturn.carry=!saturn.st&0x1000;break; - case 0xd: saturn.carry=!saturn.st&0x2000;break; - case 0xe: saturn.carry=!saturn.st&0x4000;break; - case 0xf: saturn.carry=!saturn.st&0x8000;break; - } - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn.carry=!((saturn.st>>(READ_OP_ARG()))&1); + saturn_jump_after_test(); } INLINE void saturn_st_jump_bit_set(void) { - int adr; - switch(READ_OP_ARG()) { - case 0: saturn.carry=saturn.st&1;break; - case 1: saturn.carry=saturn.st&2;break; - case 2: saturn.carry=saturn.st&4;break; - case 3: saturn.carry=saturn.st&8;break; - case 4: saturn.carry=saturn.st&0x10;break; - case 5: saturn.carry=saturn.st&0x20;break; - case 6: saturn.carry=saturn.st&0x40;break; - case 7: saturn.carry=saturn.st&0x80;break; - case 8: saturn.carry=saturn.st&0x100;break; - case 9: saturn.carry=saturn.st&0x200;break; - case 0xa: saturn.carry=saturn.st&0x400;break; - case 0xb: saturn.carry=saturn.st&0x800;break; - case 0xc: saturn.carry=saturn.st&0x1000;break; - case 0xd: saturn.carry=saturn.st&0x2000;break; - case 0xe: saturn.carry=saturn.st&0x4000;break; - case 0xf: saturn.carry=saturn.st&0x8000;break; - } - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn.carry=(saturn.st>>(READ_OP_ARG()))&1; + saturn_jump_after_test(); } INLINE void saturn_hst_clear_bits(void) { - saturn.hst&=~READ_OP_ARG(); + saturn.hst&=~(READ_OP_ARG()); } INLINE void saturn_hst_bits_cleared(void) { - saturn.carry=!(saturn.hst&READ_OP_ARG()); + saturn.carry=!(saturn.hst&(READ_OP_ARG())); + saturn_jump_after_test(); } /* p related */ @@ -385,31 +361,31 @@ INLINE void saturn_exchange_p(void) { int nr=READ_OP_ARG(); int t=saturn.p; - saturn.p=S64_READ_NIBBLE(C,nr); - S64_WRITE_NIBBLE(C,nr,t); + saturn.p=saturn.reg[C][nr]; + saturn.reg[C][nr]=t; } INLINE void saturn_p_to_c(void) { int nr=READ_OP_ARG(); - S64_WRITE_NIBBLE(C,nr,saturn.p); + saturn.reg[C][nr]=saturn.p; } INLINE void saturn_c_to_p(void) { int nr=READ_OP_ARG(); - saturn.p=S64_READ_NIBBLE(C,nr); + saturn.p=saturn.reg[C][nr]; } INLINE void saturn_dec_p(void) { saturn.carry=saturn.p==0; - saturn.p=saturn.p-1; + saturn.p=(saturn.p-1)&0xf; } INLINE void saturn_inc_p(void) { - saturn.p=saturn.p+1; + saturn.p=(saturn.p+1)&0xf; saturn.carry=saturn.p==0; } @@ -420,39 +396,19 @@ INLINE void saturn_load_p(void) INLINE void saturn_p_equals(void) { - int nr=READ_OP_ARG(); - int adr; - saturn.carry=saturn.p==nr; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn.carry=saturn.p==(READ_OP_ARG()); + saturn_jump_after_test(); } INLINE void saturn_p_not_equals(void) { - int nr=READ_OP_ARG(); - int adr; - saturn.carry=saturn.p!=nr; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn.carry=saturn.p!=(READ_OP_ARG()); + saturn_jump_after_test(); } INLINE void saturn_ca_p_1(void) { - int a=S64_READ_A(C)+1+saturn.p; + int a=(S64_READ_A(C))+1+saturn.p; saturn.carry=a>=0x100000; S64_WRITE_A(C,a&0xfffff); } @@ -461,13 +417,15 @@ INLINE void saturn_load_reg(int reg) { int count=READ_OP_ARG(); int pos=saturn.p; + saturn_assert(reg>=0 && reg<9); for (; count>=0; count--, pos=(pos+1)&0xf ) { - S64_WRITE_NIBBLE( reg, pos, READ_OP_ARG()); + saturn.reg[reg][pos]=READ_OP_ARG(); } } INLINE void saturn_jump(int adr, int jump) { + saturn_assert(adr>=0 && adr<0x100000); if (jump) { saturn.pc=adr; saturn_ICount-=10; @@ -477,6 +435,7 @@ INLINE void saturn_jump(int adr, int jump) INLINE void saturn_call(int adr) { + saturn_assert(adr>=0 && adr<0x100000); saturn_push(saturn.pc); saturn.pc=adr; // saturn_ICount-=10; @@ -510,6 +469,8 @@ INLINE void saturn_return_carry_clear(void) INLINE void saturn_return_interrupt(void) { + LOG(( "SATURN#%d at %05x: RTI\n", cpu_getactivecpu(), saturn.pc-2 )); + saturn.in_irq=0; /* set to 1 when an IRQ is taken */ saturn.pc=saturn_pop(); // saturn_ICount-=10; change_pc(saturn.pc); @@ -535,254 +496,172 @@ INLINE void saturn_push_c(void) INLINE void saturn_indirect_jump(int reg) { + saturn_assert(reg>=0 && reg<9); saturn.pc=READ_20(S64_READ_A(reg)); change_pc(saturn.pc); } INLINE void saturn_equals_zero(int reg, int begin, int count) { - int i, t,adr; + int i, t; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=1; for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - if (t!=0) break; + t=saturn.reg[reg][begin+i]; + if (t!=0) { saturn.carry=0; break; } saturn_ICount-=2; } - saturn.carry=i==count; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn_jump_after_test(); } INLINE void saturn_equals(int reg, int begin, int count, int right) { - int i, t,t2,adr; + int i, t,t2; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=1; for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t2=S64_READ_NIBBLE(right, (begin+i)&0xf ); - if (t!=t2) break; + t=saturn.reg[reg][begin+i]; + t2=saturn.reg[right][begin+i]; + if (t!=t2) { saturn.carry=0; break; } saturn_ICount-=2; } - saturn.carry=i==count; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn_jump_after_test(); } INLINE void saturn_not_equals_zero(int reg, int begin, int count) { - int i, t,adr; + int i, t; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - if (t==0) break; + t=saturn.reg[reg][begin+i]; + if (t!=0) { saturn.carry=1; break; } saturn_ICount-=2; } - saturn.carry=i==count; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn_jump_after_test(); } INLINE void saturn_not_equals(int reg, int begin, int count, int right) { - int i, t,t2,adr; + int i, t,t2; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t2=S64_READ_NIBBLE(right, (begin+i)&0xf ); - if (t==t2) break; + t=saturn.reg[reg][begin+i]; + t2=saturn.reg[right][begin+i]; + if (t!=t2) { saturn.carry=1; break; } saturn_ICount-=2; } - saturn.carry=i==count; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn_jump_after_test(); } INLINE void saturn_greater(int reg, int begin, int count, int right) { - int i, t,t2,adr; - for (i=count; i>=0; i--) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t2=S64_READ_NIBBLE(right, (begin+i)&0xf ); - if (t<=t2) break; + int i, t,t2; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; + for (i=count-1; i>=0; i--) { + t=saturn.reg[reg][begin+i]; + t2=saturn.reg[right][begin+i]; + if (t>t2) { saturn.carry=1; break; } + if (t<t2) break; saturn_ICount-=2; } - saturn.carry=i<0; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn_jump_after_test(); } INLINE void saturn_greater_equals(int reg, int begin, int count, int right) { - int i, t,t2,adr; - for (i=count; i>=0; i--) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t2=S64_READ_NIBBLE(right, (begin+i)&0xf ); - if (t<t2) break; + int i, t,t2; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=1; + for (i=count-1; i>=0; i--) { + t=saturn.reg[reg][begin+i]; + t2=saturn.reg[right][begin+i]; + if (t<t2) { saturn.carry=0; break; } + if (t>t2) break; saturn_ICount-=2; } - saturn.carry=i<0; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn_jump_after_test(); } INLINE void saturn_smaller_equals(int reg, int begin, int count, int right) { - int i, t,t2,adr; - for (i=count; i>=0; i--) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t2=S64_READ_NIBBLE(right, (begin+i)&0xf ); - if (t>t2) break; + int i, t,t2; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=1; + for (i=count-1; i>=0; i--) { + t=saturn.reg[reg][begin+i]; + t2=saturn.reg[right][begin+i]; + if (t>t2) { saturn.carry=0; break; } + if (t<t2) break; saturn_ICount-=2; } - saturn.carry=i<0; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn_jump_after_test(); } INLINE void saturn_smaller(int reg, int begin, int count, int right) { - int i, t,t2,adr; - for (i=count; i>=0; i--) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t2=S64_READ_NIBBLE(right, (begin+i)&0xf ); - if (t>=t2) break; + int i, t,t2; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; + for (i=count-1; i>=0; i--) { + t=saturn.reg[reg][begin+i]; + t2=saturn.reg[right][begin+i]; + if (t<t2) { saturn.carry=1; break; } + if (t>t2) break; saturn_ICount-=2; } - saturn.carry=i<0; - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + saturn_jump_after_test(); } INLINE void saturn_jump_bit_clear(int reg) { - int adr; - switch(READ_OP_ARG()) { - case 0: saturn.carry=!(S64_BYTE( reg, 0)&1);break; - case 1: saturn.carry=!(S64_BYTE( reg, 0)&2);break; - case 2: saturn.carry=!(S64_BYTE( reg, 0)&4);break; - case 3: saturn.carry=!(S64_BYTE( reg, 0)&8);break; - case 4: saturn.carry=!(S64_BYTE( reg, 0)&0x10);break; - case 5: saturn.carry=!(S64_BYTE( reg, 0)&0x20);break; - case 6: saturn.carry=!(S64_BYTE( reg, 0)&0x40);break; - case 7: saturn.carry=!(S64_BYTE( reg, 0)&0x80);break; - case 8: saturn.carry=!(S64_BYTE( reg, 1)&1);break; - case 9: saturn.carry=!(S64_BYTE( reg, 1)&2);break; - case 0xa: saturn.carry=!(S64_BYTE( reg, 1)&4);break; - case 0xb: saturn.carry=!(S64_BYTE( reg, 1)&8);break; - case 0xc: saturn.carry=!(S64_BYTE( reg, 1)&0x10);break; - case 0xd: saturn.carry=!(S64_BYTE( reg, 1)&0x20);break; - case 0xe: saturn.carry=!(S64_BYTE( reg, 1)&0x40);break; - case 0xf: saturn.carry=!(S64_BYTE( reg, 1)&0x80);break; - } - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + int op=READ_OP_ARG(); + saturn_assert(reg>=0 && reg<9); + saturn.carry=!((saturn.reg[reg][op>>2]>>(op&3))&1); + saturn_jump_after_test(); } INLINE void saturn_jump_bit_set(int reg) { - int adr; - switch(READ_OP_ARG()) { - case 0: saturn.carry=S64_BYTE( reg, 0)&1;break; - case 1: saturn.carry=S64_BYTE( reg, 0)&2;break; - case 2: saturn.carry=S64_BYTE( reg, 0)&4;break; - case 3: saturn.carry=S64_BYTE( reg, 0)&8;break; - case 4: saturn.carry=S64_BYTE( reg, 0)&0x10;break; - case 5: saturn.carry=S64_BYTE( reg, 0)&0x20;break; - case 6: saturn.carry=S64_BYTE( reg, 0)&0x40;break; - case 7: saturn.carry=S64_BYTE( reg, 0)&0x80;break; - case 8: saturn.carry=S64_BYTE( reg, 1)&1;break; - case 9: saturn.carry=S64_BYTE( reg, 1)&2;break; - case 0xa: saturn.carry=S64_BYTE( reg, 1)&4;break; - case 0xb: saturn.carry=S64_BYTE( reg, 1)&8;break; - case 0xc: saturn.carry=S64_BYTE( reg, 1)&0x10;break; - case 0xd: saturn.carry=S64_BYTE( reg, 1)&0x20;break; - case 0xe: saturn.carry=S64_BYTE( reg, 1)&0x40;break; - case 0xf: saturn.carry=S64_BYTE( reg, 1)&0x80;break; - } - adr=READ_OP_DIS8(); - if (saturn.carry) { - if (adr==0) { - saturn.pc=saturn_pop(); - } else { - saturn.pc=(saturn.pc+adr-2)&0xfffff; - } - change_pc(saturn.pc); - } + int op=READ_OP_ARG(); + saturn_assert(reg>=0 && reg<9); + saturn.carry=(saturn.reg[reg][op>>2]>>(op&3))&1; + saturn_jump_after_test(); } INLINE void saturn_load_pc(int reg) { + saturn_assert(reg>=0 && reg<9); saturn.pc=S64_READ_A(reg); change_pc(saturn.pc); } INLINE void saturn_store_pc(int reg) { + saturn_assert(reg>=0 && reg<9); S64_WRITE_A(reg,saturn.pc); } INLINE void saturn_exchange_pc(int reg) { int temp=saturn.pc; + saturn_assert(reg>=0 && reg<9); saturn.pc=S64_READ_A(reg); change_pc(saturn.pc); S64_WRITE_A(reg, temp); @@ -793,6 +672,8 @@ INLINE void saturn_exchange_pc(int reg) *************************************************************************************/ INLINE void saturn_load_adr(int reg, int nibbles) { + saturn_assert(reg>=0 && reg<2); + saturn_assert(nibbles==2 || nibbles==4 || nibbles==5); switch (nibbles) { case 5: saturn.d[reg]=READ_OP_ARG20(); @@ -809,6 +690,7 @@ INLINE void saturn_load_adr(int reg, int nibbles) INLINE void saturn_add_adr(int reg) { int t=saturn.d[reg]+READ_OP_ARG()+1; + saturn_assert(reg>=0 && reg<2); saturn.d[reg]=t&0xfffff; saturn.carry=t>=0x100000; } @@ -816,33 +698,44 @@ INLINE void saturn_add_adr(int reg) INLINE void saturn_sub_adr(int reg) { int t=saturn.d[reg]-READ_OP_ARG()-1; + saturn_assert(reg>=0 && reg<2); saturn.d[reg]=t&0xfffff; saturn.carry=t<0; } INLINE void saturn_adr_to_reg(int adr, int reg) { + saturn_assert(reg>=0 && reg<9); + saturn_assert(adr>=0 && adr<2); S64_WRITE_A(reg,saturn.d[adr]); } INLINE void saturn_reg_to_adr(int reg, int adr) { + saturn_assert(reg>=0 && reg<9); + saturn_assert(adr>=0 && adr<2); saturn.d[adr]=S64_READ_A(reg); } INLINE void saturn_adr_to_reg_word(int adr, int reg) { - S64_WRITE_WORD(reg,0,saturn.d[adr]&0xffff); + saturn_assert(reg>=0 && reg<9); + saturn_assert(adr>=0 && adr<2); + S64_WRITE_WORD(reg,saturn.d[adr]&0xffff); } INLINE void saturn_reg_to_adr_word(int reg, int adr) { - saturn.d[adr]=(saturn.d[adr]&0xf0000)|S64_READ_WORD(reg,0); + saturn_assert(reg>=0 && reg<9); + saturn_assert(adr>=0 && adr<2); + saturn.d[adr]=(saturn.d[adr]&0xf0000)|S64_READ_WORD(reg); } INLINE void saturn_exchange_adr_reg(int adr, int reg) { int temp=saturn.d[adr]; + saturn_assert(reg>=0 && reg<9); + saturn_assert(adr>=0 && adr<2); saturn.d[adr]=S64_READ_A(reg); S64_WRITE_A(reg,temp); } @@ -850,15 +743,20 @@ INLINE void saturn_exchange_adr_reg(int adr, int reg) INLINE void saturn_exchange_adr_reg_word(int adr, int reg) { int temp=saturn.d[adr]&0xffff; - saturn.d[adr]=(saturn.d[adr]&0xf0000)|S64_READ_WORD(reg,0); - S64_WRITE_WORD(reg,0,temp); + saturn_assert(reg>=0 && reg<9); + saturn_assert(adr>=0 && adr<2); + saturn.d[adr]=(saturn.d[adr]&0xf0000)|S64_READ_WORD(reg); + S64_WRITE_WORD(reg,temp); } INLINE void saturn_load_nibbles(int reg, int begin, int count, int adr) { int i; + saturn_assert(reg>=0 && reg<9); + saturn_assert(adr>=0 && adr<2); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - S64_WRITE_NIBBLE(reg,(begin+i)&0xf,READ_NIBBLE(saturn.d[adr]+i) ); + saturn.reg[reg][begin+i]=READ_NIBBLE(saturn.d[adr]+i); saturn_ICount-=2; } } @@ -866,54 +764,27 @@ INLINE void saturn_load_nibbles(int reg, int begin, int count, int adr) INLINE void saturn_store_nibbles(int reg, int begin, int count, int adr) { int i; + saturn_assert(reg>=0 && reg<9); + saturn_assert(adr>=0 && adr<2); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - WRITE_NIBBLE(saturn.d[adr]+i,S64_READ_NIBBLE(reg,(begin+i)&0xf) ); + WRITE_NIBBLE((saturn.d[adr]+i)&0xfffff,saturn.reg[reg][begin+i]); saturn_ICount-=2; } } INLINE void saturn_clear_bit(int reg) { - switch(READ_OP_ARG()) { - case 0: S64_BYTE( reg, 0)&=~1;break; - case 1: S64_BYTE( reg, 0)&=~2;break; - case 2: S64_BYTE( reg, 0)&=~4;break; - case 3: S64_BYTE( reg, 0)&=~8;break; - case 4: S64_BYTE( reg, 0)&=~0x10;break; - case 5: S64_BYTE( reg, 0)&=~0x20;break; - case 6: S64_BYTE( reg, 0)&=~0x40;break; - case 7: S64_BYTE( reg, 0)&=~0x80;break; - case 8: S64_BYTE( reg, 1)&=~1;break; - case 9: S64_BYTE( reg, 1)&=~2;break; - case 0xa: S64_BYTE( reg, 1)&=~4;break; - case 0xb: S64_BYTE( reg, 1)&=~8;break; - case 0xc: S64_BYTE( reg, 1)&=~0x10;break; - case 0xd: S64_BYTE( reg, 1)&=~0x20;break; - case 0xe: S64_BYTE( reg, 1)&=~0x40;break; - case 0xf: S64_BYTE( reg, 1)&=~0x80;break; - } + int arg=READ_OP_ARG(); + saturn_assert(reg>=0 && reg<9); + saturn.reg[reg][arg>>2]&=~(1<<(arg&3)); } INLINE void saturn_set_bit(int reg) { - switch(READ_OP_ARG()) { - case 0: S64_BYTE( reg, 0)|=1;break; - case 1: S64_BYTE( reg, 0)|=2;break; - case 2: S64_BYTE( reg, 0)|=4;break; - case 3: S64_BYTE( reg, 0)|=8;break; - case 4: S64_BYTE( reg, 0)|=0x10;break; - case 5: S64_BYTE( reg, 0)|=0x20;break; - case 6: S64_BYTE( reg, 0)|=0x40;break; - case 7: S64_BYTE( reg, 0)|=0x80;break; - case 8: S64_BYTE( reg, 1)|=1;break; - case 9: S64_BYTE( reg, 1)|=2;break; - case 0xa: S64_BYTE( reg, 1)|=4;break; - case 0xb: S64_BYTE( reg, 1)|=8;break; - case 0xc: S64_BYTE( reg, 1)|=0x10;break; - case 0xd: S64_BYTE( reg, 1)|=0x20;break; - case 0xe: S64_BYTE( reg, 1)|=0x40;break; - case 0xf: S64_BYTE( reg, 1)|=0x80;break; - } + int arg=READ_OP_ARG(); + saturn_assert(reg>=0 && reg<9); + saturn.reg[reg][arg>>2]|=1<<(arg&3); } /**************************************************************************** @@ -922,8 +793,10 @@ INLINE void saturn_set_bit(int reg) INLINE void saturn_clear(int reg, int begin, int count) { int i; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, 0); + saturn.reg[reg][begin+i]=0; saturn_ICount-=2; } } @@ -935,10 +808,13 @@ INLINE void saturn_exchange(int left, int begin, int count, int right) { int i; SaturnNib temp; + saturn_assert(left>=0 && left<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - temp=S64_READ_NIBBLE(left,(begin+i)&0xf); - S64_WRITE_NIBBLE(left, (begin+i)&0xf, S64_READ_NIBBLE(right,(begin+i)&0xf)); - S64_WRITE_NIBBLE(right, (begin+i)&0xf, temp); + temp=saturn.reg[left][begin+i]; + saturn.reg[left][begin+i]=saturn.reg[right][begin+i]; + saturn.reg[right][begin+i]=temp; saturn_ICount-=2; } } @@ -949,8 +825,11 @@ INLINE void saturn_exchange(int left, int begin, int count, int right) INLINE void saturn_copy(int dest, int begin, int count, int src) { int i; + saturn_assert(dest>=0 && dest<9); + saturn_assert(src>=0 && src<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - S64_WRITE_NIBBLE(dest, (begin+i)&0xf, S64_READ_NIBBLE(src, (begin+i)&0xf)); + saturn.reg[dest][begin+i]=saturn.reg[src][begin+i]; saturn_ICount-=2; } } @@ -960,32 +839,48 @@ INLINE void saturn_copy(int dest, int begin, int count, int src) ****************************************************************************/ INLINE void saturn_add(int reg, int begin, int count, int right) { - int i, t=0; + int i, t; + int base=saturn.decimal?10:16; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i<count; i++) { - if (t>0x10) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf)+1; - } else { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf); + t=saturn.reg[reg][begin+i]; + t+=saturn.reg[right][begin+i]; + t+=saturn.carry; + if (t>=base) { + saturn.carry=1; + t-=base; } - t+=S64_READ_NIBBLE(right, (begin+i)&0xf ); - S64_WRITE_NIBBLE(reg, (begin+i)&0xf , t&0x0f); + else saturn.carry=0; + saturn_assert(t>=0); saturn_assert(t<base); + saturn.reg[reg][begin+i]=t&0xf; saturn_ICount-=2; } - saturn.carry=t==0x10; } INLINE void saturn_add_const(int reg, int begin, int count, SaturnNib right) { - int i, t=0; + int i, t; + int base=saturn.decimal?10:16; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn_assert(count>1 || !saturn.decimal); /* SATURN bug */ for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf); - t+=right; - right=(right>>4)+1; - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, t&0x0f); + t=saturn.reg[reg][begin+i]; + t+=(right&0xf); + right>>=4; + if (t>=base) { + right++; + t-=base; + } + saturn_assert(t>=0); saturn_assert(t<base); + saturn.reg[reg][begin+i]=t&0xf; saturn_ICount-=2; - if (t<0x10) break; + if (!right) break; } - saturn.carry=t>=0x10; + saturn.carry=right>0; } /**************************************************************************** @@ -993,32 +888,48 @@ INLINE void saturn_add_const(int reg, int begin, int count, SaturnNib right) ****************************************************************************/ INLINE void saturn_sub(int reg, int begin, int count, int right) { - int i, t=0; + int i, t; + int base=saturn.decimal?10:16; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i<count; i++) { - if (t>0x10) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf)-1; - } else { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); + t=saturn.reg[reg][begin+i]; + t-=saturn.reg[right][begin+i]; + t-=saturn.carry; + if (t<0) { + saturn.carry=1; + t+=base; } - t-=S64_READ_NIBBLE(right, (begin+i)&0xf ); - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, t&0x0f); + else saturn.carry=0; + saturn_assert(t>=0); saturn_assert(t<base); + saturn.reg[reg][begin+i]=t&0xf; saturn_ICount-=2; } - saturn.carry=t<0; } INLINE void saturn_sub_const(int reg, int begin, int count, int right) { - int i, t=0; + int i, t; + int base=saturn.decimal?10:16; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn_assert(count>1 || !saturn.decimal); /* SATURN bug */ for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t-=right; - right=(right>>4)+1; - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, t&0x0f); + t=saturn.reg[reg][begin+i]; + t-=(right&0xf); + right>>=4; + if (t<0) { + right++; + t+=base; + } + saturn_assert(t>=0); saturn_assert(t<base); + saturn.reg[reg][begin+i]=t&0xf; saturn_ICount-=2; - if (t>=0) break; + if (!right) break; } - saturn.carry=t<0; + saturn.carry=right>0; } /**************************************************************************** @@ -1026,15 +937,25 @@ INLINE void saturn_sub_const(int reg, int begin, int count, int right) ****************************************************************************/ INLINE void saturn_sub2(int reg, int begin, int count, int right) { - int i, t=0; + int i, t; + int base=saturn.decimal?10:16; + saturn_assert(reg>=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t=S64_READ_NIBBLE(right, i)-t; - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, t&0x0f); + t=saturn.reg[right][begin+i]; + t-=saturn.reg[reg][begin+i]; + t-=saturn.carry; + if (t<0) { + saturn.carry=1; + t+=base; + } + else saturn.carry=0; + saturn_assert(t>=0); saturn_assert(t<base); + saturn.reg[reg][begin+i]=t&0xf; saturn_ICount-=2; - if (t>=0) break; } - saturn.carry=t<0; } /**************************************************************************** @@ -1043,13 +964,17 @@ INLINE void saturn_sub2(int reg, int begin, int count, int right) INLINE void saturn_increment(int reg, int begin, int count) { int i, t=0; + int base=saturn.decimal?10:16; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t++; - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, t&0x0f); saturn_ICount-=2; - if (t!=0x10) break; + t=saturn.reg[reg][begin+i]; + t++; + if (t>=base) saturn.reg[reg][begin+i]=t-base; + else { saturn.reg[reg][begin+i]=t; break; } } + saturn.carry=t>=base; } /**************************************************************************** @@ -1058,14 +983,17 @@ INLINE void saturn_increment(int reg, int begin, int count) INLINE void saturn_decrement(int reg, int begin, int count) { int i, t=0; + int base=saturn.decimal?10:16; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t=(t-1)&0xf; - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, t); saturn_ICount-=2; - if (t!=0) break; + t=saturn.reg[reg][begin+i]; + t--; + if (t<0) saturn.reg[reg][begin+i]=t+base; + else { saturn.reg[reg][begin+i]=t; break; } } - saturn.carry=t==0; + saturn.carry=t<0; } /**************************************************************************** @@ -1074,11 +1002,12 @@ INLINE void saturn_decrement(int reg, int begin, int count) INLINE void saturn_invert(int reg, int begin, int count) { int i; - SaturnNib n; - saturn.carry=1; + int max=saturn.decimal?9:15; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i<count; i++) { - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, (n=S64_READ_NIBBLE(reg,(begin+i)&0xf)) ^ 0xf); - saturn.carry=saturn.carry && (n==0); + saturn.reg[reg][begin+i]=(max-saturn.reg[reg][begin+i])&0xf; saturn_ICount-=2; } } @@ -1086,16 +1015,22 @@ INLINE void saturn_invert(int reg, int begin, int count) /**************************************************************************** negate (2 complement) opers ****************************************************************************/ -INLINE void saturn_negate(int reg, int begin, int count) +INLINE void saturn_negate(int reg, int begin, int count) { - int i; - SaturnNib n; - saturn.carry=1; + int i, n, c; + int max=saturn.decimal?9:15; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + c=1; + saturn.carry=0; for (i=0; i<count; i++) { - n=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - saturn.carry=saturn.carry && (n==0); - n=((n ^ 0xf)+1)&0xf; - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, n); + n=saturn.reg[reg][begin+i]; + if (n) saturn.carry=1; + n=max+c-n; + if (n>max) n-=max+1; + else c=0; + saturn_assert(n>=0); saturn_assert(n<=max); + saturn.reg[reg][begin+i]=n&0xf; saturn_ICount-=2; } } @@ -1106,9 +1041,11 @@ INLINE void saturn_negate(int reg, int begin, int count) INLINE void saturn_or(int dest, int begin, int count, int src) { int i; + saturn_assert(dest>=0 && dest<9); + saturn_assert(src>=0 && src<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - S64_WRITE_NIBBLE(dest, (begin+i)&0xf, - S64_READ_NIBBLE(dest,(begin+i)&0xf)|S64_READ_NIBBLE(src,(begin+i)&0xf)); + saturn.reg[dest][begin+i]|=saturn.reg[src][begin+i]; saturn_ICount-=2; } } @@ -1119,9 +1056,11 @@ INLINE void saturn_or(int dest, int begin, int count, int src) INLINE void saturn_and(int dest, int begin, int count, int src) { int i; + saturn_assert(dest>=0 && dest<9); + saturn_assert(src>=0 && src<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i<count; i++) { - S64_WRITE_NIBBLE(dest, (begin+i)&0xf, - S64_READ_NIBBLE(dest,(begin+i)&0xf)&S64_READ_NIBBLE(src,(begin+i)&0xf)); + saturn.reg[dest][begin+i]&=saturn.reg[src][begin+i]; saturn_ICount-=2; } } @@ -1132,11 +1071,14 @@ INLINE void saturn_and(int dest, int begin, int count, int src) INLINE void saturn_shift_nibble_left(int reg, int begin, int count) { int i; - for (i=count; i>1; i--) { - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, S64_READ_NIBBLE(reg,(begin+i-1)&0xf) ); + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + if (saturn.reg[reg][begin+count-1]) saturn.hst|=SB; + for (i=count-1; i>=1; i--) { + saturn.reg[reg][begin+i]=saturn.reg[reg][begin+i-1]; saturn_ICount-=2; } - S64_WRITE_NIBBLE(reg, begin, 0); + saturn.reg[reg][begin]=0; saturn_ICount-=2; } @@ -1146,64 +1088,65 @@ INLINE void saturn_shift_nibble_left(int reg, int begin, int count) INLINE void saturn_shift_nibble_right(int reg, int begin, int count) { int i; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + if (saturn.reg[reg][begin]) saturn.hst|=SB; for (i=1; i<count; i++) { - S64_WRITE_NIBBLE(reg, (begin+i-1)&0xf, S64_READ_NIBBLE(reg,(begin+i)&0xf) ); + saturn.reg[reg][begin+i-1]=saturn.reg[reg][begin+i]; saturn_ICount-=2; } - S64_WRITE_NIBBLE(reg, (begin+i-1)&0xf, 0); + saturn.reg[reg][begin+count-1]=0; saturn_ICount-=2; } + /**************************************************************************** - rotate nibble left opers + rotate nibbles left opers ****************************************************************************/ INLINE void saturn_rotate_nibble_left_w(int reg) { - SaturnNib a=S64_READ_NIBBLE(reg, 15); - S64_WRITE_W(reg, S64_READ_W(reg)<<4); - S64_WRITE_NIBBLE(reg,0,a); - saturn_ICount-=32; + int i, x=saturn.reg[reg][15]; + saturn_assert(reg>=0 && reg<9); + for (i=15; i>=1; i--) { + saturn.reg[reg][i]=saturn.reg[reg][i-1]; + saturn_ICount-=2; + } + saturn.reg[reg][0]=x; + saturn_ICount-=2; } +/**************************************************************************** + rotate nibbles right opers + ****************************************************************************/ INLINE void saturn_rotate_nibble_right_w(int reg) { - SaturnNib a=S64_READ_NIBBLE(reg,0); - if (a) saturn.hst|=SB; - S64_WRITE_W(reg, S64_READ_W(reg)>>4); - S64_WRITE_NIBBLE(reg,15,a); - saturn_ICount-=32; + int i, x=saturn.reg[reg][0]; + saturn_assert(reg>=0 && reg<9); + for (i=1; i<16; i++) { + saturn.reg[reg][i-1]=saturn.reg[reg][i]; + saturn_ICount-=2; + } + saturn.reg[reg][15]=x; + if (x) saturn.hst|=SB; + saturn_ICount-=2; } + /**************************************************************************** shift right opers ****************************************************************************/ INLINE void saturn_shift_right(int reg, int begin, int count) { int i, t, c=0; - for (i=count; i>=count; i--) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - if (c) t|=0x10; + saturn_assert(reg>=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + for (i=count-1; i>=0; i--) { + t=saturn.reg[reg][begin+i]; + t|=(c<<4); c=t&1; - S64_WRITE_NIBBLE(reg, (begin+i-1)&0xf, t>>1); + saturn.reg[reg][begin+i]=t>>1; saturn_ICount-=2; } if (c) saturn.hst|=SB; saturn_ICount-=2; } - - -/**************************************************************************** - shift left opers, sets carry! - ****************************************************************************/ -INLINE void saturn_shift_left(int reg, int begin, int count) -{ - SaturnNib t; - int i; - saturn.carry=0; - for (i=0; i<count; i++) { - t=S64_READ_NIBBLE(reg,(begin+i)&0xf); - S64_WRITE_NIBBLE(reg, (begin+i)&0xf, ((t<<1)&0xf)|saturn.carry); - saturn.carry=t&8?1:0; - saturn_ICount-=2; - } -} diff --git a/src/emu/cpu/saturn/sattable.c b/src/emu/cpu/saturn/sattable.c index 3eb06fd986d..8a5eeb2e8c1 100644 --- a/src/emu/cpu/saturn/sattable.c +++ b/src/emu/cpu/saturn/sattable.c @@ -1,9 +1,11 @@ static const int adr_a_begin[]={ -1, -1, BEGIN_XS, BEGIN_X, BEGIN_S, BEGIN_M, BEGIN_B, BEGIN_W, +-1, -1, -1, -1, -1, -1, -1, -1, }; static const int adr_a_count[]={ -1, -1, COUNT_XS, COUNT_X, COUNT_S, COUNT_M, COUNT_B, COUNT_W, +-1, -1, -1, -1, -1, -1, -1, -1, }; static const int adr_b_begin[]={ @@ -26,12 +28,37 @@ static const int adr_af_count[]={ -1, -1, -1, -1, -1, -1, -1, COUNT_A }; -static const int reg_left[]={A,B,C,D,B,C,A,C}; -static const int reg_right[]={B,C,A,C,A,B,C,D}; -static const int add_left[]={ A,B,C,D, 0,0,0,0, B,C,A,C }; -static const int add_right[]={ B,C,A,C, 0,0,0,0, A,B,C,D }; -static const int sub_left[]={A,B,C,D, 0,0,0,0, B,C,A,C, A,B,C,D}; -static const int sub_right[]={B,C,A,C, 0,0,0,0, A,B,C,D, A,B,C,D }; +static const int reg_left[] ={A,B,C,D, B,C,A,C, I,I,I,I, I,I,I,I}; +static const int reg_right[]={B,C,A,C, A,B,C,D, I,I,I,I, I,I,I,I}; +static const int add_left[] ={A,B,C,D, I,I,I,I, B,C,A,C, I,I,I,I}; +static const int add_right[]={B,C,A,C, I,I,I,I, A,B,C,D, I,I,I,I}; +static const int sub_left[] ={A,B,C,D, I,I,I,I, B,C,A,C, A,B,C,D}; +static const int sub_right[]={B,C,A,C, I,I,I,I, A,B,C,D, B,C,A,C}; + +void saturn_invalid3( int op1, int op2, int op3 ) +{ + logerror( "SATURN#%d invalid opcode %x%x%x at %05x\n", + cpu_getactivecpu(), op1, op2, op3, saturn.pc-3 ); +} + +void saturn_invalid4( int op1, int op2, int op3, int op4 ) +{ + logerror( "SATURN#%d invalid opcode %x%x%x%x at %05x\n", + cpu_getactivecpu(), op1, op2, op3, op4, saturn.pc-4 ); +} + +void saturn_invalid5( int op1, int op2, int op3, int op4, int op5 ) +{ + logerror( "SATURN#%d invalid opcode %x%x%x%x%x at %05x\n", + cpu_getactivecpu(), op1, op2, op3, op4, op5, saturn.pc-5 ); +} + +void saturn_invalid6( int op1, int op2, int op3, int op4, int op5, int op6 ) +{ + logerror( "SATURN#%d invalid opcode %x%x%x%x%x%x at %05x\n", + cpu_getactivecpu(), op1, op2, op3, op4, op5, op6, saturn.pc-6 ); +} + INLINE void saturn_instruction_0e(void) { @@ -68,6 +95,9 @@ INLINE void saturn_instruction_0e(void) break; //A=A!B xs } break; + default: + saturn_invalid3( 0, 0xe, adr ); + break; } } @@ -84,6 +114,9 @@ static void saturn_instruction_1(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_copy(R0+(reg&7), BEGIN_W, COUNT_W, C); break; // r0=c w + default: + saturn_invalid3( 1, adr, reg ); + break; } break; case 1: @@ -94,6 +127,9 @@ static void saturn_instruction_1(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_copy(C, BEGIN_W, COUNT_W, R0+(reg&7)); break; // c=r0 w + default: + saturn_invalid3( 1, adr, reg ); + break; } break; case 2: @@ -104,6 +140,9 @@ static void saturn_instruction_1(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_exchange(C, BEGIN_W, COUNT_W, R0+(reg&7)); break; // cr0ex w + default: + saturn_invalid3( 2, adr, reg ); + break; } break; case 3: @@ -159,6 +198,9 @@ static void saturn_instruction_1(void) case 2: case 3: case 4: case 5: case 6: case 7: saturn_store_nibbles(oper&4?C:A,adr_a_begin[adr],adr_a_count[adr],oper&1); break; + default: + saturn_invalid4( 1, 5, oper, adr ); + break; } break; case 2: case 3: case 6: case 7: @@ -172,6 +214,9 @@ static void saturn_instruction_1(void) case 2: case 3: case 4: case 5: case 6: case 7: saturn_load_nibbles(oper&4?C:A,adr_a_begin[adr],adr_a_count[adr],oper&1); break; + default: + saturn_invalid4( 1, 5, oper, adr ); + break; } break; case 8: saturn_store_nibbles(A, 0, READ_OP()+1, 0); break; @@ -184,21 +229,22 @@ static void saturn_instruction_1(void) case 0xf: saturn_load_nibbles(C, 0, READ_OP()+1, 1); break; } break; + case 6: saturn_add_adr(0);break; + case 7: saturn_add_adr(1);break; + case 8: saturn_sub_adr(0);break; case 9: saturn_load_adr(0,2);break; case 0xa: saturn_load_adr(0,4);break; case 0xb: saturn_load_adr(0,5);break; + case 0xc: saturn_sub_adr(1);break; case 0xd: saturn_load_adr(1,2);break; case 0xe: saturn_load_adr(1,4);break; case 0xf: saturn_load_adr(1,5);break; - case 6: saturn_add_adr(0);break; - case 7: saturn_add_adr(1);break; - case 8: saturn_sub_adr(0);break; - case 0xc: saturn_sub_adr(1);break; } } static void saturn_instruction_80(void) { + int op; switch(READ_OP()) { case 0: saturn_out_cs();break; case 1: saturn_out_c();break; @@ -212,12 +258,13 @@ static void saturn_instruction_80(void) switch(READ_OP()) { case 0: saturn_interrupt_on();break; case 1: - switch(READ_OP()) { + switch(op=READ_OP()) { case 0: saturn_reset_interrupt();break; + default: saturn_invalid5( 8, 0, 8, 1, op ); break; } break; case 2: saturn_load_reg(A);break; //la - case 3: saturn_bus_command_c();break; + case 3: saturn_bus_command_b();break; case 4: saturn_clear_bit(A);break; // abit=0 case 5: saturn_set_bit(A);break; // abit=1 case 6: saturn_jump_bit_clear(A);break; @@ -244,10 +291,10 @@ static void saturn_instruction_80(void) static void saturn_instruction_81a(void) { - int reg, adr; + int reg, adr,op; switch(adr=READ_OP()) { case 0: - switch(READ_OP()) { + switch(op=READ_OP()) { case 0: switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: case 4: @@ -256,6 +303,9 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_copy(R0+(reg&7),saturn.p,1,C); break; //r0=c p + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; case 1: @@ -266,6 +316,9 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_copy(C,saturn.p,1,R0+(reg&7)); break; //c=r0 p + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; case 2: @@ -276,12 +329,18 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_exchange(C, saturn.p,1,R0+(reg&7)); break; // cr0ex p + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; + default: + saturn_invalid5( 8, 1, 0xa, adr, op ); + break; } break; case 1: - switch(READ_OP()) { + switch(op=READ_OP()) { case 0: switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: case 4: @@ -290,6 +349,9 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_copy(R0+(reg&7),0,saturn.p+1,C); break; //r0=c wp + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; case 1: @@ -300,6 +362,9 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_copy(C,0,saturn.p+1,R0+(reg&7)); break; //c=r0 wp + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; case 2: @@ -310,12 +375,18 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_exchange(C, 0, saturn.p+1, R0+(reg&7)); break; // cr0ex wp + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; + default: + saturn_invalid5( 8, 1, 0xa, adr, op ); + break; } break; case 2: case 3: case 4: case 5: case 6: case 7: case 0xf: - switch(READ_OP()) { + switch(op=READ_OP()) { case 0: switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: case 4: @@ -324,6 +395,9 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_copy(R0+(reg&7),adr_af_begin[adr], adr_af_count[adr],C); break; //r0=c xs + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; case 1: @@ -334,6 +408,9 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_copy(C,adr_af_begin[adr],adr_af_count[adr],R0+(reg&7)); break; //c=r0 xs + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; case 2: @@ -344,10 +421,19 @@ static void saturn_instruction_81a(void) case 8: case 9: case 0xa: case 0xb: case 0xc: saturn_exchange(C, adr_af_begin[adr], adr_af_count[adr], R0+(reg&7)); break; // cr0ex xs + default: + saturn_invalid6( 8, 1, 0xa, adr, op, reg); + break; } break; + default: + saturn_invalid5( 8, 1, 0xa, adr, op ); + break; } break; + default: + saturn_invalid4( 8, 1, 0xa, adr ); + break; } } @@ -368,17 +454,23 @@ static void saturn_instruction_81(void) saturn_add_const(A+reg, saturn.p, 1, READ_OP()+1); break; case 8: case 9: case 0xa: case 0xb: - saturn_sub_const(A+reg, saturn.p, 1, READ_OP()+1); + saturn_sub_const(A+(reg&3), saturn.p, 1, READ_OP()+1); + break; + default: + saturn_invalid5( 8, 1, 8, adr, reg ); break; } break; case 1: switch (reg=READ_OP()) { case 0: case 1: case 2: case 3: - saturn_add_const(A+reg, 1, saturn.p+1, READ_OP()+1); + saturn_add_const(A+reg, 0, saturn.p+1, READ_OP()+1); break; case 8: case 9: case 0xa: case 0xb: - saturn_sub_const(A+reg, 1, saturn.p+1, READ_OP()+1); + saturn_sub_const(A+(reg&3), 0, saturn.p+1, READ_OP()+1); + break; + default: + saturn_invalid5( 8, 1, 8, adr, reg ); break; } break; @@ -388,10 +480,16 @@ static void saturn_instruction_81(void) saturn_add_const(A+reg, adr_af_begin[adr], adr_af_count[adr], READ_OP()+1); break; case 8: case 9: case 0xa: case 0xb: - saturn_sub_const(A+reg, adr_af_begin[adr], adr_af_count[adr], READ_OP()+1); + saturn_sub_const(A+(reg&3), adr_af_begin[adr], adr_af_count[adr], READ_OP()+1); + break; + default: + saturn_invalid5( 8, 1, 8, adr, reg ); break; } break; + default: + saturn_invalid4( 8, 1, 8, adr ); + break; } break; case 9: @@ -401,6 +499,9 @@ static void saturn_instruction_81(void) case 0: case 1: case 2: case 3: saturn_shift_right(A+reg,saturn.p,1); break; // asrb p + default: + saturn_invalid5( 8, 1, 9, adr, reg ); + break; } break; case 1: @@ -408,28 +509,38 @@ static void saturn_instruction_81(void) case 0: case 1: case 2: case 3: saturn_shift_right(A+reg, 0,saturn.p+1); break; // asrb wp + default: + saturn_invalid5( 8, 1, 9, adr, reg ); + break; } break; - case 2: /*case 3:*/ case 4: case 5: case 6:/* case 7:*/case 0xf: + case 2: case 3: case 4: case 5: case 6: case 7: case 0xf: switch(reg=READ_OP()){ case 0: case 1: case 2: case 3: saturn_shift_right(A+reg, adr_af_begin[adr], adr_af_count[adr]); break; // asrb xs + default: + saturn_invalid5( 8, 1, 9, adr, reg ); + break; } break; + default: + saturn_invalid4( 8, 1, 9, adr ); + break; } break; case 0xa: saturn_instruction_81a(); break; case 0xb: - switch(READ_OP()) { + switch(adr=READ_OP()) { case 2: saturn_load_pc(A);break; case 3: saturn_load_pc(C);break; case 4: saturn_store_pc(A);break; case 5: saturn_store_pc(C);break; case 6: saturn_exchange_pc(A);break; case 7: saturn_exchange_pc(C);break; + default: saturn_invalid4( 8, 1, reg, adr ); break; } break; case 0xc: case 0xd: case 0xe: case 0xf: @@ -440,7 +551,7 @@ static void saturn_instruction_81(void) static void saturn_instruction_8(void) { - int oper; + int oper, adr; switch(READ_OP()) { case 0: @@ -489,10 +600,22 @@ static void saturn_instruction_8(void) break; } break; - case 0xc: saturn_jump((READ_OP_DIS16()+saturn.pc-4)&0xfffff,1);break; - case 0xd: saturn_jump(READ_OP_ARG20(),1);break; - case 0xe: saturn_call((READ_OP_DIS16()+saturn.pc)&0xfffff);break; - case 0xf: saturn_call(READ_OP_ARG20());break; + case 0xc: + adr=READ_OP_DIS16(); + saturn_jump((adr+saturn.pc-4)&0xfffff,1); + break; + case 0xd: + adr=READ_OP_ARG20(); + saturn_jump(adr,1); + break; + case 0xe: + adr=READ_OP_DIS16(); + saturn_call((adr+saturn.pc)&0xfffff); + break; + case 0xf: + adr=READ_OP_ARG20(); + saturn_call(adr); + break; } } @@ -533,8 +656,7 @@ static void saturn_instruction_9(void) break; } break; - case 2: case 3: case 4: case 5: - case 6: case 7: + case 2: case 3: case 4: case 5: case 6: case 7: switch(oper=READ_OP()) { case 0: case 1: case 2: case 3: saturn_equals(reg_left[oper&3] ,adr_a_begin[adr], adr_a_count[adr], reg_right[oper&3]); @@ -612,9 +734,8 @@ static void saturn_instruction_a(void) case 8: case 9: case 0xa: case 0xb: saturn_add(add_left[reg], saturn.p, 1, add_right[reg]); break; - break; case 4: case 5: case 6: case 7: - saturn_shift_left(A+(reg&3), saturn.p, 1); + saturn_add(A+(reg&3), saturn.p, 1, A+(reg&3)); break; case 0xc: case 0xd: case 0xe: case 0xf: saturn_decrement(A+(reg&3), saturn.p, 1); @@ -625,13 +746,13 @@ static void saturn_instruction_a(void) switch (reg=READ_OP()) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: - saturn_add(add_left[reg], 1, saturn.p+1, add_right[reg]); + saturn_add(add_left[reg], 0, saturn.p+1, add_right[reg]); break; case 4: case 5: case 6: case 7: - saturn_shift_left(A+(reg&3), 1, saturn.p+1); + saturn_add(A+(reg&3), 0, saturn.p+1, A+(reg&3)); break; case 0xc: case 0xd: case 0xe: case 0xf: - saturn_decrement(A+(reg&3), 1, saturn.p+1); + saturn_decrement(A+(reg&3), 0, saturn.p+1); break; } break; @@ -642,7 +763,7 @@ static void saturn_instruction_a(void) saturn_add(add_left[reg], adr_a_begin[adr], adr_a_count[adr], add_right[reg]); break; case 4: case 5: case 6: case 7: - saturn_shift_left(A+(reg&3), adr_a_begin[adr], adr_a_count[adr]); + saturn_add(A+(reg&3), adr_a_begin[adr], adr_a_count[adr], A+(reg&3)); break; case 0xc: case 0xd: case 0xe: case 0xf: saturn_decrement(A+(reg&3), adr_a_begin[adr], adr_a_count[adr]); @@ -656,7 +777,7 @@ static void saturn_instruction_a(void) break; // a=0 p case 4: case 5: case 6: case 7: case 8: case 9: case 0xa: case 0xb: - saturn_copy(reg_right[reg&7], saturn.p,1,reg_left[reg&7]); //!correct + saturn_copy(reg_right[reg&7], saturn.p,1,reg_left[reg&7]); break; // a=b p case 0xc: case 0xd: case 0xe: case 0xf: saturn_exchange(reg_left[reg&3], saturn.p,1,reg_right[reg&3]); @@ -670,7 +791,7 @@ static void saturn_instruction_a(void) break; // a=0 wp case 4: case 5: case 6: case 7: case 8: case 9: case 0xa: case 0xb: - saturn_copy(reg_right[reg&7], 0, saturn.p+1, reg_left[reg&7]); //!correct + saturn_copy(reg_right[reg&7], 0, saturn.p+1, reg_left[reg&7]); break; // a=b wp case 0xc: case 0xd: case 0xe: case 0xf: saturn_exchange(reg_left[reg&3], 0, saturn.p+1, reg_right[reg&3]); @@ -684,12 +805,10 @@ static void saturn_instruction_a(void) break; // a=0 xs case 4: case 5: case 6: case 7: case 8: case 9: case 0xa: case 0xb: - saturn_copy(reg_right[reg&7], adr_b_begin[adr], adr_b_count[adr], - reg_left[reg&7]); //correct + saturn_copy(reg_right[reg&7], adr_b_begin[adr], adr_b_count[adr], reg_left[reg&7]); break; // a=b xs case 0xc: case 0xd: case 0xe: case 0xf: - saturn_exchange(reg_left[reg&3], adr_b_begin[adr], adr_b_count[adr], - reg_right[reg&3]); + saturn_exchange(reg_left[reg&3], adr_b_begin[adr], adr_b_count[adr], reg_right[reg&3]); break; // abex xs } break; @@ -705,12 +824,12 @@ static void saturn_instruction_b(void) switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: - saturn_sub(sub_left[reg], saturn.p, 1, S64_READ_P(sub_right[reg])); + saturn_sub(sub_left[reg], saturn.p, 1, sub_right[reg]); break; case 4: case 5: case 6: case 7: saturn_increment(A+(reg&3), saturn.p, 1); break; // a=a+1 p case 0xc: case 0xd: case 0xe: case 0xf: - saturn_sub2(sub_left[reg], saturn.p, 1, S64_READ_P(sub_right[reg])); + saturn_sub2(sub_left[reg], saturn.p, 1, sub_right[reg]); break; } break; @@ -718,12 +837,12 @@ static void saturn_instruction_b(void) switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: - saturn_sub(sub_left[reg], 1, saturn.p+1, sub_right[reg]); + saturn_sub(sub_left[reg], 0, saturn.p+1, sub_right[reg]); break; case 4: case 5: case 6: case 7: - saturn_increment(A+(reg&3), 1, saturn.p+1); break; // a=a+1 wp + saturn_increment(A+(reg&3), 0, saturn.p+1); break; // a=a+1 wp case 0xc: case 0xd: case 0xe: case 0xf: - saturn_sub2(sub_left[reg], 1, saturn.p+1, sub_right[reg]); + saturn_sub2(sub_left[reg], 0, saturn.p+1, sub_right[reg]); break; } break; @@ -731,8 +850,7 @@ static void saturn_instruction_b(void) switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: - saturn_sub(sub_left[reg], adr_a_begin[adr], adr_a_count[adr], - sub_right[reg]); + saturn_sub(sub_left[reg], adr_a_begin[adr], adr_a_count[adr], sub_right[reg]); break; case 4: case 5: case 6: case 7: saturn_increment(A+(reg&3), adr_a_begin[adr], adr_a_count[adr]); @@ -750,9 +868,9 @@ static void saturn_instruction_b(void) case 4: case 5: case 6: case 7: saturn_shift_nibble_right(A+(reg&3), saturn.p, 1); break; // asr p case 8: case 9: case 0xa: case 0xb: - saturn_invert(A+(reg&3), saturn.p, 1); break; // A=-A p + saturn_negate(A+(reg&3), saturn.p, 1); break; // A=-A p case 0xc: case 0xd: case 0xe: case 0xf: - saturn_negate(A+(reg&3), saturn.p, 1); break; // A=-A-1 p + saturn_invert(A+(reg&3), saturn.p, 1); break; // A=-A-1 p } break; case 9: @@ -762,9 +880,9 @@ static void saturn_instruction_b(void) case 4: case 5: case 6: case 7: saturn_shift_nibble_right(A+(reg&3),0,saturn.p+1); break; // asr wp case 8: case 9: case 0xa: case 0xb: - saturn_invert(A+(reg&3),0,saturn.p+1); break; // A=-A wp + saturn_negate(A+(reg&3),0,saturn.p+1); break; // A=-A wp case 0xc: case 0xd: case 0xe: case 0xf: - saturn_negate(A+(reg&3),0,saturn.p+1); break; // A=-A-1 wp + saturn_invert(A+(reg&3),0,saturn.p+1); break; // A=-A-1 wp } break; case 0xa: case 0xb: case 0xc: case 0xd: case 0xe: case 0xf: @@ -776,10 +894,10 @@ static void saturn_instruction_b(void) saturn_shift_nibble_right(A+(reg&3), adr_b_begin[adr], adr_b_count[adr]); break; case 8: case 9: case 0xa: case 0xb: - saturn_invert(A+(reg&3), adr_b_begin[adr], adr_b_count[adr]); + saturn_negate(A+(reg&3), adr_b_begin[adr], adr_b_count[adr]); break; case 0xc: case 0xd: case 0xe: case 0xf: - saturn_negate(A+(reg&3), adr_b_begin[adr], adr_b_count[adr]); + saturn_invert(A+(reg&3), adr_b_begin[adr], adr_b_count[adr]); break; } break; @@ -806,16 +924,10 @@ static void saturn_instruction(void) case 9: saturn_st_to_c();break; case 0xa: saturn_c_to_st();break; case 0xb: saturn_exchange_c_st();break; - case 0xc: - saturn_inc_p(); - break; - case 0xd: - saturn_dec_p(); - break; + case 0xc: saturn_inc_p();break; + case 0xd: saturn_dec_p();break; + case 0xe: saturn_instruction_0e();break; case 0xf: saturn_return_interrupt();break; - case 0xe: - saturn_instruction_0e(); - break; } break; case 1: @@ -824,12 +936,15 @@ static void saturn_instruction(void) case 2: saturn_load_p(); break; - case 3: saturn_load_reg(C);break; // lc + case 3: + saturn_load_reg(C); + break; // lc case 4: adr=READ_OP_DIS8(); if (adr==0) { saturn_return(saturn.carry); - } else { + } + else { saturn_jump((saturn.pc+adr-2)&0xfffff, saturn.carry); } break; @@ -837,7 +952,8 @@ static void saturn_instruction(void) adr=READ_OP_DIS8(); if (adr==0) { saturn_return(!saturn.carry); - } else { + } + else { saturn_jump((saturn.pc+adr-2)&0xfffff,!saturn.carry); } break; @@ -866,7 +982,7 @@ static void saturn_instruction(void) saturn_add(add_left[reg], BEGIN_A, COUNT_A, add_right[reg]); break; case 4: case 5: case 6: case 7: - saturn_shift_left(A+(reg&3), BEGIN_A, COUNT_A); + saturn_add(A+(reg&3), BEGIN_A, COUNT_A, A+(reg&3)); break; case 0xc: case 0xd: case 0xe: case 0xf: saturn_decrement(A+(reg&3), BEGIN_A, COUNT_A); @@ -880,7 +996,7 @@ static void saturn_instruction(void) break; // a=0 a case 4: case 5: case 6: case 7: case 8: case 9: case 0xa: case 0xb: - saturn_copy(reg_right[reg&7], BEGIN_A, COUNT_A, reg_left[reg&7]); //correct + saturn_copy(reg_right[reg&7], BEGIN_A, COUNT_A, reg_left[reg&7]); break; // a=b a case 0xc: case 0xd: case 0xe: case 0xf: saturn_exchange(reg_left[reg&3], BEGIN_A, COUNT_A, reg_right[reg&3]); @@ -891,13 +1007,13 @@ static void saturn_instruction(void) switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: - saturn_sub(sub_left[reg], BEGIN_A, COUNT_A, S64_READ_A(sub_right[reg])); + saturn_sub(sub_left[reg], BEGIN_A, COUNT_A, sub_right[reg]); break; case 4: case 5: case 6: case 7: saturn_increment(A+(reg&3), BEGIN_A, COUNT_A); break; // a=a+1 a case 0xc: case 0xd: case 0xe: case 0xf: - saturn_sub2(sub_left[reg], BEGIN_A, COUNT_A, S64_READ_A(sub_right[reg])); + saturn_sub2(sub_left[reg], BEGIN_A, COUNT_A, sub_right[reg]); break; } break; @@ -910,10 +1026,10 @@ static void saturn_instruction(void) saturn_shift_nibble_right(A+(reg&3),BEGIN_A, COUNT_A); break; // asr a case 8: case 9: case 0xa: case 0xb: - saturn_invert(A+(reg&3),BEGIN_A, COUNT_A); + saturn_negate(A+(reg&3),BEGIN_A, COUNT_A); break; // A=-A a case 0xc: case 0xd: case 0xe: case 0xf: - saturn_negate(A+(reg&3),BEGIN_A, COUNT_A); + saturn_invert(A+(reg&3),BEGIN_A, COUNT_A); break; // A=-A-1 a } break; diff --git a/src/emu/cpu/saturn/saturn.c b/src/emu/cpu/saturn/saturn.c index 684124e84f7..924affd0d61 100644 --- a/src/emu/cpu/saturn/saturn.c +++ b/src/emu/cpu/saturn/saturn.c @@ -6,6 +6,8 @@ * * Copyright Peter Trauner, all rights reserved. * + * Modified by Antoine Mine' + * * - This source code is released as freeware for non-commercial purposes. * - You are free to use and redistribute this code in modified or * unmodified form, provided you list me in the credits. @@ -22,7 +24,7 @@ #include "debugger.h" #include "saturn.h" -#include "sat.h" +#include "deprecat.h" /* for Machine */ #define R0 0 #define R1 1 @@ -33,18 +35,13 @@ #define B 6 #define C 7 #define D 8 +#define I 9 // invalid -typedef int SaturnAdr; // 20 bit -typedef UINT8 SaturnNib; // 4 bit -typedef short SaturnX; // 12 bit -typedef INT64 SaturnM; // 48 bit +typedef UINT32 SaturnAdr; // 20 bit, packed +typedef UINT8 SaturnNib; // 4 bit -typedef union { - UINT8 b[8]; - UINT16 w[4]; - UINT32 d[2]; - UINT64 q; -} Saturn64; +// 64 bit, unpacked (one nibble per byte) +typedef SaturnNib Saturn64[16]; #define VERBOSE 0 @@ -52,38 +49,34 @@ typedef union { /**************************************************************************** - * The 6502 registers. + * The SATURN registers. ****************************************************************************/ typedef struct { SATURN_CONFIG *config; - Saturn64 reg[9]; //r0,r1,r2,r3,r4,a,b,c,d; - SaturnAdr d[2], pc, oldpc, rstk[8]; // 20 bit addresses + Saturn64 reg[9]; //r0,r1,r2,r3,r4,a,b,c,d - int stackpointer; // this is only for debugger stepover support! + SaturnAdr d[2], pc, oldpc, rstk[8]; // 20 bit addresses SaturnNib p; // 4 bit pointer - UINT16 in; - int out; // 12 - int carry, decimal; + UINT16 out; // 12 bit (packed) + UINT8 carry, decimal; UINT16 st; // status 16 bit -#define XM 1 -#define SR 2 -#define SB 4 -#define MP 8 - int hst; // hardware status 4 bit - /* XM external Modules missing - SR Service Request - SB Sticky bit - MP Module Pulled */ - - int irq_state; - - UINT8 pending_irq; /* nonzero if an IRQ is pending */ - UINT8 after_cli; /* pending IRQ and last insn cleared I */ + + SaturnNib hst; // hardware status 4 bit +#define XM 1 // external Modules missing +#define SB 2 // Sticky bit +#define SR 4 // Service Request +#define MP 8 // Module Pulled + UINT8 nmi_state; + UINT8 irq_state; + UINT8 irq_enable; /* INTON / INTOFF */ + UINT8 in_irq; /* already servicing IRQ */ + UINT8 pending_irq; /* IRQ is pending */ + UINT8 sleeping; /* low-consumption state */ int (*irq_callback)(int irqline); /* IRQ callback */ } Saturn_Regs; @@ -94,6 +87,7 @@ static Saturn_Regs saturn; /*************************************************************** * include the opcode macros, functions and tables ***************************************************************/ + #include "satops.c" #include "sattable.c" @@ -106,12 +100,39 @@ static Saturn_Regs saturn; static void saturn_init(int index, int clock, const void *config, int (*irqcallback)(int)) { saturn.config = (SATURN_CONFIG *) config; + saturn.irq_callback = irqcallback; + + state_save_register_item_array("saturn",index,saturn.reg[R0]); + state_save_register_item_array("saturn",index,saturn.reg[R1]); + state_save_register_item_array("saturn",index,saturn.reg[R2]); + state_save_register_item_array("saturn",index,saturn.reg[R3]); + state_save_register_item_array("saturn",index,saturn.reg[R4]); + state_save_register_item_array("saturn",index,saturn.reg[A]); + state_save_register_item_array("saturn",index,saturn.reg[B]); + state_save_register_item_array("saturn",index,saturn.reg[C]); + state_save_register_item_array("saturn",index,saturn.reg[D]); + state_save_register_item_array("saturn",index,saturn.d); + state_save_register_item("saturn",index,saturn.pc); + state_save_register_item("saturn",index,saturn.oldpc); + state_save_register_item_array("saturn",index,saturn.rstk); + state_save_register_item("saturn",index,saturn.out); + state_save_register_item("saturn",index,saturn.carry); + state_save_register_item("saturn",index,saturn.st); + state_save_register_item("saturn",index,saturn.hst); + state_save_register_item("saturn",index,saturn.nmi_state); + state_save_register_item("saturn",index,saturn.irq_state); + state_save_register_item("saturn",index,saturn.irq_enable); + state_save_register_item("saturn",index,saturn.in_irq); + state_save_register_item("saturn",index,saturn.pending_irq); + state_save_register_item("saturn",index,saturn.sleeping); } static void saturn_reset(void) { - saturn.stackpointer=0; saturn.pc=0; + saturn.sleeping = 0; + saturn.irq_enable = 0; + saturn.in_irq = 0; change_pc(saturn.pc); } @@ -134,18 +155,16 @@ static void saturn_set_context (void *src) INLINE void saturn_take_irq(void) { - { - saturn_ICount -= 7; - - saturn_push(saturn.pc); - saturn.pc=IRQ_ADDRESS; - - LOG(("Saturn#%d takes IRQ ($%04x)\n", cpu_getactivecpu(), saturn.pc)); - /* call back the cpuintrf to let it clear the line */ - if (saturn.irq_callback) (*saturn.irq_callback)(0); - change_pc(saturn.pc); - } + saturn.in_irq = 1; /* reset by software, using RTI */ saturn.pending_irq = 0; + saturn_ICount -= 7; + saturn_push(saturn.pc); + saturn.pc=IRQ_ADDRESS; + + LOG(("Saturn#%d takes IRQ ($%04x)\n", cpu_getactivecpu(), saturn.pc)); + + if (saturn.irq_callback) (*saturn.irq_callback)(SATURN_IRQ_LINE); + change_pc(saturn.pc); } static int saturn_execute(int cycles) @@ -160,133 +179,96 @@ static int saturn_execute(int cycles) CALL_DEBUGGER(saturn.pc); - /* if an irq is pending, take it now */ - if( saturn.pending_irq ) - saturn_take_irq(); - - saturn_instruction(); - - /* check if the I flag was just reset (interrupts enabled) */ - if( saturn.after_cli ) + if ( saturn.sleeping ) { - LOG(("M6502#%d after_cli was >0", cpu_getactivecpu())); - saturn.after_cli = 0; - if (saturn.irq_state != CLEAR_LINE) - { - LOG((": irq line is asserted: set pending IRQ\n")); - saturn.pending_irq = 1; - } - else - { - LOG((": irq line is clear\n")); - } + /* advance time when sleeping */ + saturn_ICount -= 100; } else - if( saturn.pending_irq ) - saturn_take_irq(); + { + /* takes irq */ + if ( saturn.pending_irq && (!saturn.in_irq) ) + saturn_take_irq(); + + /* execute one instruction */ + saturn_instruction(); + } } while (saturn_ICount > 0); return cycles - saturn_ICount; } -#ifdef UNUSED_FUNCTION -void saturn_set_nmi_line(int state) + +static void saturn_set_nmi_line(int state) { - if (saturn.nmi_state == state) return; + if ( state == saturn.nmi_state ) return; saturn.nmi_state = state; - if( state != CLEAR_LINE ) - { - LOG(( "M6502#%d set_nmi_line(ASSERT)\n", cpu_getactivecpu())); - saturn_ICount -= 7; - saturn_push(saturn.pc); - saturn.pc=IRQ_ADDRESS; - - LOG(("M6502#%d takes NMI ($%04x)\n", cpu_getactivecpu(), PC)); - change_pc(saturn.pc); + if ( state != CLEAR_LINE ) + { + LOG(( "SATURN#%d set_nmi_line(ASSERT)\n", cpu_getactivecpu())); + saturn.pending_irq = 1; } } -void saturn_set_irq_line(int irqline, int state) +static void saturn_set_irq_line(int state) { + if ( state == saturn.irq_state ) return; saturn.irq_state = state; - if( state != CLEAR_LINE ) + if ( state != CLEAR_LINE && saturn.irq_enable ) { - LOG(( "M6502#%d set_irq_line(ASSERT)\n", cpu_getactivecpu())); + LOG(( "SATURN#%d set_irq_line(ASSERT)\n", cpu_getactivecpu())); saturn.pending_irq = 1; } } -void saturn_set_irq_callback(int (*callback)(int)) +static void saturn_set_wakeup_line(int state) { - saturn.irq_callback = callback; + if (saturn.sleeping && state==1) + { + LOG(( "SATURN#%d set_wakeup_line(ASSERT)\n", cpu_getactivecpu())); + if (saturn.irq_callback) (*saturn.irq_callback)(SATURN_WAKEUP_LINE); + saturn.sleeping = 0; + } } -#endif -#if 0 -static void saturn_state_save(void *file) -{ - int cpu = cpu_getactivecpu(); - state_save_UINT16(file,"m6502",cpu,"PC",&m6502.pc.w.l,2); - state_save_UINT16(file,"m6502",cpu,"SP",&m6502.sp.w.l,2); - state_save_UINT8(file,"m6502",cpu,"P",&m6502.p,1); - state_save_UINT8(file,"m6502",cpu,"A",&m6502.a,1); - state_save_UINT8(file,"m6502",cpu,"X",&m6502.x,1); - state_save_UINT8(file,"m6502",cpu,"Y",&m6502.y,1); - state_save_UINT8(file,"m6502",cpu,"PENDING",&m6502.pending_irq,1); - state_save_UINT8(file,"m6502",cpu,"AFTER_CLI",&m6502.after_cli,1); - state_save_UINT8(file,"m6502",cpu,"NMI_STATE",&m6502.nmi_state,1); - state_save_UINT8(file,"m6502",cpu,"IRQ_STATE",&m6502.irq_state,1); - state_save_UINT8(file,"m6502",cpu,"SO_STATE",&m6502.so_state,1); -} -static void saturn_state_load(void *file) -{ - int cpu = cpu_getactivecpu(); - state_load_UINT16(file,"m6502",cpu,"PC",&m6502.pc.w.l,2); - state_load_UINT16(file,"m6502",cpu,"SP",&m6502.sp.w.l,2); - state_load_UINT8(file,"m6502",cpu,"P",&m6502.p,1); - state_load_UINT8(file,"m6502",cpu,"A",&m6502.a,1); - state_load_UINT8(file,"m6502",cpu,"X",&m6502.x,1); - state_load_UINT8(file,"m6502",cpu,"Y",&m6502.y,1); - state_load_UINT8(file,"m6502",cpu,"PENDING",&m6502.pending_irq,1); - state_load_UINT8(file,"m6502",cpu,"AFTER_CLI",&m6502.after_cli,1); - state_load_UINT8(file,"m6502",cpu,"NMI_STATE",&m6502.nmi_state,1); - state_load_UINT8(file,"m6502",cpu,"IRQ_STATE",&m6502.irq_state,1); - state_load_UINT8(file,"m6502",cpu,"SO_STATE",&m6502.so_state,1); -} -#endif /************************************************************************** * Generic set_info **************************************************************************/ +static void IntReg64(Saturn64 r, INT64 d) +{ + int i; + for (i=0; i<16; i++) + r[i] = (d >> (4*i)) & 0xf; +} + + static void saturn_set_info(UINT32 state, cpuinfo *info) { switch (state) { /* --- the following bits of info are set as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_STATE + SATURN_NMI_STATE: saturn.nmi_state = info->i; break; - case CPUINFO_INT_INPUT_STATE + SATURN_IRQ_STATE: saturn.irq_state = info->i; break; + case CPUINFO_INT_INPUT_STATE + SATURN_NMI_LINE: saturn_set_nmi_line(info->i); break; + case CPUINFO_INT_INPUT_STATE + SATURN_IRQ_LINE: saturn_set_irq_line(info->i); break; + case CPUINFO_INT_INPUT_STATE + SATURN_WAKEUP_LINE: saturn_set_wakeup_line(info->i); break; case CPUINFO_INT_PC: case CPUINFO_INT_REGISTER + SATURN_PC: saturn.pc = info->i; change_pc(saturn.pc); break; - case CPUINFO_INT_SP: saturn.stackpointer = info->i; break; case CPUINFO_INT_REGISTER + SATURN_D0: saturn.d[0] = info->i; break; case CPUINFO_INT_REGISTER + SATURN_D1: saturn.d[1] = info->i; break; -#if 0 - case CPUINFO_INT_REGISTER + SATURN_A: saturn.reg[A] = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_B: saturn.reg[B] = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_C: saturn.reg[C] = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_D: saturn.reg[D] = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_R0: saturn.reg[R0] = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_R1: saturn.reg[R1] = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_R2: saturn.reg[R2] = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_R3: saturn.reg[R3] = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_R4: saturn.reg[R4] = info->i; break; -#endif + case CPUINFO_INT_REGISTER + SATURN_A: IntReg64(saturn.reg[A], info->i); break; + case CPUINFO_INT_REGISTER + SATURN_B: IntReg64(saturn.reg[B], info->i); break; + case CPUINFO_INT_REGISTER + SATURN_C: IntReg64(saturn.reg[C], info->i); break; + case CPUINFO_INT_REGISTER + SATURN_D: IntReg64(saturn.reg[D], info->i); break; + case CPUINFO_INT_REGISTER + SATURN_R0: IntReg64(saturn.reg[R0], info->i); break; + case CPUINFO_INT_REGISTER + SATURN_R1: IntReg64(saturn.reg[R1], info->i); break; + case CPUINFO_INT_REGISTER + SATURN_R2: IntReg64(saturn.reg[R2], info->i); break; + case CPUINFO_INT_REGISTER + SATURN_R3: IntReg64(saturn.reg[R3], info->i); break; + case CPUINFO_INT_REGISTER + SATURN_R4: IntReg64(saturn.reg[R4], info->i); break; case CPUINFO_INT_REGISTER + SATURN_P: saturn.p = info->i; break; - case CPUINFO_INT_REGISTER + SATURN_IN: saturn.in = info->i; break; case CPUINFO_INT_REGISTER + SATURN_OUT: saturn.out = info->i; break; case CPUINFO_INT_REGISTER + SATURN_CARRY: saturn.carry = info->i; break; case CPUINFO_INT_REGISTER + SATURN_ST: saturn.st = info->i; break; @@ -299,6 +281,7 @@ static void saturn_set_info(UINT32 state, cpuinfo *info) case CPUINFO_INT_REGISTER + SATURN_RSTK5: saturn.rstk[5] = info->i; break; case CPUINFO_INT_REGISTER + SATURN_RSTK6: saturn.rstk[6] = info->i; break; case CPUINFO_INT_REGISTER + SATURN_RSTK7: saturn.rstk[7] = info->i; break; + case CPUINFO_INT_REGISTER + SATURN_SLEEPING: saturn.sleeping = info->i; } } @@ -306,6 +289,18 @@ static void saturn_set_info(UINT32 state, cpuinfo *info) * Generic get_info **************************************************************************/ +#define Reg64Data(s) s[15],s[14],s[13],s[12],s[11],s[10],s[9],s[8],s[7],s[6],s[5],s[4],s[3],s[2],s[1],s[0] +#define Reg64Format "%x %x%x%x%x%x%x%x %x%x%x %x%x%x%x%x" + +static INT64 Reg64Int(Saturn64 r) +{ + INT64 x = 0; + int i; + for (i=0; i<16; i++) + x |= (INT64) r[i] << (4*i); + return x; +} + void saturn_get_info(UINT32 state, cpuinfo *info) { switch (state) @@ -332,29 +327,27 @@ void saturn_get_info(UINT32 state, cpuinfo *info) case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break; case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; - case CPUINFO_INT_INPUT_STATE + SATURN_NMI_STATE: info->i = saturn.nmi_state; break; - case CPUINFO_INT_INPUT_STATE + SATURN_IRQ_STATE: info->i = saturn.irq_state; break; + case CPUINFO_INT_INPUT_STATE + SATURN_NMI_LINE: info->i = saturn.nmi_state; break; + case CPUINFO_INT_INPUT_STATE + SATURN_IRQ_LINE: info->i = saturn.irq_state; break; case CPUINFO_INT_PREVIOUSPC: info->i = saturn.oldpc; break; case CPUINFO_INT_PC: case CPUINFO_INT_REGISTER + SATURN_PC: info->i = saturn.pc; break; - case CPUINFO_INT_SP: info->i = saturn.stackpointer; break; case CPUINFO_INT_REGISTER + SATURN_D0: info->i = saturn.d[0]; break; case CPUINFO_INT_REGISTER + SATURN_D1: info->i = saturn.d[1]; break; -#if 0 - case CPUINFO_INT_REGISTER + SATURN_A: info->i = saturn.reg[A]; break; - case CPUINFO_INT_REGISTER + SATURN_B: info->i = saturn.reg[B]; break; - case CPUINFO_INT_REGISTER + SATURN_C: info->i = saturn.reg[C]; break; - case CPUINFO_INT_REGISTER + SATURN_D: info->i = saturn.reg[D]; break; - case CPUINFO_INT_REGISTER + SATURN_R0: info->i = saturn.reg[R0]; break; - case CPUINFO_INT_REGISTER + SATURN_R1: info->i = saturn.reg[R1]; break; - case CPUINFO_INT_REGISTER + SATURN_R2: info->i = saturn.reg[R2]; break; - case CPUINFO_INT_REGISTER + SATURN_R3: info->i = saturn.reg[R3]; break; - case CPUINFO_INT_REGISTER + SATURN_R4: info->i = saturn.reg[R4]; break; -#endif + + case CPUINFO_INT_REGISTER + SATURN_A: info->i = Reg64Int(saturn.reg[A]); break; + case CPUINFO_INT_REGISTER + SATURN_B: info->i = Reg64Int(saturn.reg[B]); break; + case CPUINFO_INT_REGISTER + SATURN_C: info->i = Reg64Int(saturn.reg[C]); break; + case CPUINFO_INT_REGISTER + SATURN_D: info->i = Reg64Int(saturn.reg[D]); break; + case CPUINFO_INT_REGISTER + SATURN_R0: info->i = Reg64Int(saturn.reg[R0]); break; + case CPUINFO_INT_REGISTER + SATURN_R1: info->i = Reg64Int(saturn.reg[R1]); break; + case CPUINFO_INT_REGISTER + SATURN_R2: info->i = Reg64Int(saturn.reg[R2]); break; + case CPUINFO_INT_REGISTER + SATURN_R3: info->i = Reg64Int(saturn.reg[R3]); break; + case CPUINFO_INT_REGISTER + SATURN_R4: info->i = Reg64Int(saturn.reg[R4]); break; + case CPUINFO_INT_REGISTER + SATURN_P: info->i = saturn.p; break; - case CPUINFO_INT_REGISTER + SATURN_IN: info->i = saturn.in; break; case CPUINFO_INT_REGISTER + SATURN_OUT: info->i = saturn.out; break; case CPUINFO_INT_REGISTER + SATURN_CARRY: info->i = saturn.carry; break; case CPUINFO_INT_REGISTER + SATURN_ST: info->i = saturn.st; break; @@ -367,6 +360,7 @@ void saturn_get_info(UINT32 state, cpuinfo *info) case CPUINFO_INT_REGISTER + SATURN_RSTK5: info->i = saturn.rstk[5]; break; case CPUINFO_INT_REGISTER + SATURN_RSTK6: info->i = saturn.rstk[6]; break; case CPUINFO_INT_REGISTER + SATURN_RSTK7: info->i = saturn.rstk[7]; break; + case CPUINFO_INT_REGISTER + SATURN_SLEEPING: info->i = saturn.sleeping; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_SET_INFO: info->setinfo = saturn_set_info; break; @@ -391,17 +385,16 @@ void saturn_get_info(UINT32 state, cpuinfo *info) case CPUINFO_STR_REGISTER + SATURN_PC: sprintf(info->s = cpuintrf_temp_str(), "PC: %.5x", saturn.pc);break; case CPUINFO_STR_REGISTER + SATURN_D0: sprintf(info->s = cpuintrf_temp_str(), "D0: %.5x", saturn.d[0]);break; case CPUINFO_STR_REGISTER + SATURN_D1: sprintf(info->s = cpuintrf_temp_str(), "D1: %.5x", saturn.d[1]);break; - case CPUINFO_STR_REGISTER + SATURN_A: sprintf(info->s = cpuintrf_temp_str(), "A: %.8x %.8x", saturn.reg[A].d[1], saturn.reg[A].d[0]);break; - case CPUINFO_STR_REGISTER + SATURN_B: sprintf(info->s = cpuintrf_temp_str(), "B: %.8x %.8x", saturn.reg[B].d[1], saturn.reg[B].d[0]);break; - case CPUINFO_STR_REGISTER + SATURN_C: sprintf(info->s = cpuintrf_temp_str(), "C: %.8x %.8x", saturn.reg[C].d[1], saturn.reg[C].d[0]);break; - case CPUINFO_STR_REGISTER + SATURN_D: sprintf(info->s = cpuintrf_temp_str(), "D: %.8x %.8x", saturn.reg[D].d[1], saturn.reg[D].d[0]);break; - case CPUINFO_STR_REGISTER + SATURN_R0: sprintf(info->s = cpuintrf_temp_str(), "R0:%.8x %.8x", saturn.reg[R0].d[1], saturn.reg[R0].d[0]);break; - case CPUINFO_STR_REGISTER + SATURN_R1: sprintf(info->s = cpuintrf_temp_str(), "R1:%.8x %.8x", saturn.reg[R1].d[1], saturn.reg[R1].d[0]);break; - case CPUINFO_STR_REGISTER + SATURN_R2: sprintf(info->s = cpuintrf_temp_str(), "R2:%.8x %.8x", saturn.reg[R2].d[1], saturn.reg[R2].d[0]);break; - case CPUINFO_STR_REGISTER + SATURN_R3: sprintf(info->s = cpuintrf_temp_str(), "R3:%.8x %.8x", saturn.reg[R3].d[1], saturn.reg[R3].d[0]);break; - case CPUINFO_STR_REGISTER + SATURN_R4: sprintf(info->s = cpuintrf_temp_str(), "R4:%.8x %.8x", saturn.reg[R4].d[1], saturn.reg[R4].d[0]);break; + case CPUINFO_STR_REGISTER + SATURN_A: sprintf(info->s = cpuintrf_temp_str(), "A: " Reg64Format, Reg64Data(saturn.reg[A]));break; + case CPUINFO_STR_REGISTER + SATURN_B: sprintf(info->s = cpuintrf_temp_str(), "B: " Reg64Format, Reg64Data(saturn.reg[B]));break; + case CPUINFO_STR_REGISTER + SATURN_C: sprintf(info->s = cpuintrf_temp_str(), "C: " Reg64Format, Reg64Data(saturn.reg[C]));break; + case CPUINFO_STR_REGISTER + SATURN_D: sprintf(info->s = cpuintrf_temp_str(), "D: " Reg64Format, Reg64Data(saturn.reg[D]));break; + case CPUINFO_STR_REGISTER + SATURN_R0: sprintf(info->s = cpuintrf_temp_str(), "R0: " Reg64Format, Reg64Data(saturn.reg[R0]));break; + case CPUINFO_STR_REGISTER + SATURN_R1: sprintf(info->s = cpuintrf_temp_str(), "R1: " Reg64Format, Reg64Data(saturn.reg[R1]));break; + case CPUINFO_STR_REGISTER + SATURN_R2: sprintf(info->s = cpuintrf_temp_str(), "R2: " Reg64Format, Reg64Data(saturn.reg[R2]));break; + case CPUINFO_STR_REGISTER + SATURN_R3: sprintf(info->s = cpuintrf_temp_str(), "R3: " Reg64Format, Reg64Data(saturn.reg[R3]));break; + case CPUINFO_STR_REGISTER + SATURN_R4: sprintf(info->s = cpuintrf_temp_str(), "R4: " Reg64Format, Reg64Data(saturn.reg[R4]));break; case CPUINFO_STR_REGISTER + SATURN_P: sprintf(info->s = cpuintrf_temp_str(), "P:%x", saturn.p);break; - case CPUINFO_STR_REGISTER + SATURN_IN: sprintf(info->s = cpuintrf_temp_str(), "IN:%.4x", saturn.in);break; case CPUINFO_STR_REGISTER + SATURN_OUT: sprintf(info->s = cpuintrf_temp_str(), "OUT:%.3x", saturn.out);break; case CPUINFO_STR_REGISTER + SATURN_CARRY: sprintf(info->s = cpuintrf_temp_str(), "Carry: %d", saturn.carry);break; case CPUINFO_STR_REGISTER + SATURN_ST: sprintf(info->s = cpuintrf_temp_str(), "ST:%.4x", saturn.st);break; @@ -414,7 +407,8 @@ void saturn_get_info(UINT32 state, cpuinfo *info) case CPUINFO_STR_REGISTER + SATURN_RSTK5: sprintf(info->s = cpuintrf_temp_str(), "RSTK5:%.5x", saturn.rstk[5]);break; case CPUINFO_STR_REGISTER + SATURN_RSTK6: sprintf(info->s = cpuintrf_temp_str(), "RSTK6:%.5x", saturn.rstk[6]);break; case CPUINFO_STR_REGISTER + SATURN_RSTK7: sprintf(info->s = cpuintrf_temp_str(), "RSTK7:%.5x", saturn.rstk[7]);break; - case CPUINFO_STR_REGISTER + SATURN_IRQ_STATE: sprintf(info->s = cpuintrf_temp_str(), "IRQ:%.4x", saturn.pending_irq);break; - case CPUINFO_STR_FLAGS: sprintf(info->s = cpuintrf_temp_str(), "%c%c", saturn.decimal?'D':'.', saturn.carry ? 'C':'.'); break; + case CPUINFO_STR_REGISTER + SATURN_IRQ_STATE: sprintf(info->s = cpuintrf_temp_str(), "IRQ:%c%c%c%i", saturn.in_irq?'S':'.', saturn.irq_enable?'e':'.', saturn.pending_irq?'p':'.', saturn.irq_state); break; + case CPUINFO_STR_FLAGS: sprintf(info->s = cpuintrf_temp_str(), "%c%c", saturn.decimal?'D':'.', saturn.carry ? 'C':'.'); break; + case CPUINFO_STR_REGISTER + SATURN_SLEEPING: sprintf(info->s = cpuintrf_temp_str(), "sleep:%c", saturn.sleeping?'S':'.'); break; } } diff --git a/src/emu/cpu/saturn/saturn.h b/src/emu/cpu/saturn/saturn.h index 6bf164a1533..e302f5b7a66 100644 --- a/src/emu/cpu/saturn/saturn.h +++ b/src/emu/cpu/saturn/saturn.h @@ -6,6 +6,8 @@ * * Copyright Peter Trauner, all rights reserved. * + * Modified by Antoine Mine' + * * - This source code is released as freeware for non-commercial purposes. * - You are free to use and redistribute this code in modified or * unmodified form, provided you list me in the credits. @@ -49,15 +51,37 @@ HP38G 09/??/95 1LT8 Yorke typedef struct { - void (*out)(int); - int (*in)(void); - void (*reset)(void); - void (*config)(int v); - void (*unconfig)(int v); - int (*id)(void); - void (*crc)(int addr, int data); + void (*out)(running_machine*,int); + int (*in)(running_machine*); + void (*reset)(running_machine*); + void (*config)(running_machine*,int v); + void (*unconfig)(running_machine*,int v); + int (*id)(running_machine*); + void (*crc)(running_machine*,int addr, int data); + void (*rsi)(running_machine*); } SATURN_CONFIG; +enum { + SATURN_A=1, SATURN_B, SATURN_C, SATURN_D, + SATURN_R0, SATURN_R1, SATURN_R2, SATURN_R3, SATURN_R4, + SATURN_RSTK0, SATURN_RSTK1, SATURN_RSTK2, SATURN_RSTK3, + SATURN_RSTK4, SATURN_RSTK5, SATURN_RSTK6, SATURN_RSTK7, + SATURN_PC, SATURN_D0, SATURN_D1, + + SATURN_P, + SATURN_OUT, + SATURN_CARRY, + SATURN_ST, + SATURN_HST, + + SATURN_IRQ_STATE, + SATURN_SLEEPING, +}; + +#define SATURN_IRQ_LINE 0 +#define SATURN_NMI_LINE 1 +#define SATURN_WAKEUP_LINE 2 + #ifdef ENABLE_DEBUGGER unsigned saturn_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram); #endif /* ENABLE_DEBUGGER */ diff --git a/src/emu/cpu/saturn/saturnds.c b/src/emu/cpu/saturn/saturnds.c index dc92b7b7e29..a4cd921429f 100644 --- a/src/emu/cpu/saturn/saturnds.c +++ b/src/emu/cpu/saturn/saturnds.c @@ -1,11 +1,13 @@ /***************************************************************************** * - * saturn.c + * saturnds.c * portable saturn emulator interface * (hp calculators) * * Copyright Peter Trauner, all rights reserved. * + * Modified by Antoine Mine' + * * - This source code is released as freeware for non-commercial purposes. * - You are free to use and redistribute this code in modified or * unmodified form, provided you list me in the credits. @@ -24,7 +26,8 @@ #include "debugger.h" #include "saturn.h" -#include "sat.h" + +#define SATURN_HP_MNEMONICS #if defined SATURN_HP_MNEMONICS // class/hp mnemonics @@ -51,7 +54,7 @@ static const char *const adr_af[]= { P, WP, XS, X, S, M, B, W, 0, 0, 0, 0, 0, 0, 0, A }; static const char *const adr_a[]= -{ P, WP, XS, X, S, M, B, W }; + { P, WP, XS, X, S, M, B, W }; static const char number_2_hex[]= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; @@ -80,8 +83,12 @@ typedef enum { CcopyP, PcopyC, sreq, CswapP, inton, AloadImm, buscb, - clearAbit, setAbit, Abitclear, Abitset, - clearCbit, setCbit, Cbitclear, Cbitset, + clearAbit, setAbit, + branchAbitclear, returnAbitclear, + branchAbitset, returnAbitset, + clearCbit, setCbit, + branchCbitclear, returnCbitclear, + branchCbitset, returnCbitset, PCloadA, buscd, PCloadC, intoff, rsi, jumpA, jumpC, PCcopyA, PCcopyC, AcopyPC, CcopyPC, @@ -132,7 +139,7 @@ typedef enum { branchDnotgreaterC, returnDnotgreaterC, SetHexMode, SetDecMode, - PopC, PushC, + PushC, PopC, D0loadImm2, D0loadImm4, D0loadImm5, D1loadImm2, D1loadImm4, D1loadImm5, @@ -232,11 +239,15 @@ static const struct { { { "Abit=0 %x", "CLRB %x,A" } }, { { "Abit=1 %x", "SETB %x,A" } }, { { "?Abit=0 %x,%05x", "BRBC %x,A,%05x" } }, + { { "?Abit=0 %x,rtn", "RETBC %x,A" } }, { { "?Abit=1 %x,%05x", "BRBS %x,A,%05x" } }, + { { "?Abit=1 %x,rtn", "RETBS %x,A" } }, { { "Cbit=0 %x", "CLRB %x,C" } }, { { "Cbit=1 %x", "SETB %x,C" } }, { { "?Cbit=0 %x,%05x", "BRBC %x,C,%05x" } }, + { { "?Cbit=0 %x,rtn", "RETBC %x,C" } }, { { "?Cbit=1 %x,%05x", "BRBS %x,C,%05x" } }, + { { "?Cbit=1 %x,rtn", "RETBS %x,C" } }, { { "PC=(A)", "JUMP.A @A" } }, { { "!buscd", "!BUSCD" } }, { { "PC=(C)", "JUMP.A @C" } }, @@ -252,83 +263,83 @@ static const struct { { { "HST=0 %x", "CLRHST %x" } }, { { "?HST=0 %x,%05x", "BRBCHST %x,%05x" } }, - { { "?HST=0 %x", "RETBCHST %x" } }, + { { "?HST=0 %x,rtn", "RETBCHST %x" } }, { { "ST=0 %x", "CLRB %x,ST" } }, { { "ST=1 %x", "SETB %x,ST" } }, { { "?ST=0 %x,%05x", "BRBC ST,%x,%05x" } }, - { { "?ST=0 %x", "RETBC ST,%x" } }, + { { "?ST=0 %x,rtn", "RETBC ST,%x" } }, { { "?ST=1 %x,%05x", "BRBS ST,%x,%05x" } }, - { { "?ST=1 %x", "RETBS ST,%x" } }, + { { "?ST=1 %x,rtn", "RETBS ST,%x" } }, { { "?P# %x,%05x", "BRNE P,%x,%05x" } }, - { { "?P# %x", "RETNE P,%x" } }, + { { "?P# %x,rtn", "RETNE P,%x" } }, { { "?P= %x,%05x", "BREQ P,%x,%05x" } }, - { { "?P= %x", "RETEQ P,%x" } }, - - { { "?A=B %x,%05x", "BREQ.%-2s A,B,%05x" } }, - { { "?A=B %x", "RETEQ.%-2s A,B" } }, - { { "?B=C %x,%05x", "BREQ.%-2s B,C,%05x" } }, - { { "?B=C %x", "RETEQ.%-2s B,C" } }, - { { "?A=C %x,%05x", "BREQ.%-2s A,C,%05x" } }, - { { "?A=C %x", "RETEQ.%-2s A,C" } }, - { { "?C=D %x,%05x", "BREQ.%-2s C,D,%05x" } }, - { { "?C=D %x", "RETEQ.%-2s C,D" } }, - { { "?A#B %x,%05x", "BRNE.%-2s A,B,%05x" } }, - { { "?A#B %x", "RETNE.%-2s A,B" } }, - { { "?B#C %x,%05x", "BRNE.%-2s B,C,%05x" } }, - { { "?B#C %x", "RETNE.%-2s B,C" } }, - { { "?A#C %x,%05x", "BRNE.%-2s A,C,%05x" } }, - { { "?A#C %x", "RETNE.%-2s A,C" } }, - { { "?C#D %x,%05x", "BRNE.%-2s C,D,%05x" } }, - { { "?C#D %x", "RETNE.%-2s C,D" } }, - { { "?A=0 %x,%05x", "BRZ.%-2s A,%05x" } }, - { { "?A=0 %x", "RETZ.%-2s A" } }, - { { "?B=0 %x,%05x", "BRZ.%-2s B,%05x" } }, - { { "?B=0 %x", "RETZ.%-2s B" } }, - { { "?C=0 %x,%05x", "BRZ.%-2s C,%05x" } }, - { { "?C=0 %x", "RETZ.%-2s C" } }, - { { "?D=0 %x,%05x", "BRZ.%-2s D,%05x" } }, - { { "?D=0 %x", "RETZ.%-2s D" } }, - { { "?A#0 %x,%05x", "BRNZ.%-2s A,%05x" } }, - { { "?A#0 %x", "RETNZ.%-2s A" } }, - { { "?B#0 %x,%05x", "BRNZ.%-2s B,%05x" } }, - { { "?B#0 %x", "RETNZ.%-2s B" } }, - { { "?C#0 %x,%05x", "BRNZ.%-2s C,%05x" } }, - { { "?C#0 %x", "RETNZ.%-2s C" } }, - { { "?D#0 %x,%05x", "BRNZ.%-2s D,%05x" } }, - { { "?D#0 %x", "RETNZ.%-2s D" } }, - - { { "?A>B %x,%05x", "BRGT.%-2s A,B,%05x" } }, - { { "?A>B %x", "RETGT.%-2s A,B" } }, - { { "?B>C %x,%05x", "BRGT.%-2s B,C,%05x" } }, - { { "?B>C %x", "RETGT.%-2s B,C" } }, - { { "?C>A %x,%05x", "BRGT.%-2s C,A,%05x" } }, - { { "?C>A %x", "RETGT.%-2s C,A" } }, - { { "?D>C %x,%05x", "BRGT.%-2s D,C,%05x" } }, - { { "?D>C %x", "RETGT.%-2s D,C" } }, - { { "?A<B %x,%05x", "BRLT.%-2s A,B,%05x" } }, - { { "?A<B %x", "RETLT.%-2s A,B" } }, - { { "?B<C %x,%05x", "BRLT.%-2s B,C,%05x" } }, - { { "?B<C %x", "RETLT.%-2s B,C" } }, - { { "?C<A %x,%05x", "BRLT.%-2s C,A,%05x" } }, - { { "?C<A %x", "RETLT.%-2s C,A" } }, - { { "?D<C %x,%05x", "BRLT.%-2s D,C,%05x" } }, - { { "?D<C %x", "RETLT.%-2s D,C" } }, - { { "?A>=B %x,%05x", "BRGE.%-2s A,B,%05x" } }, - { { "?A>=B %x", "RETGE.%-2s A,B" } }, - { { "?B>=C %x,%05x", "BRGE.%-2s B,C,%05x" } }, - { { "?B>=C %x", "RETGE.%-2s B,C" } }, - { { "?C>=A %x,%05x", "BRGE.%-2s C,A,%05x" } }, - { { "?C>=A %x", "RETGE.%-2s C,A" } }, - { { "?D>=C %x,%05x", "BRGE.%-2s D,C,%05x" } }, - { { "?D>=C %x", "RETGE.%-2s D,C" } }, - { { "?A<=B %x,%05x", "BRLE.%-2s A,B,%05x" } }, - { { "?A<=B %x", "RETLE.%-2s A,B" } }, - { { "?B<=C %x,%05x", "BRLE.%-2s B,C,%05x" } }, - { { "?B<=C %x", "RETLE.%-2s B,C" } }, - { { "?C<=A %x,%05x", "BRLE.%-2s C,A,%05x" } }, - { { "?C<=A %x", "RETLE.%-2s C,A" } }, - { { "?D<=C %x,%05x", "BRLE.%-2s D,C,%05x" } }, - { { "?D<=C %x", "RETLE.%-2s D,C" } }, + { { "?P= %x,rtn", "RETEQ P,%x" } }, + + { { "?A=B %s,%05x", "BREQ.%-2s A,B,%05x" } }, + { { "?A=B %s,rtn", "RETEQ.%-2s A,B" } }, + { { "?B=C %s,%05x", "BREQ.%-2s B,C,%05x" } }, + { { "?B=C %s,rtn", "RETEQ.%-2s B,C" } }, + { { "?A=C %s,%05x", "BREQ.%-2s A,C,%05x" } }, + { { "?A=C %s,rtn", "RETEQ.%-2s A,C" } }, + { { "?C=D %s,%05x", "BREQ.%-2s C,D,%05x" } }, + { { "?C=D %s,rtn", "RETEQ.%-2s C,D" } }, + { { "?A#B %s,%05x", "BRNE.%-2s A,B,%05x" } }, + { { "?A#B %s,rtn", "RETNE.%-2s A,B" } }, + { { "?B#C %s,%05x", "BRNE.%-2s B,C,%05x" } }, + { { "?B#C %s,rtn", "RETNE.%-2s B,C" } }, + { { "?A#C %s,%05x", "BRNE.%-2s A,C,%05x" } }, + { { "?A#C %s,rtn", "RETNE.%-2s A,C" } }, + { { "?C#D %s,%05x", "BRNE.%-2s C,D,%05x" } }, + { { "?C#D %s,rtn", "RETNE.%-2s C,D" } }, + { { "?A=0 %s,%05x", "BRZ.%-2s A,%05x" } }, + { { "?A=0 %s,rtn", "RETZ.%-2s A" } }, + { { "?B=0 %s,%05x", "BRZ.%-2s B,%05x" } }, + { { "?B=0 %s,rtn", "RETZ.%-2s B" } }, + { { "?C=0 %s,%05x", "BRZ.%-2s C,%05x" } }, + { { "?C=0 %s,rtn", "RETZ.%-2s C" } }, + { { "?D=0 %s,%05x", "BRZ.%-2s D,%05x" } }, + { { "?D=0 %s,rtn", "RETZ.%-2s D" } }, + { { "?A#0 %s,%05x", "BRNZ.%-2s A,%05x" } }, + { { "?A#0 %s,rtn", "RETNZ.%-2s A" } }, + { { "?B#0 %s,%05x", "BRNZ.%-2s B,%05x" } }, + { { "?B#0 %s,rtn", "RETNZ.%-2s B" } }, + { { "?C#0 %s,%05x", "BRNZ.%-2s C,%05x" } }, + { { "?C#0 %s,rtn", "RETNZ.%-2s C" } }, + { { "?D#0 %s,%05x", "BRNZ.%-2s D,%05x" } }, + { { "?D#0 %s,rtn", "RETNZ.%-2s D" } }, + + { { "?A>B %s,%05x", "BRGT.%-2s A,B,%05x" } }, + { { "?A>B %s,rtn", "RETGT.%-2s A,B" } }, + { { "?B>C %s,%05x", "BRGT.%-2s B,C,%05x" } }, + { { "?B>C %s,rtn", "RETGT.%-2s B,C" } }, + { { "?C>A %s,%05x", "BRGT.%-2s C,A,%05x" } }, + { { "?C>A %s,rtn", "RETGT.%-2s C,A" } }, + { { "?D>C %s,%05x", "BRGT.%-2s D,C,%05x" } }, + { { "?D>C %s,rtn", "RETGT.%-2s D,C" } }, + { { "?A<B %s,%05x", "BRLT.%-2s A,B,%05x" } }, + { { "?A<B %s,rtn", "RETLT.%-2s A,B" } }, + { { "?B<C %s,%05x", "BRLT.%-2s B,C,%05x" } }, + { { "?B<C %s,rtn", "RETLT.%-2s B,C" } }, + { { "?C<A %s,%05x", "BRLT.%-2s C,A,%05x" } }, + { { "?C<A %s,rtn", "RETLT.%-2s C,A" } }, + { { "?D<C %s,%05x", "BRLT.%-2s D,C,%05x" } }, + { { "?D<C %s,rtn", "RETLT.%-2s D,C" } }, + { { "?A>=B %s,%05x", "BRGE.%-2s A,B,%05x" } }, + { { "?A>=B %s,rtn", "RETGE.%-2s A,B" } }, + { { "?B>=C %s,%05x", "BRGE.%-2s B,C,%05x" } }, + { { "?B>=C %s,rtn", "RETGE.%-2s B,C" } }, + { { "?C>=A %s,%05x", "BRGE.%-2s C,A,%05x" } }, + { { "?C>=A %s,rtn", "RETGE.%-2s C,A" } }, + { { "?D>=C %s,%05x", "BRGE.%-2s D,C,%05x" } }, + { { "?D>=C %s,rtn", "RETGE.%-2s D,C" } }, + { { "?A<=B %s,%05x", "BRLE.%-2s A,B,%05x" } }, + { { "?A<=B %s,rtn", "RETLE.%-2s A,B" } }, + { { "?B<=C %s,%05x", "BRLE.%-2s B,C,%05x" } }, + { { "?B<=C %s,rtn", "RETLE.%-2s B,C" } }, + { { "?C<=A %s,%05x", "BRLE.%-2s C,A,%05x" } }, + { { "?C<=A %s,rtn", "RETLE.%-2s C,A" } }, + { { "?D<=C %s,%05x", "BRLE.%-2s D,C,%05x" } }, + { { "?D<=C %s,rtn", "RETLE.%-2s D,C" } }, { { "sethex", "SETHEX" } }, { { "setdec", "SETDEC" } }, @@ -456,19 +467,19 @@ static const struct { { { "A=A!C %s", "OR.%-2s C,A" } }, { { "C=C!D %s", "OR.%-2s D,C" } }, - { { "Asrb %x", "SRB.%-2s A" } }, - { { "Bsrb %x", "SRB.%-2s B" } }, - { { "Csrb %x", "SRB.%-2s C" } }, - { { "Dsrb %x", "SRB.%-2s D" } }, + { { "Asrb %s", "SRB.%-2s A" } }, + { { "Bsrb %s", "SRB.%-2s B" } }, + { { "Csrb %s", "SRB.%-2s C" } }, + { { "Dsrb %s", "SRB.%-2s D" } }, { { "Aslc %s", "RLN.%-2s A" } }, { { "Bslc %s", "RLN.%-2s B" } }, { { "Cslc %s", "RLN.%-2s C" } }, { { "Dslc %s", "RLN.%-2s D" } }, - { { "Aslc %s", "RRN.%-2s A" } }, - { { "Bslc %s", "RRN.%-2s B" } }, - { { "Cslc %s", "RRN.%-2s C" } }, - { { "Dslc %s", "RRN.%-2s D" } }, + { { "Asrc %s", "RRN.%-2s A" } }, + { { "Bsrc %s", "RRN.%-2s B" } }, + { { "Csrc %s", "RRN.%-2s C" } }, + { { "Dsrc %s", "RRN.%-2s D" } }, { { "A=A+B %s", "ADD.%-2s B,A" } }, { { "B=B+C %s", "ADD.%-2s C,B" } }, @@ -566,7 +577,8 @@ typedef struct { xBranchReturn, // address field specified in previous opcode entry Imm, ImmCount, ImmCload, Imm2, Imm4, Imm5, Dis3, Dis3Call, Dis4, Dis4Call, Abs, - FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, FieldA + FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, FieldA, + AdrImmCount } adr; MNEMONICS mnemonic; } OPCODE; @@ -613,8 +625,8 @@ static const OPCODE opcodes[][0x10]= { { Complete, AdrNone, ReturnClearCarry }, { Complete, AdrNone, SetHexMode }, { Complete, AdrNone, SetDecMode }, - { Complete, AdrNone, PopC }, { Complete, AdrNone, PushC }, + { Complete, AdrNone, PopC }, { Complete, AdrNone, clearST }, { Complete, AdrNone, CcopyST }, { Complete, AdrNone, STcopyC }, @@ -817,12 +829,12 @@ static const OPCODE opcodes[][0x10]= { { Complete, AdrNone, buscb }, { Complete, Imm, clearAbit }, { Complete, Imm, setAbit }, - { Complete, ImmBranch, Abitclear }, - { Complete, ImmBranch, Abitset }, + { Complete, TestBranchRet, branchAbitclear }, + { Complete, TestBranchRet, branchAbitset }, { Complete, Imm, clearCbit }, { Complete, Imm, setCbit }, - { Complete, ImmBranch, Cbitclear }, - { Complete, ImmBranch, Cbitset }, + { Complete, TestBranchRet, branchCbitclear }, + { Complete, TestBranchRet, branchCbitset }, { Complete, AdrNone, PCloadA }, { Complete, AdrNone, buscd }, { Complete, AdrNone, PCloadC }, @@ -833,12 +845,12 @@ static const OPCODE opcodes[][0x10]= { }, { //81 { Complete, FieldW, AshiftleftCarry }, { Complete, FieldW, BshiftleftCarry }, + { Complete, FieldW, CshiftleftCarry }, { Complete, FieldW, DshiftleftCarry }, - { Complete, FieldW, DshiftleftCarry }, - { Complete, FieldW, AshiftrightCarry }, - { Complete, FieldW, AshiftrightCarry }, - { Complete, FieldW, AshiftrightCarry }, { Complete, FieldW, AshiftrightCarry }, + { Complete, FieldW, BshiftrightCarry }, + { Complete, FieldW, CshiftrightCarry }, + { Complete, FieldW, DshiftrightCarry }, { Opcode818 }, { Opcode819 }, { Opcode81A }, @@ -865,15 +877,22 @@ static const OPCODE opcodes[][0x10]= { { Illegal }, { Opcode818a, AdrAF }, }, { //818a - { Complete, AdrNone, AaddImm }, - { Complete, AdrNone, BaddImm }, - { Complete, AdrNone, CaddImm }, - { Complete, AdrNone, DaddImm }, - { Complete, AdrNone, AsubImm }, - { Complete, AdrNone, BsubImm }, - { Complete, AdrNone, CsubImm }, - { Complete, AdrNone, DsubImm } - //! rest illegal + { Complete, AdrImmCount, AaddImm }, + { Complete, AdrImmCount, BaddImm }, + { Complete, AdrImmCount, CaddImm }, + { Complete, AdrImmCount, DaddImm }, + { Illegal }, + { Illegal }, + { Illegal }, + { Illegal }, + { Complete, AdrImmCount, AsubImm }, + { Complete, AdrImmCount, BsubImm }, + { Complete, AdrImmCount, CsubImm }, + { Complete, AdrImmCount, DsubImm }, + { Illegal }, + { Illegal }, + { Illegal }, + { Illegal }, }, { //819 { Opcode819a, AdrAF }, { Opcode819a, AdrAF }, @@ -1269,7 +1288,7 @@ unsigned saturn_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opra while (cont) { - op = oprom[pos++]; + op = oprom[pos++] & 0xf; level+=op; switch (level->sel) { case Illegal: @@ -1311,6 +1330,9 @@ unsigned saturn_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opra case ImmCount: sprintf(dst, mnemonics[level->mnemonic].name[set], oprom[pos++]+1); break; + case AdrImmCount: + sprintf(dst, mnemonics[level->mnemonic].name[set], field_2_string(adr), oprom[pos++]+1); + break; case AdrCount: // mnemonics have string %s for address field snprintf(number,sizeof(number),"%x",oprom[pos++]+1); sprintf(dst, mnemonics[level->mnemonic].name[set], number); @@ -1336,29 +1358,29 @@ unsigned saturn_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opra sprintf(dst, mnemonics[level->mnemonic].name[set], v); break; case ImmCload: - c=i=oprom[pos++]; + c=i=oprom[pos++] & 0xf; number[i+1]=0; - for (;i>=0; i--) number[i]=number_2_hex[oprom[pos++]]; + for (;i>=0; i--) number[i]=number_2_hex[oprom[pos++] & 0xf]; sprintf(dst, mnemonics[level->mnemonic].name[set], c+1, number); break; case Dis3: SATURN_PEEKOP_DIS12(v); - c=(pc+pos-3+v)%0xfffff; + c=(pc+pos-3+v)&0xfffff; sprintf(dst, mnemonics[level->mnemonic].name[set], c ); break; case Dis3Call: SATURN_PEEKOP_DIS12(v); - c=(pc+pos-3+v)%0xfffff; + c=(pc+pos+v)&0xfffff; sprintf(dst, mnemonics[level->mnemonic].name[set], c ); break; case Dis4: SATURN_PEEKOP_DIS16(v); - c=(pc+pos-4+v)%0xfffff; + c=(pc+pos-4+v)&0xfffff; sprintf(dst, mnemonics[level->mnemonic].name[set], c ); break; case Dis4Call: SATURN_PEEKOP_DIS16(v); - c=(pc+pos-4+v)%0xfffff; + c=(pc+pos+v)&0xfffff; sprintf(dst, mnemonics[level->mnemonic].name[set], c ); break; case Abs: @@ -1436,13 +1458,13 @@ unsigned saturn_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opra sprintf(dst, mnemonics[level->mnemonic].name[set], W ); break; case AdrA: - sprintf(dst, mnemonics[level->mnemonic].name[set], adr_a[oprom[pos++]] ); + sprintf(dst, mnemonics[level->mnemonic].name[set], adr_a[oprom[pos++] & 0x7] ); break; case AdrAF: - sprintf(dst, mnemonics[level->mnemonic].name[set], adr_af[oprom[pos++]] ); + sprintf(dst, mnemonics[level->mnemonic].name[set], adr_af[oprom[pos++] & 0xf] ); break; case AdrB: - sprintf(dst, mnemonics[level->mnemonic].name[set], adr_b[oprom[pos++]&0x7] ); + sprintf(dst, mnemonics[level->mnemonic].name[set], adr_b[oprom[pos++] & 0x7] ); break; } break; |