diff --git a/.gitattributes b/.gitattributes index 2b6bfafacae..c8ca150983f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -329,7 +329,6 @@ src/emu/cpu/s2650/2650dasm.c svneol=native#text/plain src/emu/cpu/s2650/s2650.c svneol=native#text/plain src/emu/cpu/s2650/s2650.h svneol=native#text/plain src/emu/cpu/s2650/s2650cpu.h svneol=native#text/plain -src/emu/cpu/saturn/sat.h svneol=native#text/plain src/emu/cpu/saturn/satops.c svneol=native#text/plain src/emu/cpu/saturn/sattable.c svneol=native#text/plain src/emu/cpu/saturn/saturn.c svneol=native#text/plain diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index b7b5e1773f4..31e249b6c05 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -1328,8 +1328,7 @@ endif $(CPUOBJ)/saturn/saturn.o: $(CPUSRC)/saturn/saturn.c \ $(CPUSRC)/saturn/sattable.c \ $(CPUSRC)/saturn/satops.c \ - $(CPUSRC)/saturn/saturn.h \ - $(CPUSRC)/saturn/sat.h + $(CPUSRC)/saturn/saturn.h 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); +} -#define S64_READ_S(r) S64_READ_NIBBLE(r,15) -#define S64_WRITE_S(r,v) S64_WRITE_NIBBLE(r,15,v) +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_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_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_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_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; +} + +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_jump_after_test(void) +{ + 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) { - 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_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=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=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i=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=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=0; i--) { - t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); - t2=S64_READ_NIBBLE(right, (begin+i)&0xf ); - if (t=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 (tt2) 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=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 (tt2) 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=0 && reg<9); + saturn_assert(adr>=0 && adr<2); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i=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=0 && left<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i=0 && dest<9); + saturn_assert(src>=0 && src<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i=0 && reg<9); + saturn_assert(right>=0 && right<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i0x10) { - 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=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn_assert(count>1 || !saturn.decimal); /* SATURN bug */ for (i=0; i>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=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; i0x10) { - 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=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn_assert(count>1 || !saturn.decimal); /* SATURN bug */ for (i=0; i>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=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=0); saturn_assert(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=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=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + saturn.carry=0; for (i=0; i=0 && reg<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); + c=1; + saturn.carry=0; for (i=0; imax) 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=0 && dest<9); + saturn_assert(src>=0 && src<9); + saturn_assert(begin>=0 && count>=0 && begin+count<=16); for (i=0; i1; 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=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 nibble left opers + rotate nibbles right 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; -} - 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; i0", 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); - } -} - -void saturn_set_irq_line(int irqline, int state) -{ - saturn.irq_state = state; - if( state != CLEAR_LINE ) - { - LOG(( "M6502#%d set_irq_line(ASSERT)\n", cpu_getactivecpu())); + if ( state != CLEAR_LINE ) + { + LOG(( "SATURN#%d set_nmi_line(ASSERT)\n", cpu_getactivecpu())); saturn.pending_irq = 1; } } -void saturn_set_irq_callback(int (*callback)(int)) +static void saturn_set_irq_line(int state) { - saturn.irq_callback = callback; -} -#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); + if ( state == saturn.irq_state ) return; + saturn.irq_state = state; + if ( state != CLEAR_LINE && saturn.irq_enable ) + { + LOG(( "SATURN#%d set_irq_line(ASSERT)\n", cpu_getactivecpu())); + saturn.pending_irq = 1; + } } -static void saturn_state_load(void *file) +static void saturn_set_wakeup_line(int state) { - 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); + 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 + + /************************************************************************** * 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" } }, + { { "?P= %x,rtn", "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 %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 %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", "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" } }, + { { "?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", "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, DshiftleftCarry }, + { Complete, FieldW, CshiftleftCarry }, { 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;