diff options
Diffstat (limited to 'src/emu/cpu')
-rw-r--r-- | src/emu/cpu/cpu.mak | 19 | ||||
-rw-r--r-- | src/emu/cpu/ds5002fp/ds5002fp.c | 2596 | ||||
-rw-r--r-- | src/emu/cpu/ds5002fp/ds5002fp.h | 138 | ||||
-rw-r--r-- | src/emu/cpu/ds5002fp/ds5002fpdasm.c | 1040 | ||||
-rw-r--r-- | src/emu/cpu/ds5002fp/ds5002fpops.c | 960 | ||||
-rw-r--r-- | src/emu/cpu/mcs51/mcs51.c | 349 | ||||
-rw-r--r-- | src/emu/cpu/mcs51/mcs51.h | 33 | ||||
-rw-r--r-- | src/emu/cpu/mcs51/mcs51dasm.c | 527 |
8 files changed, 574 insertions, 5088 deletions
diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index dadc29d4134..d829ee25ba4 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -663,8 +663,9 @@ CPUDEFS += -DHAS_I80C52=$(if $(filter I80C52,$(CPUS)),1,0) CPUDEFS += -DHAS_I87C51=$(if $(filter I87C51,$(CPUS)),1,0) CPUDEFS += -DHAS_I87C52=$(if $(filter I87C52,$(CPUS)),1,0) CPUDEFS += -DHAS_AT89C4051=$(if $(filter AT89C4051,$(CPUS)),1,0) +CPUDEFS += -DHAS_DS5002FP=$(if $(filter DS5002FP,$(CPUS)),1,0) -ifneq ($(filter I8031 I8032 I8051 I8052 I8751 I8752 I80C31 I80C32 I80C51 I80C52 I87C51 I87C52 AT89C4051,$(CPUS)),) +ifneq ($(filter DS5002FP I8031 I8032 I8051 I8052 I8751 I8752 I80C31 I80C32 I80C51 I80C52 I87C51 I87C52 AT89C4051,$(CPUS)),) OBJDIRS += $(CPUOBJ)/mcs51 CPUOBJS += $(CPUOBJ)/mcs51/mcs51.o DBGOBJS += $(CPUOBJ)/mcs51/mcs51dasm.o @@ -674,22 +675,6 @@ $(CPUOBJ)/mcs51/mcs51.o: $(CPUSRC)/mcs51/mcs51.c \ $(CPUSRC)/mcs51/mcs51.h \ $(CPUSRC)/mcs51/mcs51ops.c - - -#------------------------------------------------- -# DS5002FP -#------------------------------------------------- - -CPUDEFS += -DHAS_DS5002FP=$(if $(filter DS5002FP,$(CPUS)),1,0) - -ifneq ($(filter DS5002FP,$(CPUS)),) -OBJDIRS += $(CPUOBJ)/ds5002fp -CPUOBJS += $(CPUOBJ)/ds5002fp/ds5002fp.o -DBGOBJS += $(CPUOBJ)/ds5002fp/ds5002fpdasm.o -endif - - - #------------------------------------------------- # Intel 80x86 series #------------------------------------------------- diff --git a/src/emu/cpu/ds5002fp/ds5002fp.c b/src/emu/cpu/ds5002fp/ds5002fp.c deleted file mode 100644 index b43c3f59c99..00000000000 --- a/src/emu/cpu/ds5002fp/ds5002fp.c +++ /dev/null @@ -1,2596 +0,0 @@ -/***************************************************************************** - * DS5002FP emulator by Manuel Abadia - * - * The emulator is just a modified version of the MCS-51 Family Emulator by Steve Ellenoff - * - * What has been added? - * - Extra SFRs - * - Bytewide Bus Support - * - Memory Partition and Memory Range - * - Bootstrap Configuration - * - Power Fail Interrupt - * - Timed Access - * - Stop Mode - * - Idle Mode - * - * What is not implemented? - * - Peripherals and Reprogrammable Peripheral Controller - * - CRC-16 - * - Watchdog timer - * - * The main features of the DS5002FP are: - * - 100% code-compatible with 8051 - * - Directly addresses 64kB program/64kB data memory - * - Nonvolatile memory control circuitry - * - 10-year data retention in the absence of power - * - In-system reprogramming via serial port - * - Dedicated memory bus, preserving four 8-bit ports for general purpose I/O - * - Power-fail reset - * - Early warning power-fail interrupt - * - Watchdog timer - * - Accesses up to 128kB on the bytewide bus - * - Decodes memory for 32kB x 8 or 128kB x 8 SRAMs - * - Four additional decoded peripheral-chip enables - * - CRC hardware for checking memory validity - * - Optionally emulates an 8042-style slave interface - * - Memory encryption using an 80-bit encryption key - * - Automatic random generation of encryption keys - * - Self-destruct input for tamper protection - * - Optional top-coating prevents microprobe - * - *****************************************************************************/ - -/***************************************************************************** - * - * i8051.c - * Portable MCS-51 Family Emulator - * - * Chips in the family: - * 8051 Product Line (8031,8051,8751) - * 8052 Product Line (8032,8052,8752) - * 8054 Product Line (8054) - * 8058 Product Line (8058) - * - * Copyright Steve Ellenoff, all rights reserved. - * - * - 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. - * - If you modify this source code, you must add a notice to each modified - * source file that it has been changed. If you're a nice person, you - * will clearly mark each change too. :) - * - If you wish to use this for commercial purposes, please contact me at - * sellenoff@hotmail.com - * - The author of this copywritten work reserves the right to change the - * terms of its usage and license at any time, including retroactively - * - This entire notice must remain in the source code. - * - * This work is based on: - * #1) 'Intel(tm) MC51 Microcontroller Family Users Manual' and - * #2) 8051 simulator by Travis Marlatte - * #3) Portable UPI-41/8041/8741/8042/8742 emulator V0.1 by Juergen Buchmueller (MAME CORE) - * - *****************************************************************************/ - -/****************************************************************************** - * Notes: - * *Important*: Internal ROM needs to be treated the same as external rom by the programmer - * creating the driver (ie, use standard cpu rom region) - * - * The term cycles is used here to really refer to clock oscilations, because 1 machine cycle - * actually takes 12 oscilations. - * - * Read/Write/Modify Instruction - - * Data is read from the Port Latch (not the Port Pin!), possibly modified, and - * written back to (the pin? and) the latch! - * - * The following all perform this on a port address.. - * (anl, orl, xrl, jbc, cpl, inc, dec, djnz, mov px.y,c, clr px.y, setb px.y) - * - * Serial UART emulation is not really accurate, but faked enough to work as far as i can tell - * - * August 27,2003: Currently support for only 8031/8051/8751 chips (ie 128 RAM) - * October 14,2003: Added initial support for the 8752 (ie 256 RAM) - * October 22,2003: Full support for the 8752 (ie 256 RAM) - * July 28,2004: Fixed MOVX command and added External Ram Paging Support - * July 31,2004: Added Serial Mode 0 Support & Fixed Interrupt Flags for Serial Port - * - * Todo: Full Timer support (all modes) - * - * NOW Implemented: RAM paging using hardware configured addressing... - * (July 28,2004) the "MOVX a,@R0/R1" and "MOVX @R0/R1,a" commands can use any of the other ports - * to output a page offset into external ram, but it is totally based on the hardware setup. - * - * Timing needs to be implemented via MAME timers perhaps? - * - *****************************************************************************/ - -#include "debugger.h" -#include "deprecat.h" -#include "ds5002fp.h" - -#define VERBOSE 0 - -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) - - -//Prototypes -INLINE void push_pc(void); -INLINE void pop_pc(void); -INLINE void set_parity(void); -INLINE void do_add_flags(UINT8 a, UINT8 data, UINT8 c); -INLINE void do_sub_flags(UINT8 a, UINT8 data, UINT8 c); -INLINE UINT8 check_interrupts(void); -INLINE void update_timer(int cyc); -INLINE void update_serial(int cyc); -INLINE void serial_transmit(UINT8 data); -static READ8_HANDLER(internal_ram_read); -static WRITE8_HANDLER(internal_ram_write); -static READ8_HANDLER(internal_ram_iread); -static READ32_HANDLER(external_ram_iaddr); -static WRITE8_HANDLER(internal_ram_iwrite); -static READ8_HANDLER(sfr_read); -static WRITE8_HANDLER(sfr_write); -static WRITE8_HANDLER( bit_address_w ); -static READ8_HANDLER( bit_address_r ); - -typedef struct { - UINT8 timerbaud; //Flag set if timer overflow is controlling baud - UINT8 sending; //Flag set when uart is sending - UINT8 data_out; //Data to send out - UINT8 bits_to_send; //How many bits left to send when transmitting out the serial port - UINT8 bitcycles; //# of bitcycles passed since last bit was sent -} DS5002FP_UART; - -typedef struct _DS5002FP { - - //Internal stuff - UINT16 ppc; //previous pc - UINT16 pc; //current pc - UINT16 subtype; //specific version of the cpu, ie 8031, or 8051 for example - UINT8 cur_irq; //Holds value of any current IRQ being serviced - UINT8 irq_priority; //Holds value of the current IRQ Priority Level - UINT8 rwm; //Signals that the current instruction is a read/write/modify instruction - UINT8 prev_used_cycles; //Track previous # of used cycles - UINT8 last_int0; //Store state of int0 - UINT8 last_int1; //Store state of int1 - UINT8 last_power_int; //Store state of last power interrupt - UINT8 int_vec; //Pending Interrupt Vector - UINT8 priority_request; //Priority level of incoming new irq - UINT8 previous_ta; //Previous Timed Access value - INT8 ta_window; //Timed Access window - UINT8 range; //Memory Range - const ds5002fp_config *config; //Bootstrap Configuration - //SFR Registers (Note: Appear in order as they do in memory) - UINT8 po; //Port 0 - UINT8 sp; //Stack Pointer - UINT8 dpl; //Data Pointer (DPTR) (Hi bit) - UINT8 dph; //Data Pointer (DPTR) (Lo bit) - UINT8 pcon; //Power Mode Control - UINT8 tcon; //Timer/Counter Control - UINT8 tmod; //Timer/Counter Mode Control - UINT8 tl0; //Timer 0 Lo - UINT8 tl1; //Timer 1 Lo - UINT8 th0; //Timer 0 Hi - UINT8 th1; //Timer 1 Hi - UINT8 p1; //Port 1 - UINT8 scon; //Serial Control - UINT8 sbuf; //Serial Data Buffer - UINT8 p2; //Port 2 - UINT8 ie; //Interrupt Enable - UINT8 p3; //Port 3 - UINT8 ip; //Interrupt Priority - UINT8 crc; //CRC - UINT8 crcl; //CRC Result (low nibble) - UINT8 crch; //CRC Result (high nibble) - UINT8 mcon; //Memory Control - UINT8 ta; //Timed Access - UINT8 rnr; //Random Number Generator - UINT8 psw; //Program Status Word - UINT8 rpctl; //RPC control - UINT8 rps; //RPC status - UINT8 acc; //Accumulator - UINT8 b; //Register B - - //Internal Ram - UINT8 IntRam[0xff+1]; //Max 256 Bytes of Internal RAM (8031/51 have 128, 8032/52 have 256) - - //Interrupt Callback - cpu_irq_callback irq_callback; - const device_config *device; - - //Serial Port TX/RX Call backs - void (*serial_tx_callback)(int data); //Call back funciton when sending data out of serial port - int (*serial_rx_callback)(void); //Call back function to retrieve data when receiving serial port data - - //Internal Indirect Read/Write Handlers - READ8_HANDLER((*iram_iread)); - WRITE8_HANDLER((*iram_iwrite)); - - //External/Bytewide Ram Address Callback for generating the hardware specific access to external ram - READ32_HANDLER((*ebram_iaddr_callback)); - -} DS5002FP; - -static int ds5002fp_icount; - -static DS5002FP ds5002fp; -static DS5002FP_UART uart; - -//Hold callback functions so they can be set by caller (before the cpu reset) -static void (*hold_serial_tx_callback)(int data); -static int (*hold_serial_rx_callback)(void); -static READ32_HANDLER((*hold_ebram_iaddr_callback)); - -/*Short cuts*/ - -/*************************************************************** - * Read Opcode/Opcode Arguments from Program Code - ***************************************************************/ -#define ROP(pc) cpu_readop(pc) -#define ROP_ARG(pc) cpu_readop_arg(pc) -/***************************************************************************** - * Read a byte from External Code Memory (Usually Program Rom(s) Space) - ***************************************************************************** - This area is mapped from 0-FFFF internally (64K) */ -#define CODEMEM_R(a) (UINT8)program_read_byte_8le(a) -/***************************************************************************** - * Read/Write a byte from/to Expanded/Byte-wide Data Memory (Usually RAM or other I/O) - ***************************************************************************** - This area is mapped from 0-FFFF internally (64K) */ -#define DATAMEM_R(a) (UINT8)data_read_byte_8le(a) -#define DATAMEM_W(a,v) data_write_byte_8le(a,v) - -/*************************************************************** - * Read/Write a byte from/to the Internal RAM - ***************************************************************/ -#define IRAM_R(a) internal_ram_read(Machine,a) -#define IRAM_W(a,v) internal_ram_write(Machine,a,v) -/*************************************************************** - * Read/Write a byte from/to the Internal RAM indirectly (called from indirect addressing) - ***************************************************************/ -#define IRAM_IR(a) internal_ram_iread(Machine,a) -#define IRAM_IW(a,v) internal_ram_iwrite(Machine,a,v) -/*************************************************************** - * Form an Address to Read/Write to External RAM indirectly (called from indirect addressing) - ***************************************************************/ -#define ERAM_ADDR(a,m) external_ram_iaddr(Machine,a,m) -/*************************************************************** - * Read/Write a byte from/to the SFR Registers - ***************************************************************/ -#define SFR_R(a) sfr_read(Machine,a) -#define SFR_W(a,v) sfr_write(Machine,a,v) -/*************************************************************** - * Read/Write a bit from Bit Addressable Memory - ***************************************************************/ -#define BIT_R(a) bit_address_r(Machine,a) -#define BIT_W(a,v) bit_address_w(Machine,a,v) -/*************************************************************** - * Input/Output a byte from given I/O port - ***************************************************************/ -#define IN(port) ((UINT8)io_read_byte(port)) -#define OUT(port,value) io_write_byte(port,value) -/*************************************************************** - * Access the 4 banks of R registers (R0...R7) - ***************************************************************/ -#define R_R(n) ds5002fp.IntRam[(GET_RS*8)+(n)] -/*************************************************************** - * Easy macro for working with 16 bit DPTR - ***************************************************************/ -#define R_DPTR ((R_DPH<<8) | R_DPL) -#define DPTR_W(n) SFR_W(DPH, ((n)>>8)&0xff);\ - SFR_W(DPL, ((n)&0xff)); -/*************************************************************** - * Easy macros for Setting Flags - ***************************************************************/ -/*PSW Flags*/ -#define SET_CY(n) R_PSW = (R_PSW & 0x7f) | (n<<7); //Carry Flag -#define SET_AC(n) R_PSW = (R_PSW & 0xbf) | (n<<6); //Aux.Carry Flag -#define SET_FO(n) R_PSW = (R_PSW & 0xdf) | (n<<5); //User Flag -#define SET_RS(n) R_PSW = (R_PSW & 0xe7) | (n<<3); //R Bank Select -#define SET_OV(n) R_PSW = (R_PSW & 0xfb) | (n<<2); //Overflow Flag -#define SET_P(n) R_PSW = (R_PSW & 0xfe) | (n<<0); //Parity Flag -/*IE Flags*/ -#define SET_EA(n) R_IE = (R_IE & 0x7f) | (n<<7); //Global Interrupt Enable/Disable -#define SET_ES(n) R_IE = (R_IE & 0xef) | (n<<4); //Serial Interrupt Enable/Disable -#define SET_ET1(n) R_IE = (R_IE & 0xf7) | (n<<3); //Timer 1 Interrupt Enable/Disable -#define SET_EX1(n) R_IE = (R_IE & 0xfb) | (n<<2); //External Int 1 Interrupt Enable/Disable -#define SET_ET0(n) R_IE = (R_IE & 0xfd) | (n<<1); //Timer 0 Interrupt Enable/Disable -#define SET_EX0(n) R_IE = (R_IE & 0xfe) | (n<<0); //External Int 0 Interrupt Enable/Disable -/*IP Flags*/ -#define SET_PS0(n) R_IP = (R_IP & 0xef) | (n<<4); //Set Serial Priority Level -#define SET_PT1(n) R_IP = (R_IP & 0xf7) | (n<<3); //Set Timer 1 Priority Level -#define SET_PX1(n) R_IP = (R_IP & 0xfb) | (n<<2); //Set External Int 1 Priority Level -#define SET_PT0(n) R_IP = (R_IP & 0xfd) | (n<<1); //Set Timer 0 Priority Level -#define SET_PX0(n) R_IP = (R_IP & 0xfe) | (n<<0); //Set External Int 0 Priority Level -/*TCON Flags*/ -#define SET_TF1(n) R_TCON = (R_TCON & 0x7f) | (n<<7); //Indicated Timer 1 Overflow Int Triggered -#define SET_TR1(n) R_TCON = (R_TCON & 0xbf) | (n<<6); //IndicateS Timer 1 is running -#define SET_TF0(n) R_TCON = (R_TCON & 0xdf) | (n<<5); //Indicated Timer 0 Overflow Int Triggered -#define SET_TR0(n) R_TCON = (R_TCON & 0xef) | (n<<4); //IndicateS Timer 0 is running -#define SET_IE1(n) R_TCON = (R_TCON & 0xf7) | (n<<3); //Indicated External Int 1 Triggered -#define SET_IT1(n) R_TCON = (R_TCON & 0xfb) | (n<<2); //Indicates how External Int 1 is Triggered -#define SET_IE0(n) R_TCON = (R_TCON & 0xfd) | (n<<1); //Indicated External Int 0 Triggered -#define SET_IT0(n) R_TCON = (R_TCON & 0xfe) | (n<<0); //Indicates how External Int 0 is Triggered -/*SCON Flags*/ -#define SET_SM0(n) R_SCON = (R_SCON & 0x7f) | (n<<7); //Sets Serial Port Mode -#define SET_SM1(n) R_SCON = (R_SCON & 0xbf) | (n<<6); //Sets Serial Port Mode -#define SET_SM2(n) R_SCON = (R_SCON & 0xdf) | (n<<5); //Sets Serial Port Mode (Multiprocesser mode) -#define SET_REN(n) R_SCON = (R_SCON & 0xef) | (n<<4); //Sets Serial Port Receive Enable -#define SET_TB8(n) R_SCON = (R_SCON & 0xf7) | (n<<3); //Transmit 8th Bit -#define SET_RB8(n) R_SCON = (R_SCON & 0xfb) | (n<<2); //Receive 8th Bit -#define SET_TI(n) R_SCON = (R_SCON & 0xfd) | (n<<1); //Indicates Transmit Interrupt Occurred -#define SET_RI(n) R_SCON = (R_SCON & 0xfe) | (n<<0); //Indicates Receive Interrupt Occurred -/*TMOD Flags*/ -#define SET_GATE1(n) R_TMOD = (R_TMOD & 0x7f) | (n<<7); //Timer 1 Gate Mode -#define SET_CT1(n) R_TMOD = (R_TMOD & 0xbf) | (n<<6); //Timer 1 Counter Mode -#define SET_M1_1(n) R_TMOD = (R_TMOD & 0xdf) | (n<<5); //Timer 1 Timer Mode Bit 1 -#define SET_M1_0(n) R_TMOD = (R_TMOD & 0xef) | (n<<4); //Timer 1 Timer Mode Bit 0 -#define SET_GATE0(n) R_TMOD = (R_TMOD & 0xf7) | (n<<3); //Timer 0 Gate Mode -#define SET_CT0(n) R_TMOD = (R_TMOD & 0xfb) | (n<<2); //Timer 0 Counter Mode -#define SET_M0_1(n) R_TMOD = (R_TMOD & 0xfd) | (n<<1); //Timer 0 Timer Mode Bit 1 -#define SET_M0_0(n) R_TMOD = (R_TMOD & 0xfe) | (n<<0); //Timer 0 Timer Mode Bit 0 -/*PCON Flags*/ -#define SET_POR(n) R_PCON = (R_PCON & 0xbf) | (n<<6); //Power On Reset -#define SET_PFW(n) R_PCON = (R_PCON & 0xdf) | (n<<5); //Power Fail Warning -#define SET_WTR(n) R_PCON = (R_PCON & 0xef) | (n<<4); //Watchdog Timer Reset -#define SET_EPFW(n) R_PCON = (R_PCON & 0xf7) | (n<<3); //Enable Power Fail Interrupt -#define SET_EWT(n) R_PCON = (R_PCON & 0xfb) | (n<<2); //Enable Watchdog Timer -#define SET_STOP(n) R_PCON = (R_PCON & 0xfd) | (n<<1); //Stop -#define SET_IDLE(n) R_PCON = (R_PCON & 0xfe) | (n<<0); //Idle - -/*************************************************************** - * Easy macros for Getting Flags - ***************************************************************/ -/*PSW Flags*/ -#define GET_CY ((R_PSW & 0x80)>>7) -#define GET_AC ((R_PSW & 0x40)>>6) -#define GET_FO ((R_PSW & 0x20)>>5) -#define GET_RS ((R_PSW & 0x18)>>3) -#define GET_OV ((R_PSW & 0x04)>>2) -#define GET_P ((R_PSW & 0x01)>>0) -/*IE Flags*/ -#define GET_EA ((R_IE & 0x80)>>7) -#define GET_ET2 ((R_IE & 0x20)>>5) -#define GET_ES ((R_IE & 0x10)>>4) -#define GET_ET1 ((R_IE & 0x08)>>3) -#define GET_EX1 ((R_IE & 0x04)>>2) -#define GET_ET0 ((R_IE & 0x02)>>1) -#define GET_EX0 ((R_IE & 0x01)>>0) -#define GET_PS ((R_IP & 0x10)>>4) -#define GET_PT1 ((R_IP & 0x08)>>3) -#define GET_PX1 ((R_IP & 0x04)>>2) -#define GET_PT0 ((R_IP & 0x02)>>1) -#define GET_PX0 ((R_IP & 0x01)>>0) -/*TCON Flags*/ -#define GET_TF1 ((R_TCON & 0x80)>>7) -#define GET_TR1 ((R_TCON & 0x40)>>6) -#define GET_TF0 ((R_TCON & 0x20)>>5) -#define GET_TR0 ((R_TCON & 0x10)>>4) -#define GET_IE1 ((R_TCON & 0x08)>>3) -#define GET_IT1 ((R_TCON & 0x04)>>2) -#define GET_IE0 ((R_TCON & 0x02)>>1) -#define GET_IT0 ((R_TCON & 0x01)>>0) -/*SCON Flags*/ -#define GET_SM0 ((R_SCON & 0x80)>>7) -#define GET_SM1 ((R_SCON & 0x40)>>6) -#define GET_SM2 ((R_SCON & 0x20)>>5) -#define GET_REN ((R_SCON & 0x10)>>4) -#define GET_TB8 ((R_SCON & 0x08)>>3) -#define GET_RB8 ((R_SCON & 0x04)>>2) -#define GET_TI ((R_SCON & 0x02)>>1) -#define GET_RI ((R_SCON & 0x01)>>0) -/*TMOD Flags*/ -#define GET_GATE1 ((R_TMOD & 0x80)>>7) -#define GET_CT1 ((R_TMOD & 0x40)>>6) -#define GET_M1_1 ((R_TMOD & 0x20)>>5) -#define GET_M1_0 ((R_TMOD & 0x10)>>4) -#define GET_GATE0 ((R_TMOD & 0x08)>>3) -#define GET_CT0 ((R_TMOD & 0x04)>>2) -#define GET_M0_1 ((R_TMOD & 0x02)>>1) -#define GET_M0_0 ((R_TMOD & 0x01)>>0) -/*PCON Flags*/ -#define GET_SMOD ((R_PCON & 0x80)>>7) -#define GET_POR ((R_PCON & 0x40)>>6) -#define GET_PFW ((R_PCON & 0x20)>>5) -#define GET_WTR ((R_PCON & 0x10)>>4) -#define GET_EPFW ((R_PCON & 0x08)>>3) -#define GET_EWT ((R_PCON & 0x04)>>2) -#define GET_STOP ((R_PCON & 0x02)>>1) -#define GET_IDLE ((R_PCON & 0x01)>>0) -/*MCON Flags*/ -#define GET_PA ((R_MCON & 0xf0)>>4) -#define GET_RG1 ((R_MCON & 0x08)>>3) -#define GET_PES ((R_MCON & 0x04)>>2) -#define GET_PM ((R_MCON & 0x02)>>1) -#define GET_SL ((R_MCON & 0x01)>>0) -/*RPCTL Flags*/ -#define GET_RNR ((R_RPCTL & 0x80)>>7) -#define GET_EXBS ((R_RPCTL & 0x20)>>5) -#define GET_AE ((R_RPCTL & 0x10)>>4) -#define GET_IBI ((R_RPCTL & 0x08)>>3) -#define GET_DMA ((R_RPCTL & 0x04)>>2) -#define GET_RPCON ((R_RPCTL & 0x02)>>1) -#define GET_RG0 ((R_RPCTL & 0x01)>>0) - -/*Add and Subtract Flag settings*/ -#define DO_ADD_FLAGS(a,d,c) do_add_flags(a,d,c); -#define DO_SUB_FLAGS(a,d,c) do_sub_flags(a,d,c); - -#define SET_PARITY set_parity(); -#define PUSH_PC push_pc(); -#define POP_PC pop_pc(); - -/* PC vectors */ -#define V_RESET 0x000 /* power on address */ -#define V_IE0 0x003 /* External Interrupt 0 */ -#define V_TF0 0x00b /* Timer 0 Overflow */ -#define V_IE1 0x013 /* External Interrupt 1 */ -#define V_TF1 0x01b /* Timer 1 Overflow */ -#define V_RITI 0x023 /* Serial Receive/Transmit */ -#define V_PFI 0x02b /* Power Failure Interrupt */ - -/* Any pending IRQ */ -#define SERIALPORT_IRQ ((R_SCON & 0x03) && GET_ES) - -/* Clear Current IRQ */ -#define CLEAR_CURRENT_IRQ ds5002fp.cur_irq = 0xff;\ - ds5002fp.irq_priority = 0; - -/* shorter names for the DS5002FP structure elements */ - -//Internal stuff -#define PPC ds5002fp.ppc -#define PC ds5002fp.pc -#define TYPE ds5002fp.subtype -#define RWM ds5002fp.rwm - -//SFR Registers -#define R_P0 ds5002fp.po -#define R_SP ds5002fp.sp -#define R_DPL ds5002fp.dpl -#define R_DPH ds5002fp.dph -#define R_PCON ds5002fp.pcon -#define R_TCON ds5002fp.tcon -#define R_TMOD ds5002fp.tmod -#define R_TL0 ds5002fp.tl0 -#define R_TL1 ds5002fp.tl1 -#define R_TH0 ds5002fp.th0 -#define R_TH1 ds5002fp.th1 -#define R_P1 ds5002fp.p1 -#define R_SCON ds5002fp.scon -#define R_SBUF ds5002fp.sbuf -#define R_P2 ds5002fp.p2 -#define R_IE ds5002fp.ie -#define R_P3 ds5002fp.p3 -#define R_IP ds5002fp.ip -#define R_CRC ds5002fp.crc -#define R_CRCL ds5002fp.crcl -#define R_CRCH ds5002fp.crch -#define R_MCON ds5002fp.mcon -#define R_TA ds5002fp.ta -#define R_RNR ds5002fp.rnr -#define R_PSW ds5002fp.psw -#define R_RPCTL ds5002fp.rpctl -#define R_RPS ds5002fp.rps -#define R_ACC ds5002fp.acc -#define R_B ds5002fp.b - -/* # of oscilations each opcode requires*/ -static const UINT8 ds5002fp_cycles[] = { - 12,24,24,12,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,24,12,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,24,12,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,24,12,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,12,24,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,12,24,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,12,24,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,24,24,12,24,12,12,12,12,12,12,12,12,12,12, - 24,24,24,24,48,24,24,24,24,24,24,24,24,24,24,24, - 24,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,12,24,48,12,24,24,24,24,24,24,24,24,24,24, - 24,24,12,12,24,24,24,24,24,24,24,24,24,24,24,24, - 24,24,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,12,12,12,24,12,12,24,24,24,24,24,24,24,24, - 24,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12, - 24,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12 -}; - -/* default configuration */ -static const ds5002fp_config default_config = -{ - 0x00, - 0x00, - 0x00 -}; - -/* Memory Range (RG1 and RG0 @ MCON and RPCTL registers) */ -static const UINT16 ds5002fp_ranges[4] = { - 0x1fff, - 0x3fff, - 0x7fff, - 0xffff -}; - -/* Memory Partition Table (RG1 & RG0 @ MCON & RPCTL registers) */ -static const UINT32 ds5002fp_partitions[16] = { - 0x0000, - 0x1000, - 0x2000, - 0x3000, - 0x4000, - 0x5000, - 0x6000, - 0x7000, - 0x8000, - 0x9000, - 0xa000, - 0xb000, - 0xc000, - 0xd000, - 0xe000, - 0x10000 -}; - -/* Include Opcode functions */ -#include "ds5002fpops.c" - -static CPU_INIT( ds5002fp ) -{ - const ds5002fp_config *configdata = config ? config : &default_config; - - ds5002fp.config = configdata; - ds5002fp.device = device; - ds5002fp_set_irq_callback(irqcallback); - - //Internal stuff - state_save_register_item("ds5002fp", index, ds5002fp.ppc); - state_save_register_item("ds5002fp", index, ds5002fp.pc); - state_save_register_item("ds5002fp", index, ds5002fp.subtype); - state_save_register_item("ds5002fp", index, ds5002fp.rwm ); - state_save_register_item("ds5002fp", index, ds5002fp.cur_irq ); - state_save_register_item("ds5002fp", index, ds5002fp.irq_priority ); - state_save_register_item("ds5002fp", index, ds5002fp.prev_used_cycles ); - state_save_register_item("ds5002fp", index, ds5002fp.last_int0 ); - state_save_register_item("ds5002fp", index, ds5002fp.last_int1 ); - state_save_register_item("ds5002fp", index, ds5002fp.last_power_int ); - state_save_register_item("ds5002fp", index, ds5002fp.int_vec ); - state_save_register_item("ds5002fp", index, ds5002fp.priority_request ); - state_save_register_item("ds5002fp", index, ds5002fp.previous_ta ); - state_save_register_item("ds5002fp", index, ds5002fp.ta_window ); - state_save_register_item("ds5002fp", index, ds5002fp.range ); - //SFR Registers - state_save_register_item("ds5002fp", index, ds5002fp.po); - state_save_register_item("ds5002fp", index, ds5002fp.sp); - state_save_register_item("ds5002fp", index, ds5002fp.dpl); - state_save_register_item("ds5002fp", index, ds5002fp.dph); - state_save_register_item("ds5002fp", index, ds5002fp.pcon); - state_save_register_item("ds5002fp", index, ds5002fp.tcon); - state_save_register_item("ds5002fp", index, ds5002fp.tmod); - state_save_register_item("ds5002fp", index, ds5002fp.tl0); - state_save_register_item("ds5002fp", index, ds5002fp.tl1); - state_save_register_item("ds5002fp", index, ds5002fp.th0); - state_save_register_item("ds5002fp", index, ds5002fp.th1); - state_save_register_item("ds5002fp", index, ds5002fp.p1); - state_save_register_item("ds5002fp", index, ds5002fp.scon); - state_save_register_item("ds5002fp", index, ds5002fp.sbuf); - state_save_register_item("ds5002fp", index, ds5002fp.p2); - state_save_register_item("ds5002fp", index, ds5002fp.ie); - state_save_register_item("ds5002fp", index, ds5002fp.p3); - state_save_register_item("ds5002fp", index, ds5002fp.ip); - state_save_register_item("ds5002fp", index, ds5002fp.crc); - state_save_register_item("ds5002fp", index, ds5002fp.crcl); - state_save_register_item("ds5002fp", index, ds5002fp.crch); - state_save_register_item("ds5002fp", index, ds5002fp.mcon); - state_save_register_item("ds5002fp", index, ds5002fp.ta); - state_save_register_item("ds5002fp", index, ds5002fp.rnr); - state_save_register_item("ds5002fp", index, ds5002fp.psw); - state_save_register_item("ds5002fp", index, ds5002fp.rpctl); - state_save_register_item("ds5002fp", index, ds5002fp.rps); - state_save_register_item("ds5002fp", index, ds5002fp.acc); - state_save_register_item("ds5002fp", index, ds5002fp.b); - state_save_register_item_array("ds5002fp", index, ds5002fp.IntRam); -} - -/* Reset registers to the initial values */ -CPU_RESET( ds5002fp ) -{ - cpu_irq_callback save_irqcallback; - const ds5002fp_config *save_config; - const device_config *save_device; - - save_irqcallback = ds5002fp.irq_callback; - save_config = ds5002fp.config; - save_device = ds5002fp.device; - memset(&ds5002fp, 0, sizeof(DS5002FP)); - ds5002fp.irq_callback = save_irqcallback; - ds5002fp.config = save_config; - ds5002fp.device = save_device; - - memset(&uart, 0, sizeof(DS5002FP_UART)); - ds5002fp.subtype = 8051; - - //Set up 8051 specific internal read/write (indirect) handlers.. - ds5002fp.iram_iread = internal_ram_read; //Indirect ram read/write handled the same as direct for 8051! - ds5002fp.iram_iwrite = internal_ram_write; //Indirect ram read/write handled the same as direct for 8051! - - //Set up serial call back handlers - ds5002fp.serial_tx_callback = hold_serial_tx_callback; - hold_serial_tx_callback = NULL; - ds5002fp.serial_rx_callback = hold_serial_rx_callback; - hold_serial_rx_callback = NULL; - - //Setup Expanded/Byte-wide ram callback handlers - ds5002fp.ebram_iaddr_callback = hold_ebram_iaddr_callback; - hold_ebram_iaddr_callback = NULL; - - //Clear Ram (w/0xff) - memset(&ds5002fp.IntRam, 0xff, sizeof(ds5002fp.IntRam)); - - /* these are all defined reset states */ - PC = 0; - SFR_W(ACC, 0); - SFR_W(B, 0); - SFR_W(PSW, 0); - SFR_W(SP, 0x7); - SFR_W(DPH, 0); - SFR_W(DPL, 0); - SFR_W(P3, 0xff); - SFR_W(P2, 0xff); - SFR_W(P1, 0xff); - SFR_W(P0, 0xff); - SFR_W(IP, 0); - SFR_W(IE, 0); - SFR_W(TMOD, 0); - SFR_W(TCON, 0); - SFR_W(TH1, 0); - SFR_W(TH0, 0); - SFR_W(TL1, 0); - SFR_W(TL0, 0); - SFR_W(SCON, 0); - - // set initial values (some of them are set using the bootstrap loader) - R_PCON = 0; - R_MCON = ds5002fp.config->mcon & 0xfb; - R_RPCTL = ds5002fp.config->rpctl & 0x01; - R_RPS = 0; - R_RNR = 0; - R_CRC = ds5002fp.config->crc & 0xf0; - R_CRCL = 0; - R_CRCH = 0; - R_TA = 0; - - /* Flag as NO IRQ in Progress */ - CLEAR_CURRENT_IRQ - - // set internal CPU state - ds5002fp.last_power_int = CLEAR_LINE; - ds5002fp.previous_ta = 0; - ds5002fp.ta_window = 0; - ds5002fp.range = (GET_RG1 << 1) | GET_RG0; -} - -/* Shut down CPU core */ -CPU_EXIT( ds5002fp ) -{ - /* nothing to do */ -} - -/* Execute cycles - returns number of cycles actually run */ -CPU_EXECUTE( ds5002fp ) -{ - //In stop mode, no op takes place - if (R_PCON & 0x02) { - return cycles; - } - - ds5002fp_icount = cycles; - - //In idle mode, update timers and serial port (not sure if we need to do more things here) - if (R_PCON & 0x01) { - do { - //Update Timer (if any timers are running) - if((GET_TR0 && GET_ET0) || (GET_TR1 && GET_ET1)) - update_timer(12); - - //Update Serial (if serial port sending data) - if(uart.sending) - update_serial(12); - - ds5002fp_icount -= 12; - } while( ds5002fp_icount > 0 ); - - return cycles - ds5002fp_icount; - } - - do { - //Read next opcode - UINT8 op = cpu_readop(PC); - - //Store previous PC - PPC = PC; - - //Call Debugger - debugger_instruction_hook(Machine, PC); - - //remove after testing - if(PC != PPC) op = cpu_readop(PC); - - //Update Timer (if any timers are running) - if((GET_TR0 && GET_ET0) || (GET_TR1 && GET_ET1)) - update_timer(ds5002fp.prev_used_cycles); - - //Update Serial (if serial port sending data) - if(uart.sending) - update_serial(ds5002fp.prev_used_cycles); - - //Update PC - PC += 1; - //Decrement total count by # of cycles used for this opcode - ds5002fp_icount -= (ds5002fp_cycles[op]); - - switch( op ) - { - //NOP - case 0x00: /* 1: 0000 0000 */ - nop(); - break; - //AJMP code addr /* 1: aaa0 0001 */ - case 0x01: - ajmp(); - break; - //LJMP code addr - case 0x02: /* 1: 0000 0010 */ - ljmp(); - break; - //RR A - case 0x03: /* 1: 0000 0011 */ - rr_a(); - break; - //INC A - case 0x04: /* 1: 0000 0100 */ - inc_a(); - break; - //INC data addr - case 0x05: /* 1: 0000 0101 */ - RWM=1; - inc_mem(); - RWM=0; - break; - //INC @R0/@R1 /* 1: 0000 011i */ - case 0x06: - case 0x07: - inc_ir(op&1); - break; - //INC R0 to R7 /* 1: 0000 1rrr */ - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - inc_r(op&7); - break; - //JBC bit addr, code addr - case 0x10: /* 1: 0001 0000 */ - RWM=1; - jbc(); - RWM=0; - break; - //ACALL code addr /* 1: aaa1 0001 */ - case 0x11: - acall(); - break; - //LCALL code addr - case 0x12: /* 1: 0001 0010 */ - lcall(); - break; - //RRC A - case 0x13: /* 1: 0001 0011 */ - rrc_a(); - break; - //DEC A - case 0x14: /* 1: 0001 0100 */ - dec_a(); - break; - //DEC data addr - case 0x15: /* 1: 0001 0101 */ - RWM=1; - dec_mem(); - RWM=0; - break; - //DEC @R0/@R1 /* 1: 0001 011i */ - case 0x16: - case 0x17: - dec_ir(op&1); - break; - //DEC R0 to R7 /* 1: 0001 1rrr */ - case 0x18: - case 0x19: - case 0x1a: - case 0x1b: - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f: - dec_r(op&7); - break; - //JB bit addr, code addr - case 0x20: /* 1: 0010 0000 */ - jb(); - break; - //AJMP code addr /* 1: aaa0 0001 */ - case 0x21: - ajmp(); - break; - //RET - case 0x22: /* 1: 0010 0010 */ - ret(); - break; - //RL A - case 0x23: /* 1: 0010 0011 */ - rl_a(); - break; - //ADD A, #data - case 0x24: /* 1: 0010 0100 */ - add_a_byte(); - break; - //ADD A, data addr - case 0x25: /* 1: 0010 0101 */ - add_a_mem(); - break; - //ADD A, @R0/@R1 /* 1: 0010 011i */ - case 0x26: - case 0x27: - add_a_ir(op&1); - break; - //ADD A, R0 to R7 /* 1: 0010 1rrr */ - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f: - add_a_r(op&7); - break; - //JNB bit addr, code addr - case 0x30: /* 1: 0011 0000 */ - jnb(); - break; - //ACALL code addr /* 1: aaa1 0001 */ - case 0x31: - acall(); - break; - //RETI - case 0x32: /* 1: 0011 0010 */ - reti(); - break; - //RLC A - case 0x33: /* 1: 0011 0011 */ - rlc_a(); - break; - //ADDC A, #data - case 0x34: /* 1: 0011 0100 */ - addc_a_byte(); - break; - //ADDC A, data addr - case 0x35: /* 1: 0011 0101 */ - addc_a_mem(); - break; - //ADDC A, @R0/@R1 /* 1: 0011 011i */ - case 0x36: - case 0x37: - addc_a_ir(op&1); - break; - //ADDC A, R0 to R7 /* 1: 0011 1rrr */ - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - addc_a_r(op&7); - break; - //JC code addr - case 0x40: /* 1: 0100 0000 */ - jc(); - break; - //AJMP code addr /* 1: aaa0 0001 */ - case 0x41: - ajmp(); - break; - //ORL data addr, A - case 0x42: /* 1: 0100 0010 */ - RWM=1; - orl_mem_a(); - RWM=0; - break; - //ORL data addr, #data - case 0x43: /* 1: 0100 0011 */ - RWM=1; - orl_mem_byte(); - RWM=0; - break; - //ORL A, #data - case 0x44: /* 1: 0100 0100 */ - orl_a_byte(); - break; - //ORL A, data addr - case 0x45: /* 1: 0100 0101 */ - orl_a_mem(); - break; - //ORL A, @RO/@R1 /* 1: 0100 011i */ - case 0x46: - case 0x47: - orl_a_ir(op&1); - break; - //ORL A, RO to R7 /* 1: 0100 1rrr */ - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - orl_a_r(op&7); - break; - //JNC code addr - case 0x50: /* 1: 0101 0000 */ - jnc(); - break; - //ACALL code addr /* 1: aaa1 0001 */ - case 0x51: - acall(); - break; - //ANL data addr, A - case 0x52: /* 1: 0101 0010 */ - RWM=1; - anl_mem_a(); - RWM=0; - break; - //ANL data addr, #data - case 0x53: /* 1: 0101 0011 */ - RWM=1; - anl_mem_byte(); - RWM=0; - break; - //ANL A, #data - case 0x54: /* 1: 0101 0100 */ - anl_a_byte(); - break; - //ANL A, data addr - case 0x55: /* 1: 0101 0101 */ - anl_a_mem(); - break; - //ANL A, @RO/@R1 /* 1: 0101 011i */ - case 0x56: - case 0x57: - anl_a_ir(op&1); - break; - //ANL A, RO to R7 /* 1: 0101 1rrr */ - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - anl_a_r(op&7); - break; - //JZ code addr - case 0x60: /* 1: 0110 0000 */ - jz(); - break; - //AJMP code addr /* 1: aaa0 0001 */ - case 0x61: - ajmp(); - break; - //XRL data addr, A - case 0x62: /* 1: 0110 0010 */ - RWM=1; - xrl_mem_a(); - RWM=0; - break; - //XRL data addr, #data - case 0x63: /* 1: 0110 0011 */ - RWM=1; - xrl_mem_byte(); - RWM=0; - break; - //XRL A, #data - case 0x64: /* 1: 0110 0100 */ - xrl_a_byte(); - break; - //XRL A, data addr - case 0x65: /* 1: 0110 0101 */ - xrl_a_mem(); - break; - //XRL A, @R0/@R1 /* 1: 0110 011i */ - case 0x66: - case 0x67: - xrl_a_ir(op&1); - break; - //XRL A, R0 to R7 /* 1: 0110 1rrr */ - case 0x68: - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - xrl_a_r(op&7); - break; - //JNZ code addr - case 0x70: /* 1: 0111 0000 */ - jnz(); - break; - //ACALL code addr /* 1: aaa1 0001 */ - case 0x71: - acall(); - break; - //ORL C, bit addr - case 0x72: /* 1: 0111 0010 */ - orl_c_bitaddr(); - break; - //JMP @A+DPTR - case 0x73: /* 1: 0111 0011 */ - jmp_iadptr(); - break; - //MOV A, #data - case 0x74: /* 1: 0111 0100 */ - mov_a_byte(); - break; - //MOV data addr, #data - case 0x75: /* 1: 0111 0101 */ - mov_mem_byte(); - break; - //MOV @R0/@R1, #data /* 1: 0111 011i */ - case 0x76: - case 0x77: - mov_ir_byte(op&1); - break; - //MOV R0 to R7, #data /* 1: 0111 1rrr */ - case 0x78: - case 0x79: - case 0x7a: - case 0x7b: - case 0x7c: - case 0x7d: - case 0x7e: - case 0x7f: - mov_r_byte(op&7); - break; - //SJMP code addr - case 0x80: /* 1: 1000 0000 */ - sjmp(); - break; - //AJMP code addr /* 1: aaa0 0001 */ - case 0x81: - ajmp(); - break; - //ANL C, bit addr - case 0x82: /* 1: 1000 0010 */ - anl_c_bitaddr(); - break; - //MOVC A, @A + PC - case 0x83: /* 1: 1000 0011 */ - movc_a_iapc(); - break; - //DIV AB - case 0x84: /* 1: 1000 0100 */ - div_ab(); - break; - //MOV data addr, data addr - case 0x85: /* 1: 1000 0101 */ - mov_mem_mem(); - break; - //MOV data addr, @R0/@R1 /* 1: 1000 011i */ - case 0x86: - case 0x87: - mov_mem_ir(op&1); - break; - //MOV data addr,R0 to R7 /* 1: 1000 1rrr */ - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - mov_mem_r(op&7); - break; - //MOV DPTR, #data - case 0x90: /* 1: 1001 0000 */ - mov_dptr_byte(); - break; - //ACALL code addr /* 1: aaa1 0001 */ - case 0x91: - acall(); - break; - //MOV bit addr, C - case 0x92: /* 1: 1001 0010 */ - RWM = 1; - mov_bitaddr_c(); - RWM = 0; - break; - //MOVC A, @A + DPTR - case 0x93: /* 1: 1001 0011 */ - movc_a_iadptr(); - break; - //SUBB A, #data - case 0x94: /* 1: 1001 0100 */ - subb_a_byte(); - break; - //SUBB A, data addr - case 0x95: /* 1: 1001 0101 */ - subb_a_mem(); - break; - //SUBB A, @R0/@R1 /* 1: 1001 011i */ - case 0x96: - case 0x97: - subb_a_ir(op&1); - break; - //SUBB A, R0 to R7 /* 1: 1001 1rrr */ - case 0x98: - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - case 0x9d: - case 0x9e: - case 0x9f: - subb_a_r(op&7); - break; - //ORL C, /bit addr - case 0xa0: /* 1: 1010 0000 */ - orl_c_nbitaddr(); - break; - //AJMP code addr /* 1: aaa0 0001 */ - case 0xa1: - ajmp(); - break; - //MOV C, bit addr - case 0xa2: /* 1: 1010 0010 */ - mov_c_bitaddr(); - break; - //INC DPTR - case 0xa3: /* 1: 1010 0011 */ - inc_dptr(); - break; - //MUL AB - case 0xa4: /* 1: 1010 0100 */ - mul_ab(); - break; - //reserved - case 0xa5: /* 1: 1010 0101 */ - illegal(); - break; - //MOV @R0/@R1, data addr /* 1: 1010 011i */ - case 0xa6: - case 0xa7: - mov_ir_mem(op&1); - break; - //MOV R0 to R7, data addr /* 1: 1010 1rrr */ - case 0xa8: - case 0xa9: - case 0xaa: - case 0xab: - case 0xac: - case 0xad: - case 0xae: - case 0xaf: - mov_r_mem(op&7); - break; - //ANL C,/bit addr - case 0xb0: /* 1: 1011 0000 */ - anl_c_nbitaddr(); - break; - //ACALL code addr /* 1: aaa1 0001 */ - case 0xb1: - acall(); - break; - //CPL bit addr - case 0xb2: /* 1: 1011 0010 */ - RWM=1; - cpl_bitaddr(); - RWM=0; - break; - //CPL C - case 0xb3: /* 1: 1011 0011 */ - cpl_c(); - break; - //CJNE A, #data, code addr - case 0xb4: /* 1: 1011 0100 */ - cjne_a_byte(); - break; - //CJNE A, data addr, code addr - case 0xb5: /* 1: 1011 0101 */ - cjne_a_mem(); - break; - //CJNE @R0/@R1, #data, code addr /* 1: 1011 011i */ - case 0xb6: - case 0xb7: - cjne_ir_byte(op&1); - break; - //CJNE R0 to R7, #data, code addr/* 1: 1011 1rrr */ - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - case 0xbd: - case 0xbe: - case 0xbf: - cjne_r_byte(op&7); - break; - //PUSH data addr - case 0xc0: /* 1: 1100 0000 */ - push(); - break; - //AJMP code addr /* 1: aaa0 0001 */ - case 0xc1: - ajmp(); - break; - //CLR bit addr - case 0xc2: /* 1: 1100 0010 */ - RWM=1; - clr_bitaddr(); - RWM=0; - break; - //CLR C - case 0xc3: /* 1: 1100 0011 */ - clr_c(); - break; - //SWAP A - case 0xc4: /* 1: 1100 0100 */ - swap_a(); - break; - //XCH A, data addr - case 0xc5: /* 1: 1100 0101 */ - xch_a_mem(); - break; - //XCH A, @RO/@R1 /* 1: 1100 011i */ - case 0xc6: - case 0xc7: - xch_a_ir(op&1); - break; - //XCH A, RO to R7 /* 1: 1100 1rrr */ - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - xch_a_r(op&7); - break; - //POP data addr - case 0xd0: /* 1: 1101 0000 */ - pop(); - break; - //ACALL code addr /* 1: aaa1 0001 */ - case 0xd1: - acall(); - break; - //SETB bit addr - case 0xd2: /* 1: 1101 0010 */ - RWM=1; - setb_bitaddr(); - RWM=0; - break; - //SETB C - case 0xd3: /* 1: 1101 0011 */ - setb_c(); - break; - //DA A - case 0xd4: /* 1: 1101 0100 */ - da_a(); - break; - //DJNZ data addr, code addr - case 0xd5: /* 1: 1101 0101 */ - RWM=1; - djnz_mem(); - RWM=0; - break; - //XCHD A, @R0/@R1 /* 1: 1101 011i */ - case 0xd6: - case 0xd7: - xchd_a_ir(op&1); - break; - //DJNZ R0 to R7,code addr /* 1: 1101 1rrr */ - case 0xd8: - case 0xd9: - case 0xda: - case 0xdb: - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf: - djnz_r(op&7); - break; - //MOVX A,@DPTR - case 0xe0: /* 1: 1110 0000 */ - movx_a_idptr(); - break; - //AJMP code addr /* 1: aaa0 0001 */ - case 0xe1: - ajmp(); - break; - //MOVX A, @R0/@R1 /* 1: 1110 001i */ - case 0xe2: - case 0xe3: - movx_a_ir(op&1); - break; - //CLR A - case 0xe4: /* 1: 1110 0100 */ - clr_a(); - break; - //MOV A, data addr - case 0xe5: /* 1: 1110 0101 */ - mov_a_mem(); - break; - //MOV A,@RO/@R1 /* 1: 1110 011i */ - case 0xe6: - case 0xe7: - mov_a_ir(op&1); - break; - //MOV A,R0 to R7 /* 1: 1110 1rrr */ - case 0xe8: - case 0xe9: - case 0xea: - case 0xeb: - case 0xec: - case 0xed: - case 0xee: - case 0xef: - mov_a_r(op&7); - break; - //MOVX @DPTR,A - case 0xf0: /* 1: 1111 0000 */ - movx_idptr_a(); - break; - //ACALL code addr /* 1: aaa1 0001 */ - case 0xf1: - acall(); - break; - //MOVX @R0/@R1,A /* 1: 1111 001i */ - case 0xf2: - case 0xf3: - movx_ir_a(op&1); - break; - //CPL A - case 0xf4: /* 1: 1111 0100 */ - cpl_a(); - break; - //MOV data addr, A - case 0xf5: /* 1: 1111 0101 */ - mov_mem_a(); - break; - //MOV @R0/@R1, A /* 1: 1111 011i */ - case 0xf6: - case 0xf7: - mov_ir_a(op&1); - break; - //MOV R0 to R7, A /* 1: 1111 1rrr */ - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - case 0xff: - mov_r_a(op&7); - break; - default: - illegal(); - } - - //If the chip entered in stop mode, end execution - if (R_PCON & 0x02) { - return cycles; - } - - //Store # of used cycles for this opcode (for timer & serial check at top of code) - ds5002fp.prev_used_cycles = ds5002fp_cycles[op]; - - // decrement the timed access window - if (ds5002fp.ta_window > 0) { - ds5002fp.ta_window -= ds5002fp_cycles[op]; - if (ds5002fp.ta_window < 0) { - ds5002fp.ta_window = 0; - } - } - - //Check for pending interrupts & handle - remove cycles used - ds5002fp_icount-=check_interrupts(); - - //If the chip entered in idle mode, end the loop - if (R_PCON & 0x01) { - return cycles - ds5002fp_icount; - } - } while( ds5002fp_icount > 0 ); - - return cycles - ds5002fp_icount; -} - -/* Get registers, return context size */ -void ds5002fp_get_context(void *dst) -{ - if( dst ) - memcpy(dst, &ds5002fp, sizeof(DS5002FP)); -} - -/* Set registers */ -void ds5002fp_set_context(void *src) -{ - if( src ) - memcpy(&ds5002fp, src, sizeof(DS5002FP)); -} - -/* Get Internal RAM value */ -unsigned ds5002fp_get_intram(int offset) -{ - UINT8 ram_ret = 0; - RWM = 1; - ram_ret = IRAM_R(offset); - RWM = 0; - return ram_ret; -} - -/*NOTE: These are not used by the opcode functions, they are here only for MAME requirements*/ -unsigned ds5002fp_get_reg(int regnum) -{ - switch( regnum ) - { - case REG_PREVIOUSPC: return PPC; - case REG_PC: - case DS5002FP_PC: return PC; - case REG_SP: - case DS5002FP_SP: return R_SP; - case DS5002FP_ACC: return R_ACC; - case DS5002FP_PSW: return R_PSW; - case DS5002FP_B: return R_B; - case DS5002FP_DPH: return R_DPH; - case DS5002FP_DPL: return R_DPL; - case DS5002FP_IE: return R_IE; - - case DS5002FP_PCON: return R_PCON; - case DS5002FP_MCON: return R_MCON; - case DS5002FP_RPCTL:return R_RPCTL; - case DS5002FP_CRC: return R_CRC; - //Not real registers - case DS5002FP_R0: return R_R(0); - case DS5002FP_R1: return R_R(1); - case DS5002FP_R2: return R_R(2); - case DS5002FP_R3: return R_R(3); - case DS5002FP_R4: return R_R(4); - case DS5002FP_R5: return R_R(5); - case DS5002FP_R6: return R_R(6); - case DS5002FP_R7: return R_R(7); - case DS5002FP_RB: return GET_RS; - default: - return 0; - } -} - -/*NOTE: These are not used by the opcode functions, they are here only for MAME requirements*/ -void ds5002fp_set_reg (int regnum, unsigned val) -{ - switch( regnum ) - { - case REG_PC: - case DS5002FP_PC: PC = val & 0xffff; break; - case REG_SP: - case DS5002FP_SP: SFR_W(SP,val); break; //Use SFR to handle error checking - case DS5002FP_ACC: SFR_W(ACC,val); break; - case DS5002FP_PSW: SFR_W(PSW,val); break; - case DS5002FP_B: SFR_W(B,val); break; - case DS5002FP_DPH: SFR_W(DPH,val); break; - case DS5002FP_DPL: SFR_W(DPL,val); break; - case DS5002FP_IE: SFR_W(IE,val); break; - case DS5002FP_PCON: SFR_W(PCON,val); break; - case DS5002FP_MCON: SFR_W(MCON,val); break; - case DS5002FP_RPCTL: SFR_W(RPCTL,val); break; - case DS5002FP_CRC: SFR_W(CRCR,val); break; - //Not real registers - case DS5002FP_R0: R_R(0) = val; break; - case DS5002FP_R1: R_R(1) = val; break; - case DS5002FP_R2: R_R(2) = val; break; - case DS5002FP_R3: R_R(3) = val; break; - case DS5002FP_R4: R_R(4) = val; break; - case DS5002FP_R5: R_R(5) = val; break; - case DS5002FP_R6: R_R(6) = val; break; - case DS5002FP_R7: R_R(7) = val; break; - case DS5002FP_RB: SET_RS( (val&3) ); break; - - default: - return; - } -} - -void ds5002fp_set_irq_line(int irqline, int state) -{ - switch( irqline ) - { - //External Interrupt 0 - case DS5002FP_INT0_LINE: - //Line Asserted? - if (state != CLEAR_LINE) { - //Is the enable flag for this interrupt set? - if(GET_EX0) { - //Need cleared->active line transition? (Logical 1-0 Pulse on the line) - CLEAR->ASSERT Transition since INT0 active lo! - if(GET_IT0){ - if(ds5002fp.last_int0 == CLEAR_LINE) - SET_IE0(1); - } - else - SET_IE0(1); //Nope, just set it.. - } - } - else - SET_IE0(0); //Clear Int occurred flag - ds5002fp.last_int0 = state; - - //Do the interrupt & handle - remove machine cycles used - if(GET_IE0) - ds5002fp_icount-=check_interrupts(); - break; - - //External Interrupt 1 - case DS5002FP_INT1_LINE: - - //Line Asserted? - if (state != CLEAR_LINE) { - if(GET_EX1) { - //Need cleared->active line transition? (Logical 1-0 Pulse on the line) - CLEAR->ASSERT Transition since INT1 active lo! - if(GET_IT1){ - if(ds5002fp.last_int1 == CLEAR_LINE) - SET_IE1(1); - } - else - SET_IE1(1); //Nope, just set it.. - } - } - else - SET_IE1(0); //Clear Int occurred flag - ds5002fp.last_int1 = state; - - //Do the interrupt & handle - remove machine cycles used - if(GET_IE1) - ds5002fp_icount-=check_interrupts(); - break; - - //Serial Port Receive - case DS5002FP_RX_LINE: - //Is the enable flags for this interrupt set? - if(GET_ES && GET_REN) { - int data = 0; - //Call our callball function to retrieve the data - if(ds5002fp.serial_rx_callback) - data = ds5002fp.serial_rx_callback(); - //Update the register directly, since SFR_W() will trigger a serial transmit instead! - R_SBUF=data; - //Flag the IRQ - SET_RI(1); - } - break; - //Note: we won't call check interrupts, we'll let the main loop catch it - - //Power Fail Interrupt - case DS5002FP_PFI_LINE: - //Line Asserted? - if (state != CLEAR_LINE) { - if (GET_EPFW) { - SET_PFW(1); - //Need cleared->active line transition? (Logical 1-0 Pulse on the line) - CLEAR->ASSERT Transition since INT1 active lo! - if (ds5002fp.last_power_int == CLEAR_LINE) { - ds5002fp_icount-=check_interrupts(); - } - } - } - ds5002fp.last_power_int = state; - break; - } -} - -/*********************************************************************************** - Check for pending Interrupts and process - returns # of cycles used for the int - - Note about priority & interrupting interrupts.. - 1) A high priority interrupt cannot be interrupted by anything! - 2) A low priority interrupt can ONLY be interrupted by a high priority interrupt - 3) If more than 1 Interrupt Flag is set (ie, 2 simultaneous requests occur), - the following logic works as follows: - 1) If two requests come in of different priority levels, the higher one is selected.. - 2) If the requests are of the same level, an internal order is used: - a) IEO - b) TFO - c) IE1 - d) TF1 - e) RI+TI - f) TF2+EXF2 - **********************************************************************************/ -INLINE UINT8 check_interrupts(void) -{ - //If All Inerrupts Disabled or no pending abort if no Power Fail Interrupt is pending - if(!GET_EA && !GET_PFW) { - return 0; - } - - //Skip if current irq in progress is high priority and no Power Fail Interrupt is pending - if(!GET_PFW && ds5002fp.irq_priority) { /* LOG(("high priority irq in progress, skipping irq request\n")); */ return 0; } - - //Check which interrupt(s) requests have occurred.. - //NOTE: The order of checking is based on the internal/default priority levels when levels are the same - - // Power Fail Interrupt - if(GET_PFW) { - if (ds5002fp.last_power_int == CLEAR_LINE) { - //Set vector & priority level request - ds5002fp.int_vec = V_PFI; - ds5002fp.priority_request = GET_PFW; - } else if (!GET_EA) { - return 0; - } - } - //External Int 0 - if(!ds5002fp.priority_request && GET_IE0) { - //Set vector & priority level request - ds5002fp.int_vec = V_IE0; - ds5002fp.priority_request = GET_PX0; - } - //Timer 0 overflow - if(!ds5002fp.priority_request && GET_TF0 && (!ds5002fp.int_vec || (ds5002fp.int_vec && GET_PT0))) { - //Set vector & priority level request - ds5002fp.int_vec = V_TF0; - ds5002fp.priority_request = GET_PT0; - } - //External Int 1 - if(!ds5002fp.priority_request && GET_IE1 && (!ds5002fp.int_vec || (ds5002fp.int_vec && GET_PX1))) { - //Set vector & priority level request - ds5002fp.int_vec = V_IE1; - ds5002fp.priority_request = GET_PX1; - } - //Timer 1 overflow - if(!ds5002fp.priority_request && GET_TF1 && (!ds5002fp.int_vec || (ds5002fp.int_vec && GET_PT1))) { - //Set vector & priority level request - ds5002fp.int_vec = V_TF1; - ds5002fp.priority_request = GET_PT1; - } - //Serial Interrupt Transmit/Receive Interrupts (Note: ES Bit - Serial Interrupts must be enabled) - if(!ds5002fp.priority_request && GET_ES && (GET_TI || GET_RI) && (!ds5002fp.int_vec || (ds5002fp.int_vec && GET_PS))) { - //Set vector & priority level request - ds5002fp.int_vec = V_RITI; - ds5002fp.priority_request = GET_PS; - } - - //Skip the interrupt request if currently processing is lo priority, and the new request IS NOT HI PRIORITY! - if(ds5002fp.cur_irq < 0xff && !ds5002fp.priority_request) - { LOG(("low priority irq in progress already, skipping low irq request\n")); return 0; } - - /*** --- Perform the interrupt --- ***/ - - //Save current pc to stack, set pc to new interrupt vector - push_pc(); - PC = ds5002fp.int_vec; - - //Set current Irq & Priority being serviced - ds5002fp.cur_irq = ds5002fp.int_vec; - ds5002fp.irq_priority = ds5002fp.priority_request; - - //Clear any interrupt flags that should be cleared since we're servicing the irq! - switch(ds5002fp.cur_irq) { - case V_IE0: - //External Int Flag only cleared when configured as Edge Triggered.. - //if(GET_IT0) - for some reason having this, breaks alving dmd games - SET_IE0(0); - break; - case V_TF0: - //Timer 0 - Always clear Flag - SET_TF0(0); - break; - case V_IE1: - //External Int Flag only cleared when configured as Edge Triggered.. - //if(GET_IT1) - for some reason having this, breaks alving dmd games - SET_IE1(0); - break; - case V_TF1: - //Timer 0 - Always clear Flag - SET_TF1(0); - break; - case V_RITI: - // no flags are cleared, TI and RI remain set until reset by software - break; - case V_PFI: - // no flags are cleared, PFW is reset by software - break; - } - - //Clear vars.. (these are part of the 8051 structure for speed, so we don't have to dynamically allocate space each time) - ds5002fp.int_vec = 0; - ds5002fp.priority_request = 0; - - //All interrupts use 2 machine cycles - return 24; -} - - -void ds5002fp_set_irq_callback(cpu_irq_callback irq_callback) -{ - ds5002fp.irq_callback = irq_callback; -} - -void ds5002fp_set_serial_tx_callback(void (*callback)(int data)) -{ - //Hold in static variable since this function can get called before reset has run, which wipes ds5002fp memory clean - hold_serial_tx_callback = callback; -} -void ds5002fp_set_serial_rx_callback(int (*callback)(void)) -{ - //Hold in static variable since this function can get called before reset has run, which wipes ds5002fp memory clean - hold_serial_rx_callback = callback; -} - -void ds5002fp_set_ebram_iaddr_callback(READ32_HANDLER((*callback))) -{ - //Hold in static variable since this function can get called before reset has run, which wipes ds5002fp memory clean - hold_ebram_iaddr_callback = callback; -} - - -void ds5002fp_state_save(void *file) -{ -} - -void ds5002fp_state_load(void *file) -{ -} - -/* HELPER FUNCTIONS */ - -/*All writes to SFR are handled here*/ -static WRITE8_HANDLER(sfr_write) -{ - UINT8 is_timed_access; - UINT8 reg_mask1; - UINT8 reg_mask2; - - data &= 0xff; //Ensure only 8 bits - switch (offset) - { - case P0: - R_P0 = data; - OUT(0,data); - break; - - case SP: - if(offset > 0xff) - LOG(("ds5002fp #%d: attemping to write value to SP past 256 bytes at 0x%04x\n", cpu_getactivecpu(), PC)); - R_SP = data&0xff; //keep sp w/in 256 bytes - break; - - case DPL: R_DPL = data; break; - case DPH: R_DPH = data; break; - case PCON: - reg_mask1 = 0xb9; - - is_timed_access = (ds5002fp.ta_window > 0) && (R_TA == 0x55); - if (is_timed_access) { - reg_mask1 = 0xff; - } - R_PCON = (R_PCON & (~reg_mask1)) | (data & reg_mask1); - break; - case TCON: R_TCON = data; break; - case TMOD: R_TMOD = data; break; - case TL0: R_TL0 = data; break; - case TL1: R_TL1 = data; break; - case TH0: R_TH0 = data; break; - case TH1: R_TH1 = data; break; - - case P1: - R_P1 = data; - OUT(1,data); - break; - - case SCON: { - //Update register - R_SCON = data; - break; - } - - case SBUF: - //R_SBUF = data; //This register is used only for "Receiving data coming in!" - serial_transmit(data); //Set up to transmit the data - break; - - case P2: - R_P2 = data; - OUT(2,data); - break; - - case IE: R_IE = data; break; - - case P3: - R_P3 = data; - OUT(3,data); - break; - - case IP: - reg_mask1 = 0x7f; - - is_timed_access = (ds5002fp.ta_window > 0) && (R_TA == 0x55); - if (is_timed_access) { - reg_mask1 = 0xff; - } - R_IP = (R_IP & (~reg_mask1)) | (data & reg_mask1); - break; - - case CRCR: reg_mask2 = 0x0f; - R_CRC = (R_CRC & (~reg_mask2)) | (data & reg_mask2); - LOG(("ds5002fp #%d: write to CRC register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, data)); - break; - case CRCL: R_CRCL = data; - LOG(("ds5002fp #%d: write to CRCL register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, data)); - break; - case CRCH: R_CRCH = data; - LOG(("ds5002fp #%d: write to CRCH register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, data)); - break; - case MCON: reg_mask1 = 0x0f; - reg_mask2 = 0xf7; - - is_timed_access = (ds5002fp.ta_window > 0) && (R_TA == 0x55); - if (is_timed_access) { - reg_mask1 = 0xff; - } - data = (R_MCON & (~reg_mask1)) | (data & reg_mask1); - R_MCON = (R_MCON & (~reg_mask2)) | (data & reg_mask2); - LOG(("ds5002fp #%d: write to MCON register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, data)); - break; - case TA: ds5002fp.previous_ta = R_TA; - R_TA = data; - - // init the time window after having wrote 0xaa - if ((data == 0xaa) && (ds5002fp.ta_window == 0)) { - ds5002fp.ta_window = 4*12 + 2*12; - LOG(("ds5002fp #%d: TA window initiated at 0x%04x\n", cpu_getactivecpu(), PC)); - } - //LOG(("ds5002fp #%d: write to TA register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, data)); - break; - case RNR: R_RNR = data; - LOG(("ds5002fp #%d: write to RNR register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, data)); - break; - - case PSW: - R_PSW = data; - SET_PARITY; - break; - - case RPCTL: reg_mask1 = 0xef; - reg_mask2 = 0xfe; - - is_timed_access = (ds5002fp.ta_window > 0) && (R_TA == 0x55); - if (is_timed_access) { - reg_mask1 = 0xff; - } - data = (R_RPCTL & (~reg_mask1)) | (data & reg_mask1); - R_RPCTL = (R_RPCTL & (~reg_mask2)) | (data & reg_mask2); - LOG(("ds5002fp #%d: write to RPCTL register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, data)); - break; - case RPS: R_RPS = data; - LOG(("ds5002fp #%d: write to RPS register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, data)); - break; - - case ACC: - R_ACC = data; - SET_PARITY; - break; - - case B: R_B = data; break; - - /* Illegal or non-implemented sfr */ - default: - LOG(("ds5002fp #%d: attemping to write to an invalid/non-implemented SFR address: %x at 0x%04x, data=%x\n", cpu_getactivecpu(), offset, PC, data)); - } -} - -/*All reads to SFR are handled here*/ -static READ8_HANDLER(sfr_read) -{ - switch (offset) - { - case P0: - if(RWM) - return R_P0; //Read directly from port latch - else - return IN(0); //Read from actual port - case SP: return R_SP; - case DPL: return R_DPL; - case DPH: return R_DPH; - case PCON: return R_PCON; - case TCON: return R_TCON; - case TMOD: return R_TMOD; - case TL0: return R_TL0; - case TL1: return R_TL1; - case TH0: return R_TH0; - case TH1: return R_TH1; - case P1: - if(RWM) - return R_P1; //Read directly from port latch - else - return IN(1); //Read from actual port - case SCON: return R_SCON; - case SBUF: return R_SBUF; - case P2: - if(RWM) - return R_P2; //Read directly from port latch - else - return IN(2); //Read from actual port - case IE: return R_IE; - case P3: - if(RWM) - return R_P3; //Read directly from port latch - else - return IN(3); //Read from actual port - case IP: return R_IP; - - case CRCR: LOG(("ds5002fp #%d: read CRC register at 0x%04x\n", cpu_getactivecpu(), PC)); - return R_CRC; - case CRCL: LOG(("ds5002fp #%d: read CRCL register at 0x%04x\n", cpu_getactivecpu(), PC)); - return R_CRCL; - case CRCH: LOG(("ds5002fp #%d: read CRCH register at 0x%04x\n", cpu_getactivecpu(), PC)); - return R_CRCH; - case MCON: LOG(("ds5002fp #%d: read MCON register at 0x%04x\n", cpu_getactivecpu(), PC)); - return R_MCON; - case TA: LOG(("ds5002fp #%d: read TA register at 0x%04x\n", cpu_getactivecpu(), PC)); - return R_TA; - case RNR: LOG(("ds5002fp #%d: read RNR register at 0x%04x\n", cpu_getactivecpu(), PC)); - return R_RNR; - - case PSW: return R_PSW; - - case RPCTL: LOG(("ds5002fp #%d: read RPCTL register at 0x%04x\n", cpu_getactivecpu(), PC)); - return R_RPCTL; - case RPS: LOG(("ds5002fp #%d: read RPS register at 0x%04x\n", cpu_getactivecpu(), PC)); - return R_RPS; - - case ACC: return R_ACC; - case B: return R_B; - - /* Illegal or non-implemented sfr */ - default: - LOG(("ds5002fp #%d: attemping to read an invalid/non-implemented SFR address: %x at 0x%04x\n", cpu_getactivecpu(), offset,PC)); - } - return 0xff; -} - -/* Reads the contents of the Internal RAM memory */ -/* Anything above 0x7f is a sfr/register */ -static READ8_HANDLER(internal_ram_read) -{ - if (offset < 0x80) - return ds5002fp.IntRam[offset]; - else { - if (offset < 0x100) - return SFR_R(offset); - else - LOG(("ds5002fp #%d: attemping to read from an invalid Internal Ram address: %x at 0x%04x\n", cpu_getactivecpu(), offset,PC)); - } - return 0xff; -} - -/* Writes the contents of the Internal RAM memory */ -/* Anything above 0x7f is a sfr/register */ -static WRITE8_HANDLER(internal_ram_write) -{ - data &= 0xff; //Ensure it's only 8 bits - if (offset < 0x80) - ds5002fp.IntRam[offset] = data; - else { - if (offset < 0x100) - SFR_W(offset,data); - else - LOG(("ds5002fp #%d: attemping to write to invalid Internal Ram address: %x at 0x%04x\n", cpu_getactivecpu(), offset,PC)); - } -} - -/* Reads the contents of the Internal RAM memory (BUT CALLED FROM AN INDIRECT ADDRESSING MODE) */ -/* Different chip types handle differently, for speed, simply call the chip's handler */ -static READ8_HANDLER(internal_ram_iread) -{ - return ds5002fp.iram_iread(machine,offset); -} - -/* Writes the contents of the Internal RAM memory (BUT CALLED FROM AN INDIRECT ADDRESSING MODE) */ -/* Different chip types handle differently, for speed, simply call the chip's handler */ -static WRITE8_HANDLER(internal_ram_iwrite) -{ - ds5002fp.iram_iwrite(machine,offset,data); -} - -/* Generate an expanded bus/bytewide bus ram address for read/writing */ -/* - The DS5002FP has 2 16 bits data address buses (the byte-wide bus and the expanded bus). The exact memory position accessed depends on the - partition mode, the memory range and the expanded bus select. The partition mode and the expanded bus select can be changed at any time. - - In order to simplify memory mapping to the data address bus, the following address map is assumed for partitioned mode: - - 0x00000-0x0ffff -> data memory on the expanded bus - 0x10000-0x1ffff -> data memory on the byte-wide bus - - For non-partitioned mode the following memory map is assumed: - - 0x0000-0xffff -> data memory (the bus used to access it does not matter) -*/ -static READ32_HANDLER(external_ram_iaddr) -{ - // if partition mode is set, adjust offset based on the bus - if (!GET_PM) { - if (!GET_EXBS) { - if ((offset >= ds5002fp_partitions[GET_PA]) && (offset <= ds5002fp_ranges[ds5002fp.range])) { - offset += 0x10000; - } - } - } - if(ds5002fp.ebram_iaddr_callback) - return ds5002fp.ebram_iaddr_callback(machine,offset,mem_mask); - else { - //LOG(("ds5002fp #%d: external ram address requested (8 bit offset=%02x), but no callback available! at PC:%04x\n", cpu_getactivecpu(), offset, PC)); - } - - return offset; -} - -/*Push the current PC to the stack*/ -INLINE void push_pc() -{ - UINT8 tmpSP = R_SP; //Grab and Increment Stack Pointer - tmpSP++; // "" - SFR_W(SP,tmpSP); // "" - if (tmpSP == R_SP) //Ensure it was able to write to new stack location - IRAM_IW(tmpSP, (PC & 0xff)); //Store low byte of PC to Internal Ram (Use IRAM_IW to store stack above 128 bytes) - tmpSP = R_SP; //Increment Stack Pointer - tmpSP++; // "" - SFR_W(SP,tmpSP); // "" - if (tmpSP == R_SP) //Ensure it was able to write to new stack location - IRAM_IW(tmpSP, ( (PC & 0xff00) >> 8)); //Store hi byte of PC to next address in Internal Ram (Use IRAM_IW to store stack above 128 bytes) -} - -/*Pop the current PC off the stack and into the pc*/ -INLINE void pop_pc() -{ - UINT8 tmpSP = R_SP; //Grab Stack Pointer - PC = (IRAM_IR(tmpSP) & 0xff) << 8; //Store hi byte to PC (must use IRAM_IR to access stack pointing above 128 bytes) - tmpSP = R_SP-1; //Decrement Stack Pointer - SFR_W(SP,tmpSP); // "" - if (tmpSP == R_SP) //Ensure it was able to write to new stack location - PC = PC | IRAM_IR(tmpSP); //Store lo byte to PC (must use IRAM_IR to access stack pointing above 128 bytes) - SFR_W(SP,tmpSP-1); //Decrement Stack Pointer -} - -//Set the PSW Parity Flag -INLINE void set_parity() -{ - //This flag will be set when the accumulator contains an odd # of bits set.. - int i, - p = 0; - for (i=1; i<=128; i=i*2) { //Test for each of the 8 bits in the ACC! - if ((R_ACC & i) != 0) - p++; //Keep track of how many bits are set - } - - //Update the PSW Pairty bit - SET_P(p & 1); -} - -static READ8_HANDLER(bit_address_r) -{ - int word; - int mask; - int bit_pos; - int base; /* base of bit space or sfr */ - int distance; /* distance between bit addressable words */ - /* 1 for normal bits, 8 for sfr bit addresses */ - - offset &= 0xff; - - //User defined bit addresses 0x20-0x2f (values are 0x0-0x7f) - if (offset < 0x80) { - base = 0x20; - distance = 1; - } - //SFR bit addressable registers - else { - base = 0x80; - distance = 8; - } - word = ( (offset & 0x78) >> 3) * distance + base; - bit_pos = offset & 0x7; - mask = 0x1 << bit_pos; - return((IRAM_R(word) & mask) >> bit_pos); //Do not use IRAM_IR -} - - -static WRITE8_HANDLER(bit_address_w) -{ - int word; - int mask; - int bit_pos; - int result; - int base; - int distance; - - offset &= 0xff; - - //User defined bit addresses 0x20-0x2f (values are 0x0-0x7f) - if (offset < 0x80) { - base = 0x20; - distance = 1; - } - //SFR bit addressable registers - else { - base = 0x80; - distance = 8; - } - word = ((offset & 0x78) >> 3) * distance + base; - bit_pos = offset & 0x7; - data = (data & 0x1) << bit_pos; - mask = ~(1 << bit_pos) & 0xff; - result = IRAM_R(word) & mask; //Do not use IRAM_IR - result = result | data; - IRAM_W(word, result); //Do not use IRAM_IW -} - -/* The following two handlers are used by the MAME Debugger Memory Window... - By keeping these functions separate from the internally used IRAM_W/IRAM_R functions, - we can manipulate and display internal memory in the debugger memory window in a layout - that is not necessarily how the real memory is.. this will be especially useful for - the 8052 chip where both the SFR and the upper 128 bytes of ram are mapped to the same - address, so we can handle that here by mapping the sfr to a different address */ - -READ8_HANDLER(ds5002fp_internal_r) -{ - //Restrict internal ram to 256 Bytes max - if(offset < 0x100) - return IRAM_R(offset); - else - return 0; -} -WRITE8_HANDLER(ds5002fp_internal_w) -{ - //Restrict internal ram to 256 Bytes max - if(offset < 0x100) - IRAM_W(offset,data); -} - -INLINE void do_add_flags(UINT8 a, UINT8 data, UINT8 c) -{ - UINT16 result = a+data+c; - INT16 result1 = (INT8)a+(INT8)data+c; - int cy, ac, ov; - - cy = (result & 0x100) >> 8; - result = (a&0x0f)+(data&0x0f)+c; - ac = (result & 0x10) >> 4; - ov = (result1 < -128 || result1 > 127); - - SET_CY(cy); - SET_AC(ac); - SET_OV(ov); - -// mame_printf_debug("add: result=%x, c=%x, ac=%x, ov=%x\n",a+data+c,cy,ac,ov); -} - -INLINE void do_sub_flags(UINT8 a, UINT8 data, UINT8 c) -{ - UINT16 result = a-(data+c); - INT16 result1 = (INT8)a-(INT8)(data+c); - int cy, ac, ov; - cy = (result & 0x100) >> 8; - result = (a&0x0f)-((data&0x0f)+c); - ac = (result & 0x10) >> 4; - ov = (result1 < -128 || result1 > 127); - SET_CY(cy); - SET_AC(ac); - SET_OV(ov); - -// mame_printf_debug("sub: a=%x, d=%x, c=%x, result=%x, cy=%x, ac=%x, ov=%x\n",a,data,c,a-data-c,cy,ac,ov); -} - -INLINE void update_timer(int cyc) -{ - //This code sucks, needs to be rewritten SJE - - //Todo: Probably better to store the current mode of the timer on a write, so we don't waste time reading it. - - //Note: Counting modes increment on 1 machine cycle (12 oscilator periods) - except Timer 2 in certain modes - - //Update Timer 0 - if(GET_TR0) { - //Determine Mode - int mode = (GET_M0_1<<1) | GET_M0_0; - int overflow; - UINT16 count = 0; - switch(mode) { - case 0: //13 Bit Timer Mode - count = ((R_TH0<<8) | R_TL0); - overflow = 0x3fff; - //Todo - really, we update HI counter when LO counter hits 0x20 - case 1: //16 Bit Timer Mode - count = ((R_TH0<<8) | R_TL0); - overflow = 0xffff; - //Check for overflow - if((UINT32)(count+(cyc/12))>overflow) { - //Any overflow from cycles? - cyc-= (overflow-count)*12; - count = 0; - SET_TF0(1); - } - //Update the timer - if(cyc) { - int inctimer = 0; - //Gate Bit Set? Timer only incremented if Int0 is set! - if(GET_GATE0 && GET_IE0) - inctimer = (cyc/12); - //Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line - if(GET_CT0) { - //Not supported - } - //Neither, regular timer mode - if(!GET_GATE0 && !GET_CT0) - inctimer = (cyc/12); - - count+=inctimer; //Increment counter - } - //Update new values of the counter - R_TH0 = (count>>8) & 0xff; - R_TL0 = count & 0xff; - break; - case 2: //8 Bit Autoreload - overflow = 0xff; - count = R_TL0; - //Check for overflow - if(count+(cyc/12)>overflow) { - SET_TF0(1); - //Reload - count = R_TH0+(overflow-count); - } - else - count+=(cyc/12); - //Update new values of the counter - R_TL0 = count & 0xff; - break; - case 3: //Split Timer - //Split Timer 1 - overflow = 0xff; - count = R_TL0; - //Check for overflow - if(count+(cyc/12)>overflow) { - count = overflow-count; - SET_TF0(1); - } - else - count+=(cyc/12); - //Update new values of the counter - R_TL0 = count & 0xff; - - //Split Timer 2 - if(GET_TR1) { - overflow = 0xff; - count = R_TH0; - //Check for overflow - if(count+(cyc/12)>overflow) { - count = overflow-count; - SET_TF1(1); - } - else - count+=(cyc/12); - //Update new values of the counter - R_TH0 = count & 0xff; - } - break; - } - } - - //Update Timer 1 - if(GET_TR1) { - //Determine Mode - int mode = (GET_M1_1<<1) | GET_M1_0; - int overflow; - UINT16 count = 0; - switch(mode) { - case 0: //13 Bit Timer Mode - count = ((R_TH1<<8) | R_TL1); - overflow = 0x3fff; - //Todo - really, we update HI counter when LO counter hits 0x20 - case 1: //16 Bit Timer Mode - count = ((R_TH1<<8) | R_TL1); - overflow = 0xffff; - //Check for overflow - if((UINT32)(count+(cyc/12))>overflow) { - - //TODO: Timer 1 can be set as Serial Baud Rate in the 8051 only... process bits here.. - - //Any overflow from cycles? - cyc-= (overflow-count)*12; - count = 0; - SET_TF1(1); - } - //Update the timer - if(cyc) { - int inctimer = 0; - //Gate Bit Set? Timer only incremented if Int0 is set! - if(GET_GATE1 && GET_IE1) - inctimer = (cyc/12); - //Counter Mode? Only increment on 1-0 transition of the Port 3's T0 Line - if(GET_CT1) { - //Not supported - } - //Neither, regular timer mode - if(!GET_GATE1 && !GET_CT1) - inctimer = (cyc/12); - - count+=inctimer; //Increment counter - } - //Update new values of the counter - R_TH1 = (count>>8) & 0xff; - R_TL1 = count & 0xff; - break; - case 2: //8 Bit Autoreload - overflow = 0xff; - count = R_TL1; - //Check for overflow - if(count+(cyc/12)>overflow) { - SET_TF1(1); - //Reload - count = R_TH1+(overflow-count); - } - else - count+=(cyc/12); - //Update new values of the counter - R_TL1 = count & 0xff; - break; - case 3: //Split Timer - break; - } - } -} - -//Set up to transmit data out of serial port -//NOTE: Enable Serial Port Interrupt bit is NOT required to send/receive data! -INLINE void serial_transmit(UINT8 data) -{ - int mode = (GET_SM0<<1) | GET_SM1; - - //Flag that we're sending data - uart.sending = 1; - uart.data_out = data; - switch(mode) { - //8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12 - case 0: - uart.timerbaud = 0; - uart.bitcycles = 0; - uart.bits_to_send = 8+2; - break; - //8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2 - case 1: - uart.timerbaud = 1; - uart.bits_to_send = 8+2; - break; - //9 bit uart - case 2: - case 3: - LOG(("Serial mode 2 & 3 not supported in ds5002fp!\n")); - break; - } -} - -//Check and update status of serial port -INLINE void update_serial(int cyc) -{ - //Any bits left to send? - if(uart.bits_to_send) { - //Timer Generated baud? - if(uart.timerbaud) { - //Let Timer overflow handle removing bits - } - else { - //Oscillator Based baud rate = Osc/12 baud rate, however it also means 1 bit = 12 cycles. - uart.bitcycles+=cyc; - if(uart.bitcycles > 11) { - int bits_sent = uart.bitcycles / 12; - int diff = uart.bitcycles % 12; - //don't allow more bits sent than ready to send - if(bits_sent > uart.bits_to_send) { - bits_sent = uart.bits_to_send; - diff = 0; - } - uart.bits_to_send-=bits_sent; - uart.bitcycles = diff; - } - } - } - //If no bits left to send - flag the interrupt & call the callback - if(!uart.bits_to_send) { - //Clear sending flag - uart.sending = 0; - uart.bitcycles = 0; - //Call the callback function - if(ds5002fp.serial_tx_callback) - ds5002fp.serial_tx_callback(uart.data_out); - //Set Interrupt Flag - SET_TI(1); - //Note: we'll let the main loop catch the interrupt - } -} - -/************************************************************************** - * Generic set_info - **************************************************************************/ - -static void ds5002fp_set_info(UINT32 state, cpuinfo *info) -{ - switch (state) - { - /* --- the following bits of info are set as 64-bit signed integers --- */ - case CPUINFO_INT_PC: PC = info->i; break; - case CPUINFO_INT_SP: ds5002fp.sp = info->i; break; - - case CPUINFO_INT_INPUT_STATE + DS5002FP_INT0_LINE: ds5002fp_set_irq_line(DS5002FP_INT0_LINE, info->i); break; - case CPUINFO_INT_INPUT_STATE + DS5002FP_INT1_LINE: ds5002fp_set_irq_line(DS5002FP_INT1_LINE, info->i); break; - case CPUINFO_INT_INPUT_STATE + DS5002FP_T0_LINE: ds5002fp_set_irq_line(DS5002FP_T0_LINE, info->i); break; - case CPUINFO_INT_INPUT_STATE + DS5002FP_T1_LINE: ds5002fp_set_irq_line(DS5002FP_T1_LINE, info->i); break; - case CPUINFO_INT_INPUT_STATE + DS5002FP_RX_LINE: ds5002fp_set_irq_line(DS5002FP_RX_LINE, info->i); break; - case CPUINFO_INT_INPUT_STATE + DS5002FP_PFI_LINE: ds5002fp_set_irq_line(DS5002FP_PFI_LINE, info->i); break; - - case CPUINFO_INT_REGISTER + DS5002FP_PC: PC = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_SP: R_SP = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_PSW: ds5002fp.psw = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_ACC: ds5002fp.acc = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_B: ds5002fp.b = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_DPH: ds5002fp.dph = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_DPL: ds5002fp.dpl = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_IE: ds5002fp.ie = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_PCON: ds5002fp.pcon = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_MCON: ds5002fp.mcon = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_RPCTL: ds5002fp.rpctl = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_CRC: ds5002fp.crc = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_R0: ds5002fp.IntRam[0+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_R1: ds5002fp.IntRam[1+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_R2: ds5002fp.IntRam[2+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_R3: ds5002fp.IntRam[3+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_R4: ds5002fp.IntRam[4+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_R5: ds5002fp.IntRam[5+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_R6: ds5002fp.IntRam[6+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_R7: ds5002fp.IntRam[7+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - case CPUINFO_INT_REGISTER + DS5002FP_RB: ds5002fp.IntRam[8+(8*((ds5002fp.psw & 0x18)>>3))] = info->i; break; - } -} - -/************************************************************************** - * Generic get_info - **************************************************************************/ - -void ds5002fp_get_info(UINT32 state, cpuinfo *info) -{ - DS5002FP *r = &ds5002fp; - - switch (state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(ds5002fp); break; - case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; - case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break; - case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; - case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; - case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; - case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 5; break; - case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; - case CPUINFO_INT_MAX_CYCLES: info->i = 20; /* rough guess */ break; - case CPUINFO_INT_INPUT_LINES: info->i = 6; break; - - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 17; /* really 16 bits, but it has 2 address bus */ break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; - - case CPUINFO_INT_PREVIOUSPC: info->i = PPC; break; - case CPUINFO_INT_PC: info->i = PC; break; - case CPUINFO_INT_SP: info->i = R_SP; break; - - case CPUINFO_INT_REGISTER + DS5002FP_PC: info->i = PC; break; - case CPUINFO_INT_REGISTER + DS5002FP_SP: info->i = R_SP; break; - case CPUINFO_INT_REGISTER + DS5002FP_PSW: info->i = ds5002fp.psw; break; - case CPUINFO_INT_REGISTER + DS5002FP_ACC: info->i = ds5002fp.acc; break; - case CPUINFO_INT_REGISTER + DS5002FP_B: info->i = ds5002fp.b; break; - case CPUINFO_INT_REGISTER + DS5002FP_DPH: info->i = ds5002fp.dph; break; - case CPUINFO_INT_REGISTER + DS5002FP_DPL: info->i = ds5002fp.dpl; break; - case CPUINFO_INT_REGISTER + DS5002FP_IE: info->i = ds5002fp.ie; break; - case CPUINFO_INT_REGISTER + DS5002FP_PCON: info->i = ds5002fp.pcon; break; - case CPUINFO_INT_REGISTER + DS5002FP_MCON: info->i = ds5002fp.mcon; break; - case CPUINFO_INT_REGISTER + DS5002FP_RPCTL: info->i = ds5002fp.rpctl; break; - case CPUINFO_INT_REGISTER + DS5002FP_CRC: info->i = ds5002fp.crc; break; - case CPUINFO_INT_REGISTER + DS5002FP_R0: info->i = ds5002fp.IntRam[0+(8*((ds5002fp.psw & 0x18)>>3))]; break; - case CPUINFO_INT_REGISTER + DS5002FP_R1: info->i = ds5002fp.IntRam[1+(8*((ds5002fp.psw & 0x18)>>3))]; break; - case CPUINFO_INT_REGISTER + DS5002FP_R2: info->i = ds5002fp.IntRam[2+(8*((ds5002fp.psw & 0x18)>>3))]; break; - case CPUINFO_INT_REGISTER + DS5002FP_R3: info->i = ds5002fp.IntRam[3+(8*((ds5002fp.psw & 0x18)>>3))]; break; - case CPUINFO_INT_REGISTER + DS5002FP_R4: info->i = ds5002fp.IntRam[4+(8*((ds5002fp.psw & 0x18)>>3))]; break; - case CPUINFO_INT_REGISTER + DS5002FP_R5: info->i = ds5002fp.IntRam[5+(8*((ds5002fp.psw & 0x18)>>3))]; break; - case CPUINFO_INT_REGISTER + DS5002FP_R6: info->i = ds5002fp.IntRam[6+(8*((ds5002fp.psw & 0x18)>>3))]; break; - case CPUINFO_INT_REGISTER + DS5002FP_R7: info->i = ds5002fp.IntRam[7+(8*((ds5002fp.psw & 0x18)>>3))]; break; - case CPUINFO_INT_REGISTER + DS5002FP_RB: info->i = ds5002fp.IntRam[8+(8*((ds5002fp.psw & 0x18)>>3))]; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_PTR_SET_INFO: info->setinfo = ds5002fp_set_info; break; - case CPUINFO_PTR_GET_CONTEXT: info->getcontext = ds5002fp_get_context; break; - case CPUINFO_PTR_SET_CONTEXT: info->setcontext = ds5002fp_set_context; break; - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(ds5002fp); break; - case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(ds5002fp); break; - case CPUINFO_PTR_EXIT: info->exit = CPU_EXIT_NAME(ds5002fp); break; - case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(ds5002fp); break; - case CPUINFO_PTR_BURN: info->burn = NULL; break; - case CPUINFO_PTR_DISASSEMBLE: info->disassemble = ds5002fp_dasm; break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &ds5002fp_icount; break; - - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = NULL; break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = NULL; break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_IO: info->internal_map8 = NULL; break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "DS5002FP"); break; - case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Dallas"); break; - case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break; - case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; - case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Manuel Abadia"); break; - - case CPUINFO_STR_FLAGS: - sprintf(info->s, "%c%c%c%c%c%c%c%c", - r->psw & 0x80 ? 'C':'.', - r->psw & 0x40 ? 'A':'.', - r->psw & 0x20 ? 'F':'.', - r->psw & 0x10 ? '0':'.', - r->psw & 0x08 ? '1':'.', - r->psw & 0x04 ? 'V':'.', - r->psw & 0x02 ? '?':'.', - r->psw & 0x01 ? 'P':'.'); - break; - - case CPUINFO_STR_REGISTER + DS5002FP_PC: sprintf(info->s, "PC:%04X", r->pc); break; - case CPUINFO_STR_REGISTER + DS5002FP_SP: sprintf(info->s, "SP:%02X", r->sp); break; - case CPUINFO_STR_REGISTER + DS5002FP_PSW: sprintf(info->s, "PSW:%02X", r->psw); break; - case CPUINFO_STR_REGISTER + DS5002FP_ACC: sprintf(info->s, "A:%02X", r->acc); break; - case CPUINFO_STR_REGISTER + DS5002FP_B: sprintf(info->s, "B:%02X", r->b); break; - case CPUINFO_STR_REGISTER + DS5002FP_DPH: sprintf(info->s, "DPH:%02X", r->dph); break; - case CPUINFO_STR_REGISTER + DS5002FP_DPL: sprintf(info->s, "DPL:%02X", r->dpl); break; - case CPUINFO_STR_REGISTER + DS5002FP_IE: sprintf(info->s, "IE:%02X", r->ie); break; - case CPUINFO_STR_REGISTER + DS5002FP_PCON: sprintf(info->s, "PCON:%02X", r->pcon); break; - case CPUINFO_STR_REGISTER + DS5002FP_MCON: sprintf(info->s, "MCON:%02X", r->mcon); break; - case CPUINFO_STR_REGISTER + DS5002FP_RPCTL: sprintf(info->s, "RPCTL:%02X", r->rpctl);break; - case CPUINFO_STR_REGISTER + DS5002FP_CRC: sprintf(info->s, "CRC:%02X", r->crc); break; - case CPUINFO_STR_REGISTER + DS5002FP_R0: sprintf(info->s, "R0:%02X", r->IntRam[0+(8*((r->psw & 0x18)>>3))]); break; - case CPUINFO_STR_REGISTER + DS5002FP_R1: sprintf(info->s, "R1:%02X", r->IntRam[1+(8*((r->psw & 0x18)>>3))]); break; - case CPUINFO_STR_REGISTER + DS5002FP_R2: sprintf(info->s, "R2:%02X", r->IntRam[2+(8*((r->psw & 0x18)>>3))]); break; - case CPUINFO_STR_REGISTER + DS5002FP_R3: sprintf(info->s, "R3:%02X", r->IntRam[3+(8*((r->psw & 0x18)>>3))]); break; - case CPUINFO_STR_REGISTER + DS5002FP_R4: sprintf(info->s, "R4:%02X", r->IntRam[4+(8*((r->psw & 0x18)>>3))]); break; - case CPUINFO_STR_REGISTER + DS5002FP_R5: sprintf(info->s, "R5:%02X", r->IntRam[5+(8*((r->psw & 0x18)>>3))]); break; - case CPUINFO_STR_REGISTER + DS5002FP_R6: sprintf(info->s, "R6:%02X", r->IntRam[6+(8*((r->psw & 0x18)>>3))]); break; - case CPUINFO_STR_REGISTER + DS5002FP_R7: sprintf(info->s, "R7:%02X", r->IntRam[7+(8*((r->psw & 0x18)>>3))]); break; - case CPUINFO_STR_REGISTER + DS5002FP_RB: sprintf(info->s, "RB:%02X", ((r->psw & 0x18)>>3)); break; - } -} diff --git a/src/emu/cpu/ds5002fp/ds5002fp.h b/src/emu/cpu/ds5002fp/ds5002fp.h deleted file mode 100644 index 96529c7b697..00000000000 --- a/src/emu/cpu/ds5002fp/ds5002fp.h +++ /dev/null @@ -1,138 +0,0 @@ -/***************************************************************************** - * DS5002FP emulator - * - * The emulator is just a modified version of the MCS-51 Family Emulator by Steve Ellenoff - * - *****************************************************************************/ - -/***************************************************************************** - * - * i8051.h - * Portable MCS-51 Family Emulator - * - * Chips in the family: - * 8051 Product Line (8031,8051,8751) - * 8052 Product Line (8032,8052,8752) - * 8054 Product Line (8054) - * 8058 Product Line (8058) - * - * Copyright Steve Ellenoff, all rights reserved. - * - * - 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. - * - If you modify this source code, you must add a notice to each modified - * source file that it has been changed. If you're a nice person, you - * will clearly mark each change too. :) - * - If you wish to use this for commercial purposes, please contact me at - * sellenoff@hotmail.com - * - The author of this copywritten work reserves the right to change the - * terms of its usage and license at any time, including retroactively - * - This entire notice must remain in the source code. - * - * This work is based on: - * #1) 'Intel(tm) MC51 Microcontroller Family Users Manual' and - * #2) 8051 simulator by Travis Marlatte - * #3) Portable UPI-41/8041/8741/8042/8742 emulator V0.1 by Juergen Buchmueller (MAME CORE) - * - *****************************************************************************/ - -#pragma once - -#ifndef __DS5002FP_H__ -#define __DS5002FP_H__ - -#include "cpuintrf.h" - -enum -{ - DS5002FP_PC=1, DS5002FP_SP, DS5002FP_PSW, DS5002FP_ACC, DS5002FP_B, DS5002FP_DPH, DS5002FP_DPL, DS5002FP_IE, - DS5002FP_PCON, DS5002FP_MCON, DS5002FP_RPCTL, DS5002FP_CRC, - DS5002FP_R0, DS5002FP_R1, DS5002FP_R2, DS5002FP_R3, DS5002FP_R4, DS5002FP_R5, DS5002FP_R6, DS5002FP_R7, DS5002FP_RB -}; - -#define DS5002FP_INT0_LINE 0 /* External Interrupt 0 */ -#define DS5002FP_INT1_LINE 1 /* External Interrupt 1 */ -#define DS5002FP_T0_LINE 2 /* Timer 0 External Input */ -#define DS5002FP_T1_LINE 3 /* Timer 1 External Input */ -#define DS5002FP_RX_LINE 4 /* Serial Port Receive Line */ -#define DS5002FP_PFI_LINE 5 /* Power Fail Interrupt */ - -/* definition of the special function registers. Note that the values are */ -/* the same as the internal memory address in the DS5002FP */ -#define P0 0x80 -#define SP 0x81 -#define DPL 0x82 -#define DPH 0x83 -#define PCON 0x87 -#define TCON 0x88 -#define TMOD 0x89 -#define TL0 0x8a -#define TL1 0x8b -#define TH0 0x8c -#define TH1 0x8d -#define P1 0x90 -#define SCON 0x98 -#define SBUF 0x99 -#define P2 0xa0 -#define IE 0xa8 -#define P3 0xb0 -#define IP 0xb8 -#define CRCR 0xc1 -#define CRCL 0xc2 -#define CRCH 0xc3 -#define MCON 0xc6 -#define TA 0xc7 -#define RNR 0xcf -#define PSW 0xd0 -#define RPCTL 0xd8 -#define RPS 0xda -#define ACC 0xe0 -#define B 0xf0 - -/* commonly used bit address for the DS5002FP */ -#define C 0xd7 -#define P 0xd0 -#define AC 0xd6 -#define OV 0xd2 -#define PFW 0x8d -#define TF1 0x8f -#define IE0 0x89 -#define IE1 0x8b -#define TI 0x99 -#define RI 0x98 - -#define TI_FLAG 1 -#define RI_FLAG 2 - -/* configuration of the DS5002FP */ -typedef struct _ds5002fp_config ds5002fp_config; -struct _ds5002fp_config -{ - UINT8 mcon; /* bootstrap loader MCON register */ - UINT8 rpctl; /* bootstrap loader RPCTL register */ - UINT8 crc; /* bootstrap loader CRC register */ -}; - -extern void ds5002fp_get_context (void *dst); /* Get registers, return context size */ -extern void ds5002fp_set_context (void *src); /* Set registers */ -extern unsigned ds5002fp_get_intram (int offset); -extern unsigned ds5002fp_get_reg (int regnum); -extern void ds5002fp_set_reg (int regnum, unsigned val); -extern void ds5002fp_set_irq_line(int irqline, int state); -extern void ds5002fp_set_irq_callback(cpu_irq_callback callback); -extern void ds5002fp_state_save(void *file); -extern void ds5002fp_state_load(void *file); - -WRITE8_HANDLER( ds5002fp_internal_w ); -READ8_HANDLER( ds5002fp_internal_r ); - -extern void ds5002fp_set_serial_tx_callback(void (*callback)(int data)); -extern void ds5002fp_set_serial_rx_callback(int (*callback)(void)); -extern void ds5002fp_set_ebram_iaddr_callback(READ32_HANDLER((*callback))); - -extern offs_t ds5002fp_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram); - -void ds5002fp_get_info(UINT32 state, cpuinfo *info); - -#endif /* __DS5002FP_H__ */ diff --git a/src/emu/cpu/ds5002fp/ds5002fpdasm.c b/src/emu/cpu/ds5002fp/ds5002fpdasm.c deleted file mode 100644 index bd4a8c5a104..00000000000 --- a/src/emu/cpu/ds5002fp/ds5002fpdasm.c +++ /dev/null @@ -1,1040 +0,0 @@ -/***************************************************************************** - * DS5002FP emulator - * - * The emulator is just a modified version of the MCS-51 Family Emulator by Steve Ellenoff - * - *****************************************************************************/ - -/***************************************************************************** - * - * i8051dasm.c - * Portable MCS-51 Family Emulator - * - * Chips in the family: - * 8051 Product Line (8031,8051,8751) - * 8052 Product Line (8032,8052,8752) - * 8054 Product Line (8054) - * 8058 Product Line (8058) - * - * Copyright Steve Ellenoff, all rights reserved. - * - * - 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. - * - If you modify this source code, you must add a notice to each modified - * source file that it has been changed. If you're a nice person, you - * will clearly mark each change too. :) - * - If you wish to use this for commercial purposes, please contact me at - * sellenoff@hotmail.com - * - The author of this copywritten work reserves the right to change the - * terms of its usage and license at any time, including retroactively - * - This entire notice must remain in the source code. - * - * This work is based on: - * #1) 'Intel(tm) MC51 Microcontroller Family Users Manual' and - * #2) 8051 simulator by Travis Marlatte - * #3) Portable UPI-41/8041/8741/8042/8742 emulator V0.1 by Juergen Buchmueller (MAME CORE) - * - ***************************************************************************** - * Symbol Memory Name Tables borrowed from: - * D52 8052 Disassembler - Copyright Jeffery L. Post - *****************************************************************************/ - -#include "debugger.h" -#include "ds5002fp.h" - -#define SHOW_MEMORY_NAMES 1 - -#ifdef SHOW_MEMORY_NAMES - -/*Display the memory address names for data & bit address access*/ - -//SFR Names -static const char sfr[128][7] = { - "p0", "sp", "dpl", "dph", /* 80 - 83 */ - "84h", "85h", "86h", "pcon", /* 84 - 87 */ - "tcon", "tmod", "tl0", "tl1", /* 88 - 8b */ - "th0", "th1", "pwcm", "pwmp", /* 8a - 8f */ - "p1", "91h", "92h", "93h", /* 90 - 93 */ - "94h", "95h", "96h", "97h", /* 94 - 97 */ - "scon", "sbuf", "9ah", "9bh", /* 98 - 9b */ - "9ch", "9dh", "9eh", "9fh", /* 9c - 9f */ - "p2", "0a1h", "0a2h", "0a3h", /* a0 - a3 */ - "0a4h", "0a5h", "0a6h", "0a7h", /* a4 - a7 */ - "ie", "0a9h", "0aah", "0abh", /* a8 - ab */ - "0ach", "0adh", "0aeh", "0afh", /* ac - af */ - "p3", "0b1h", "0b2h", "0b3h", /* b0 - b3 */ - "0b4h", "0b5h", "0b6h", "0b7h", /* b4 - b7 */ - "ip", "0b9h", "0bah", "0bbh", /* b8 - bb */ - "0bch", "0bdh", "0beh", "0bfh", /* bc - bf */ - "0c0h", "crc", "crcl", "crch", /* c0 - c3 */ - "0c4h", "0c5h", "mcon", "ta", /* c4 - c7 */ - "0c8h", "0c9h", "0cah", "0cbh", /* c8 - cb */ - "0cch", "0cdh", "0ceh", "rnr", /* cc - cf */ - "psw", "0d1h", "0d2h", "0d3h", /* d0 - d3 */ - "0d4h", "0d5h", "0d6h", "0d7h", /* d4 - d7 */ - "rpctl", "0d9h", "rps", "0dbh", /* d8 - db */ - "0dch", "0ddh", "0deh", "0dfh", /* dc - df */ - "acc", "0e1h", "0e2h", "0e3h", /* e0 - e3 */ - "0e4h", "0e5h", "0e6h", "0e7h", /* e4 - e7 */ - "0e8h", "0e9h", "0eah", "0ebh", /* e8 - eb */ - "0ech", "0edh", "0eeh", "0efh", /* ec - ef */ - "b", "0f1h", "0f2h", "0f3h", /* f0 - f3 */ - "0f4h", "0f5h", "0f6h", "0f7h", /* f4 - f7 */ - "0f8h", "0f9h", "0fah", "0fbh", /* f8 - fb */ - "0fch", "0fdh", "0feh", "0ffh" /* fc - ff */ -}; - -//SFR Addressable bits -static const char sfrbits[128][8] = { - "p0.0", "p0.1", "p0.2", "p0.3", /* 80 - 83 */ - "p0.4", "p0.5", "p0.6", "p0.7", /* 84 - 87 */ - "it0", "ie0", "it1", "ie1", /* 88 - 8b */ - "tr0", "tf0", "tr1", "tf1", /* 8c - 8f */ - "p1.0", "p1.1", "p1.2", "p1.3", /* 90 - 93 */ - "p1.4", "p1.5", "p1.6", "p1.7", /* 94 - 97 */ - "ri", "ti", "rb8", "tb8", /* 98 - 9b */ - "ren", "sm2", "sm1", "sm0", /* 9c - 9f */ - "p2.0", "p2.1", "p2.2", "p2.3", /* a0 - a3 */ - "p2.4", "p2.5", "p2.6", "p2.7", /* a4 - a7 */ - "ex0", "et0", "ex1", "et1", /* a8 - ab */ - "es", "ie.5", "ie.6", "ea", /* ac - af */ - "p3.0", "p3.1", "p3.2", "p3.3", /* b0 - b3 */ - "p3.4", "p3.5", "p3.6", "p3.7", /* b4 - b7 */ - "px0", "pt0", "px1", "pt1", /* b8 - bb */ - "ps", "ip.5", "ip.6", "rwt", /* bc - bf */ - "0c0h.0", "0c0h.1", "0c0h.2", "0c0h.3", /* c0 - c3 */ - "0c0h.4", "0c0h.5", "0c0h.6", "0c0h.7", /* c4 - c7 */ - "0c8h.0", "0c8h.1", "0c8h.2", "0c8h.3", /* c8 - cb */ - "0c8h.4", "0c8h.5", "0c8h.6", "0c8h.7", /* cc - cf */ - "p", "psw.1", "ov", "rs0", /* d0 - d3 */ - "rs1", "f0", "ac", "c", /* d4 - d7 */ - "rg0", "rpc", "dma", "ibi", /* d8 - db */ - "ae", "exbs", "0d8h.6", "rnr", /* dc - df */ - "acc.0", "acc.1", "acc.2", "acc.3", /* e0 - e3 */ - "acc.4", "acc.5", "acc.6", "acc.7", /* e4 - e7 */ - "0e8h.0", "0e8h.1", "0e8h.2", "0e8h.3", /* e8 - eb */ - "0e8h.4", "0e8h.5", "0e8h.6", "0e8h.7", /* ec - ef */ - "b.0", "b.1", "b.2", "b.3", /* f0 - f3 */ - "b.4", "b.5", "b.6", "b.7", /* f4 - f7 */ - "0f8h.0", "0f8h.1", "0f8h.2", "0f8h.3", /* f8 - fb */ - "0f8h.4", "0f8h.5", "0f8h.6", "0f8h.7" /* fc - ff */ -} ; - -//Names for bit addressable memory -static const char membits[128][6] = { - "20h.0", "20h.1", "20h.2", "20h.3", - "20h.4", "20h.5", "20h.6", "20h.7", - "21h.0", "21h.1", "21h.2", "21h.3", - "21h.4", "21h.5", "21h.6", "21h.7", - "22h.0", "22h.1", "22h.2", "22h.3", - "22h.4", "22h.5", "22h.6", "22h.7", - "23h.0", "23h.1", "23h.2", "23h.3", - "23h.4", "23h.5", "23h.6", "23h.7", - "24h.0", "24h.1", "24h.2", "24h.3", - "24h.4", "24h.5", "24h.6", "24h.7", - "25h.0", "25h.1", "25h.2", "25h.3", - "25h.4", "25h.5", "25h.6", "25h.7", - "26h.0", "26h.1", "26h.2", "26h.3", - "26h.4", "26h.5", "26h.6", "26h.7", - "27h.0", "27h.1", "27h.2", "27h.3", - "27h.4", "27h.5", "27h.6", "27h.7", - "28h.0", "28h.1", "28h.2", "28h.3", - "28h.4", "28h.5", "28h.6", "28h.7", - "29h.0", "29h.1", "29h.2", "29h.3", - "29h.4", "29h.5", "29h.6", "29h.7", - "2ah.0", "2ah.1", "2ah.2", "2ah.3", - "2ah.4", "2ah.5", "2ah.6", "2ah.7", - "2bh.0", "2bh.1", "2bh.2", "2bh.3", - "2bh.4", "2bh.5", "2bh.6", "2bh.7", - "2ch.0", "2ch.1", "2ch.2", "2ch.3", - "2ch.4", "2ch.5", "2ch.6", "2ch.7", - "2dh.0", "2dh.1", "2dh.2", "2dh.3", - "2dh.4", "2dh.5", "2dh.6", "2dh.7", - "2eh.0", "2eh.1", "2eh.2", "2eh.3", - "2eh.4", "2eh.5", "2eh.6", "2eh.7", - "2fh.0", "2fh.1", "2fh.2", "2fh.3", - "2fh.4", "2fh.5", "2fh.6", "2fh.7" -}; - -//Regiser Bank memory names -static const char regbank[][6] = { - "rb0r0", "rb0r1", "rb0r2", "rb0r3", - "rb0r4", "rb0r5", "rb0r6", "rb0r7", - "rb1r0", "rb1r1", "rb1r2", "rb1r3", - "rb1r4", "rb1r5", "rb1r6", "rb1r7", - "rb2r0", "rb2r1", "rb2r2", "rb2r3", - "rb2r4", "rb2r5", "rb2r6", "rb2r7", - "rb3r0", "rb3r1", "rb3r2", "rb3r3", - "rb3r4", "rb3r5", "rb3r6", "rb3r7" -}; - -static const char *get_data_address( UINT8 arg ) -{ - char *buffer = cpuintrf_temp_str(); - - if(arg < 0x80) - { - //Ram locations 0-0x1F are considered register access in 3 banks - if(arg < 0x1f) - sprintf(buffer,"%s",regbank[arg]); - else - sprintf(buffer,"$%02X",arg); - } - else - sprintf(buffer,"%s",sfr[arg-0x80]); - return buffer; -} - -static const char *get_bit_address( UINT8 arg ) -{ - char *buffer = cpuintrf_temp_str(); - - if(arg < 0x80) - { - //Bit address 0-7F can be referred to as 20.0, 20.1, to 20.7 for address 0, and 2f.0,2f.1 to 2f.7 for address 7f - if(arg < 0x7f) - sprintf(buffer,"%s",membits[arg]); - else - sprintf(buffer,"$%02X",arg); - } - else - sprintf(buffer,"%s",sfrbits[arg-0x80]); - return buffer; -} - -#else - -/*Just display the actual memory address for data & bit address access*/ - -static const char *get_data_address( UINT8 arg ) -{ - char *buffer = cpuintrf_temp_str(); - sprintf(buffer,"$%02X",arg); - return buffer; -} - -static const char *get_bit_address( UINT8 arg ) -{ - char *buffer = cpuintrf_temp_str(); - sprintf(buffer,"$%02X",arg); - return buffer; -} - -#endif - - -unsigned ds5002fp_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opram) -{ - UINT32 flags = 0; - unsigned PC = pc; - const char *sym, *sym2; - UINT8 op, data; - UINT16 addr; - INT8 rel; - - op = oprom[PC++ - pc]; - switch( op ) - { - //NOP - case 0x00: /* 1: 0000 0000 */ - sprintf(dst, "nop"); - break; - - //AJMP code addr /* 1: aaa0 0001 */ - case 0x01: - case 0x21: - case 0x41: - case 0x61: - case 0x81: - case 0xa1: - case 0xc1: - case 0xe1: - addr = opram[PC++ - pc]; - addr|= (PC++ & 0xf800) | ((op & 0xe0) << 3); - sprintf(dst, "ajmp $%04X", addr); - break; - - //LJMP code addr - case 0x02: /* 1: 0000 0010 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; - sprintf(dst, "ljmp $%04X", addr); - break; - - //RR A - case 0x03: /* 1: 0000 0011 */ - sprintf(dst, "rr a"); - break; - - //INC A - case 0x04: /* 1: 0000 0100 */ - sprintf(dst, "inc a"); - break; - - //INC data addr - case 0x05: /* 1: 0000 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "inc %s", sym); - break; - - //INC @R0/@R1 /* 1: 0000 011i */ - case 0x06: - case 0x07: - sprintf(dst, "inc @r%d", op&1); - break; - - //INC R0 to R7 /* 1: 0000 1rrr */ - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - sprintf(dst, "inc r%d", op&7); - break; - - //JBC bit addr, code addr - case 0x10: /* 1: 0001 0000 */ - sym = get_bit_address(opram[PC++ - pc]); - rel = opram[PC++ - pc]; - sprintf(dst, "jbc %s,$%04X", sym, PC + rel); - break; - - //ACALL code addr /* 1: aaa1 0001 */ - case 0x11: - case 0x31: - case 0x51: - case 0x71: - case 0x91: - case 0xb1: - case 0xd1: - case 0xf1: - sprintf(dst, "acall $%04X", (PC & 0xf800) | ((op & 0xe0) << 3) | opram[PC - pc]); - PC++; - flags = DASMFLAG_STEP_OVER; - break; - - //LCALL code addr - case 0x12: /* 1: 0001 0010 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; - sprintf(dst, "lcall $%04X", addr); - flags = DASMFLAG_STEP_OVER; - break; - - //RRC A - case 0x13: /* 1: 0001 0011 */ - sprintf(dst, "rrc a"); - break; - - //DEC A - case 0x14: /* 1: 0001 0100 */ - sprintf(dst, "dec a"); - break; - - //DEC data addr - case 0x15: /* 1: 0001 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "dec %s", sym); - break; - - //Unable to test - //DEC @R0/@R1 /* 1: 0001 011i */ - case 0x16: - case 0x17: - sprintf(dst, "dec @r%d", op&1); - break; - - //DEC R0 to R7 /* 1: 0001 1rrr */ - case 0x18: - case 0x19: - case 0x1a: - case 0x1b: - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f: - sprintf(dst, "dec r%d", op&7); - break; - - //JB bit addr, code addr - case 0x20: /* 1: 0010 0000 */ - sym = get_bit_address(opram[PC++ - pc]); - rel = opram[PC++ - pc]; - sprintf(dst, "jb %s,$%04X", sym, (PC + rel)); - break; - - //RET - case 0x22: /* 1: 0010 0010 */ - sprintf(dst, "ret"); - flags = DASMFLAG_STEP_OUT; - break; - - //RL A - case 0x23: /* 1: 0010 0011 */ - sprintf(dst, "rl a"); - break; - - //ADD A, #data - case 0x24: /* 1: 0010 0100 */ - sprintf(dst, "add a,#$%02X", opram[PC++ - pc]); - break; - - //ADD A, data addr - case 0x25: /* 1: 0010 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "add a,%s", sym); - break; - - //Unable to Test - //ADD A, @R0/@R1 /* 1: 0010 011i */ - case 0x26: - case 0x27: - sprintf(dst, "add a,@r%d", op&1); - break; - - //ADD A, R0 to R7 /* 1: 0010 1rrr */ - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f: - sprintf(dst, "add a,r%d", op&7); - break; - - //JNB bit addr, code addr - case 0x30: /* 1: 0011 0000 */ - sym = get_bit_address(opram[PC++ - pc]); - rel = opram[PC++ - pc]; - sprintf(dst, "jnb %s,$%04X", sym, (PC + rel)); - break; - - //RETI - case 0x32: /* 1: 0011 0010 */ - sprintf(dst, "reti"); - flags = DASMFLAG_STEP_OUT; - break; - - //RLC A - case 0x33: /* 1: 0011 0011 */ - sprintf(dst, "rlc a"); - break; - - //ADDC A, #data - case 0x34: /* 1: 0011 0100 */ - sprintf(dst, "addc a,#$%02X", opram[PC++ - pc]); - break; - - //ADDC A, data addr - case 0x35: /* 1: 0011 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "addc a,%s", sym); - break; - - //ADDC A, @R0/@R1 /* 1: 0011 011i */ - case 0x36: - case 0x37: - sprintf(dst, "addc a,@r%d", op&1); - break; - - //ADDC A, R0 to R7 /* 1: 0011 1rrr */ - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - sprintf(dst, "addc a,r%d", op&7); - break; - - //JC code addr - case 0x40: /* 1: 0100 0000 */ - rel = opram[PC++ - pc]; - sprintf(dst, "jc $%04X", PC + rel); - break; - - //ORL data addr, A - case 0x42: /* 1: 0100 0010 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "orl %s,a", sym); - break; - - //ORL data addr, #data - case 0x43: /* 1: 0100 0011 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "orl %s,#$%02X", sym, opram[PC++ - pc]); - break; - - //Unable to Test - //ORL A, #data - case 0x44: /* 1: 0100 0100 */ - sprintf(dst, "orl a,#$%02X", opram[PC++ - pc]); - break; - - //ORL A, data addr - case 0x45: /* 1: 0100 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "orl a,%s", sym); - break; - - //ORL A, @RO/@R1 /* 1: 0100 011i */ - case 0x46: - case 0x47: - sprintf(dst, "orl a,@r%d", op&1); - break; - - //ORL A, RO to R7 /* 1: 0100 1rrr */ - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - sprintf(dst, "orl a,r%d", op&7); - break; - - //JNC code addr - case 0x50: /* 1: 0101 0000 */ - rel = opram[PC++ - pc]; - sprintf(dst, "jnc $%04X", PC + rel); - break; - - //Unable to test - //ANL data addr, A - case 0x52: /* 1: 0101 0010 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "anl %s,a", sym); - break; - - //Unable to test - //ANL data addr, #data - case 0x53: /* 1: 0101 0011 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "anl %s,#$%02X", sym, opram[PC++ - pc]); - break; - - //ANL A, #data - case 0x54: /* 1: 0101 0100 */ - sprintf(dst, "anl a,#$%02X", opram[PC++ - pc]); - break; - - //ANL A, data addr - case 0x55: /* 1: 0101 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "anl a,%s", sym); - break; - - //Unable to test - //ANL A, @RO/@R1 /* 1: 0101 011i */ - case 0x56: - case 0x57: - sprintf(dst, "anl a,@r%d", op&1); - break; - - //ANL A, RO to R7 /* 1: 0101 1rrr */ - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - sprintf(dst, "anl a,r%d", op&7); - break; - - //JZ code addr - case 0x60: /* 1: 0110 0000 */ - rel = opram[PC++ - pc]; - sprintf(dst, "jz $%04X", PC + rel); - break; - - //Unable to test - //XRL data addr, A - case 0x62: /* 1: 0110 0010 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "xrl %s,a", sym); - break; - - //XRL data addr, #data - case 0x63: /* 1: 0110 0011 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "xrl %s,#$%02X", sym, opram[PC++ - pc]); - break; - - //XRL A, #data - case 0x64: /* 1: 0110 0100 */ - sprintf(dst, "xrl a,#$%02X", opram[PC++ - pc]); - break; - - //XRL A, data addr - case 0x65: /* 1: 0110 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "xrl a,%s", sym); - break; - - //Unable to test - //XRL A, @R0/@R1 /* 1: 0110 011i */ - case 0x66: - case 0x67: - sprintf(dst, "xrl a,@r%d", op&1); - break; - - //XRL A, R0 to R7 /* 1: 0110 1rrr */ - case 0x68: - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - sprintf(dst, "xrl a,r%d", op&7); - break; - - //JNZ code addr - case 0x70: /* 1: 0111 0000 */ - rel = opram[PC++ - pc]; - sprintf(dst, "jnz $%04X", PC + rel); - break; - - //Unable to test - //ORL C, bit addr - case 0x72: /* 1: 0111 0010 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "orl c,%s", sym); - break; - - //Unable to test - //JMP @A+DPTR - case 0x73: /* 1: 0111 0011 */ - sprintf(dst, "jmp @a+dptr"); - break; - - //MOV A, #data - case 0x74: /* 1: 0111 0100 */ - sprintf(dst, "mov a,#$%02X", opram[PC++ - pc]); - break; - - //MOV data addr, #data - case 0x75: /* 1: 0111 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "mov %s,#$%02X", sym, opram[PC++ - pc]); - break; - - //Unable to test - //MOV @R0/@R1, #data /* 1: 0111 011i */ - case 0x76: - case 0x77: - sprintf(dst, "mov @r%d,#$%02X", op&1, opram[PC++ - pc]); - break; - - //MOV R0 to R7, #data /* 1: 0111 1rrr */ - case 0x78: - case 0x79: - case 0x7a: - case 0x7b: - case 0x7c: - case 0x7d: - case 0x7e: - case 0x7f: - sprintf(dst, "mov r%d,#$%02X", (op & 7), opram[PC++ - pc]); - break; - - //SJMP code addr - case 0x80: /* 1: 1000 0000 */ - rel = opram[PC++ - pc]; - sprintf(dst, "sjmp $%04X", PC + rel); - break; - - //ANL C, bit addr - case 0x82: /* 1: 1000 0010 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "anl c,%s", sym); - break; - - //MOVC A, @A + PC - case 0x83: /* 1: 1000 0011 */ - sprintf(dst, "movc a,@a+pc"); - break; - - //DIV AB - case 0x84: /* 1: 1000 0100 */ - sprintf(dst, "div ab"); - break; - - //MOV data addr, data addr (Note: 1st address is src, 2nd is dst, but the mov command works as mov dst,src) - case 0x85: /* 1: 1000 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sym2 = get_data_address(opram[PC++ - pc]); - sprintf(dst, "mov %s,%s", sym2, sym); - break; - - //Unable to test - //MOV data addr, @R0/@R1/* 1: 1000 011i */ - case 0x86: - case 0x87: - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "mov %s,@r%d", sym, op&1); - break; - - //MOV data addr,R0 to R7/* 1: 1000 1rrr */ - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "mov %s,r%d", sym, op&7); - break; - - //MOV DPTR, #data16 - case 0x90: /* 1: 1001 0000 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; - sprintf(dst, "mov dptr,#$%04X", addr); - break; - - //MOV bit addr, C - case 0x92: /* 1: 1001 0010 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "mov %s,c", sym); - break; - - //MOVC A, @A + DPTR - case 0x93: /* 1: 1001 0011 */ - sprintf(dst, "movc a,@a+dptr"); - break; - - //SUBB A, #data - case 0x94: /* 1: 1001 0100 */ - sprintf(dst, "subb a,#$%02X", opram[PC++ - pc]); - break; - - //SUBB A, data addr - case 0x95: /* 1: 1001 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "subb a,%s", sym); - break; - - //Unable to test - //SUBB A, @R0/@R1 /* 1: 1001 011i */ - case 0x96: - case 0x97: - sprintf(dst, "subb a,@r%d", op&1); - break; - - //SUBB A, R0 to R7 /* 1: 1001 1rrr */ - case 0x98: - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - case 0x9d: - case 0x9e: - case 0x9f: - sprintf(dst, "subb a,r%d", op&7); - break; - - //Unable to test - //ORL C, /bit addr - case 0xa0: /* 1: 1010 0000 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "orl c,/%s", sym); - break; - - //MOV C, bit addr - case 0xa2: /* 1: 1010 0010 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "mov c,%s", sym); - break; - - //INC DPTR - case 0xa3: /* 1: 1010 0011 */ - sprintf(dst, "inc dptr"); - break; - - //MUL AB - case 0xa4: /* 1: 1010 0100 */ - sprintf(dst, "mul ab"); - break; - - //reserved - case 0xa5: /* 1: 1010 0101 */ - sprintf(dst, "ill/rsv"); - break; - - //Unable to test - //MOV @R0/@R1, data addr /* 1: 1010 011i */ - case 0xa6: - case 0xa7: - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "mov @r%d,%s", op&1, sym); - break; - - //MOV R0 to R7, data addr /* 1: 1010 1rrr */ - case 0xa8: - case 0xa9: - case 0xaa: - case 0xab: - case 0xac: - case 0xad: - case 0xae: - case 0xaf: - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "mov r%d,%s", op&7, sym); - break; - - //ANL C,/bit addr - case 0xb0: /* 1: 1011 0000 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "anl c,/%s", sym); - break; - - //CPL bit addr - case 0xb2: /* 1: 1011 0010 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "cpl %s", sym); - break; - - //Unable to test - //CPL C - case 0xb3: /* 1: 1011 0011 */ - sprintf(dst, "cpl c"); - break; - - //CJNE A, #data, code addr - case 0xb4: /* 1: 1011 0100 */ - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; - sprintf(dst, "cjne a,#$%02X,$%04X", data, PC + rel); - break; - - //CJNE A, data addr, code addr - case 0xb5: /* 1: 1011 0101 */ - sym = get_data_address(opram[PC++ - pc]); - rel = opram[PC++ - pc]; - sprintf(dst, "cjne a,%s,$%04X", sym, PC + rel); - break; - - //Unable to test - //CJNE @R0/@R1, #data, code addr /* 1: 1011 011i */ - case 0xb6: - case 0xb7: - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; - sprintf(dst, "cjne @r%d,#$%02X,$%04X", op&1, data, PC + rel); - break; - - //CJNE R0 to R7, #data, code addr/* 1: 1011 1rrr */ - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - case 0xbd: - case 0xbe: - case 0xbf: - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; - sprintf(dst, "cjne r%d,#$%02X,$%04X", op&7, data, PC + rel); - break; - - //PUSH data addr - case 0xc0: /* 1: 1100 0000 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "push %s", sym); - break; - - //CLR bit addr - case 0xc2: /* 1: 1100 0010 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "clr %s", sym); - break; - - //CLR C - case 0xc3: /* 1: 1100 0011 */ - sprintf(dst, "clr c"); - break; - - //SWAP A - case 0xc4: /* 1: 1100 0100 */ - sprintf(dst, "swap a"); - break; - - //XCH A, data addr - case 0xc5: /* 1: 1100 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "xch a,%s", sym); - break; - - //XCH A, @RO/@R1 /* 1: 1100 011i */ - case 0xc6: - case 0xc7: - sprintf(dst, "xch a,@r%d", op&1); - break; - - //XCH A, RO to R7 /* 1: 1100 1rrr */ - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - sprintf(dst, "xch a,r%d", op&7); - break; - - //POP data addr - case 0xd0: /* 1: 1101 0000 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "pop %s", sym); - break; - - //SETB bit addr - case 0xd2: /* 1: 1101 0010 */ - sym = get_bit_address(opram[PC++ - pc]); - sprintf(dst, "setb %s", sym); - break; - - //SETB C - case 0xd3: /* 1: 1101 0011 */ - sprintf(dst, "setb c"); - break; - - //Unable to test - //DA A - case 0xd4: /* 1: 1101 0100 */ - sprintf(dst, "da a"); - break; - - //DJNZ data addr, code addr - case 0xd5: /* 1: 1101 0101 */ - sym = get_data_address(opram[PC++ - pc]); - rel = opram[PC++ - pc]; - sprintf(dst, "djnz %s,$%04X", sym, PC + rel); - flags = DASMFLAG_STEP_OVER; - break; - - //XCHD A, @R0/@R1 /* 1: 1101 011i */ - case 0xd6: - case 0xd7: - sprintf(dst, "xchd a,@r%d", op&1); - break; - - //DJNZ R0 to R7,code addr /* 1: 1101 1rrr */ - case 0xd8: - case 0xd9: - case 0xda: - case 0xdb: - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf: - rel = opram[PC++ - pc]; - sprintf(dst, "djnz r%d,$%04X", op&7, (PC + rel)); - flags = DASMFLAG_STEP_OVER; - break; - - //MOVX A,@DPTR - case 0xe0: /* 1: 1110 0000 */ - sprintf(dst, "movx a,@dptr"); - break; - - //Unable to test - //MOVX A, @R0/@R1 /* 1: 1110 001i */ - case 0xe2: - case 0xe3: - sprintf(dst, "movx a,@r%d", op&1); - break; - - //CLR A - case 0xe4: /* 1: 1110 0100 */ - sprintf(dst, "clr a"); - break; - - //MOV A, data addr - case 0xe5: /* 1: 1110 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "mov a,%s", sym); - break; - - //Unable to test - //MOV A,@RO/@R1 /* 1: 1110 011i */ - case 0xe6: - case 0xe7: - sprintf(dst, "mov a,@r%d", op&1); - break; - - //MOV A,R0 to R7 /* 1: 1110 1rrr */ - case 0xe8: - case 0xe9: - case 0xea: - case 0xeb: - case 0xec: - case 0xed: - case 0xee: - case 0xef: - sprintf(dst, "mov a,r%d", op&7); - break; - - //MOVX @DPTR,A - case 0xf0: /* 1: 1111 0000 */ - sprintf(dst, "movx @dptr,a"); - break; - - //Unable to test - //MOVX @R0/@R1,A /* 1: 1111 001i */ - case 0xf2: - case 0xf3: - sprintf(dst, "movx @r%d,a", op&1); - break; - - //CPL A - case 0xf4: /* 1: 1111 0100 */ - sprintf(dst, "cpl a"); - break; - - //MOV data addr, A - case 0xf5: /* 1: 1111 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sprintf(dst, "mov %s,a", sym); - break; - - //MOV @R0/@R1, A /* 1: 1111 011i */ - case 0xf6: - case 0xf7: - sprintf(dst, "mov @r%d,a", op&1); - break; - - //MOV R0 to R7, A /* 1: 1111 1rrr */ - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - case 0xff: - sprintf(dst, "mov r%d,a", op&7); - break; - - default: - sprintf(dst, "illegal"); - } - return (PC - pc) | flags | DASMFLAG_SUPPORTED; -} diff --git a/src/emu/cpu/ds5002fp/ds5002fpops.c b/src/emu/cpu/ds5002fp/ds5002fpops.c deleted file mode 100644 index 2b061911aa8..00000000000 --- a/src/emu/cpu/ds5002fp/ds5002fpops.c +++ /dev/null @@ -1,960 +0,0 @@ -/******************************************************************************************* - NOTE: All registers are accessed directly, instead of using the SFR_R() function for speed - Direct register access is availabe from the R_(register name) macros.. ex: R_ACC for the ACC - with the exception of the PC -********************************************************************************************/ - -//ACALL code addr /* 1: aaa1 0001 */ -INLINE void acall(void) -{ - UINT8 op = ROP(PC-1); //Grab the opcode for ACALL - UINT8 addr = ROP_ARG(PC++); //Grab code address byte - PUSH_PC //Save PC to the stack - //Thanks Gerrit for help with this! :) - PC = (PC & 0xf800) | ((op & 0xe0) << 3) | addr; -} - -//ADD A, #data /* 1: 0010 0100 */ -INLINE void add_a_byte(void) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - UINT8 result = R_ACC + data; //Add data to accumulator - DO_ADD_FLAGS(R_ACC,data,0) //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//ADD A, data addr /* 1: 0010 0101 */ -INLINE void add_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - UINT8 result = R_ACC + data; //Add data to accumulator - DO_ADD_FLAGS(R_ACC,data,0); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//ADD A, @R0/@R1 /* 1: 0010 011i */ -INLINE void add_a_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); //Grab data from memory pointed to by R0 or R1 - UINT8 result = R_ACC + data; //Add data to accumulator - DO_ADD_FLAGS(R_ACC,data,0); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//ADD A, R0 to R7 /* 1: 0010 1rrr */ -INLINE void add_a_r(int r) -{ - UINT8 data = R_R(r); //Grab data from R0 - R7 - UINT8 result = R_ACC + data; //Add data to accumulator - DO_ADD_FLAGS(R_ACC,data,0); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//ADDC A, #data /* 1: 0011 0100 */ -INLINE void addc_a_byte(void) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - UINT8 result = R_ACC + data + GET_CY; //Add data + carry flag to accumulator - DO_ADD_FLAGS(R_ACC,data,GET_CY); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//ADDC A, data addr /* 1: 0011 0101 */ -INLINE void addc_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - UINT8 result = R_ACC + data + GET_CY; //Add data + carry flag to accumulator - DO_ADD_FLAGS(R_ACC,data,GET_CY); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//ADDC A, @R0/@R1 /* 1: 0011 011i */ -INLINE void addc_a_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); //Grab data from memory pointed to by R0 or R1 - UINT8 result = R_ACC + data + GET_CY; //Add data + carry flag to accumulator - DO_ADD_FLAGS(R_ACC,data,GET_CY); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//ADDC A, R0 to R7 /* 1: 0011 1rrr */ -INLINE void addc_a_r(int r) -{ - UINT8 data = R_R(r); //Grab data from R0 - R7 - UINT8 result = R_ACC + data + GET_CY; //Add data + carry flag to accumulator - DO_ADD_FLAGS(R_ACC,data,GET_CY); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//AJMP code addr /* 1: aaa0 0001 */ -INLINE void ajmp(void) -{ - UINT8 op = ROP(PC-1); //Grab the opcode for AJMP - UINT8 addr = ROP_ARG(PC++); //Grab code address byte - //Thanks Gerrit for help with this! :) - PC = (PC & 0xf800) | ((op & 0xe0) << 3) | addr; -} - -//ANL data addr, A /* 1: 0101 0010 */ -INLINE void anl_mem_a(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - IRAM_W(addr,data & R_ACC); //Set data address value to it's value Logical AND with ACC -} - -//ANL data addr, #data /* 1: 0101 0011 */ -INLINE void anl_mem_byte(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = ROP_ARG(PC++); //Grab data - UINT8 srcdata = IRAM_R(addr); //Grab data from data address - IRAM_W(addr,srcdata & data); //Set data address value to it's value Logical AND with Data -} - -//ANL A, #data /* 1: 0101 0100 */ -INLINE void anl_a_byte(void) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - SFR_W(ACC,R_ACC & data); //Set ACC to value of ACC Logical AND with Data -} - -//ANL A, data addr /* 1: 0101 0101 */ -INLINE void anl_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - SFR_W(ACC,R_ACC & data); //Set ACC to value of ACC Logical AND with Data -} - -//ANL A, @RO/@R1 /* 1: 0101 011i */ -INLINE void anl_a_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); //Grab data from address R0 or R1 points to - SFR_W(ACC,R_ACC & data); //Set ACC to value of ACC Logical AND with Data -} - -//ANL A, RO to R7 /* 1: 0101 1rrr */ -INLINE void anl_a_r(int r) -{ - UINT8 data = R_R(r); //Grab data from R0 - R7 - SFR_W(ACC,R_ACC & data); //Set ACC to value of ACC Logical AND with Data -} - -//ANL C, bit addr /* 1: 1000 0010 */ -INLINE void anl_c_bitaddr(void) -{ - int cy = GET_CY; - UINT8 addr = ROP_ARG(PC++); //Grab bit address - UINT8 bit = BIT_R(addr); //Grab bit data from bit address - SET_CY( (cy & bit) ); //Set Carry flag to Carry Flag Value Logical AND with Bit -} - -//ANL C,/bit addr /* 1: 1011 0000 */ -INLINE void anl_c_nbitaddr(void) -{ - int cy = GET_CY; - UINT8 addr = ROP_ARG(PC++); //Grab bit address - UINT8 bit = BIT_R(addr); //Grab bit data from bit address - bit = ((~bit)&1); //Complement bit - SET_CY( (cy & bit) ); //Set Carry flag to Carry Flag Value Logical AND with Complemented Bit -} - -//CJNE A, #data, code addr /* 1: 1011 0100 */ -INLINE void cjne_a_byte(void) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - - if(R_ACC != data) //Jump if values are not equal - PC = PC + rel_addr; - - //Set carry flag to 1 if 1st compare value is < 2nd compare value - SET_CY( (R_ACC < data) ); -} - -//CJNE A, data addr, code addr /* 1: 1011 0101 */ -INLINE void cjne_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - UINT8 data = IRAM_R(addr); //Pull value from data address - - if(R_ACC != data) //Jump if values are not equal - PC = PC + rel_addr; - - //Set carry flag to 1 if 1st compare value is < 2nd compare value - SET_CY( (R_ACC < data) ); -} - -//CJNE @R0/@R1, #data, code addr /* 1: 1011 011i */ -INLINE void cjne_ir_byte(int r) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - UINT8 srcdata = IRAM_IR(R_R(r)); //Grab value pointed to by R0 or R1 - - if(srcdata != data) //Jump if values are not equal - PC = PC + rel_addr; - - //Set carry flag to 1 if 1st compare value is < 2nd compare value - SET_CY( (srcdata < data) ); -} - -//CJNE R0 to R7, #data, code addr /* 1: 1011 1rrr */ -INLINE void cjne_r_byte(int r) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - UINT8 srcdata = R_R(r); //Grab value of R0 - R7 - - if(srcdata != data) //Jump if values are not equal - PC = PC + rel_addr; - - //Set carry flag to 1 if 1st compare value is < 2nd compare value - SET_CY( (srcdata < data) ); -} - -//CLR bit addr /* 1: 1100 0010 */ -INLINE void clr_bitaddr(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab bit address - BIT_W(addr,0); //Clear bit at specified bit address -} - -//CLR C /* 1: 1100 0011 */ -INLINE void clr_c(void) -{ - SET_CY(0); //Clear Carry Flag -} - -//CLR A /* 1: 1110 0100 */ -INLINE void clr_a(void) -{ - SFR_W(ACC,0); //Clear Accumulator -} - -//CPL bit addr /* 1: 1011 0010 */ -INLINE void cpl_bitaddr(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab bit address - UINT8 data = (~BIT_R(addr))&1; - BIT_W(addr,data); //Complement bit at specified bit address -} - -//CPL C /* 1: 1011 0011 */ -INLINE void cpl_c(void) -{ - UINT8 bit = (~GET_CY)&1; //Complement Carry Flag - SET_CY(bit); -} - -//CPL A /* 1: 1111 0100 */ -INLINE void cpl_a(void) -{ - UINT8 data = ((~R_ACC)&0xff); - SFR_W(ACC,data); //Complement Accumulator -} - -//DA A /* 1: 1101 0100 */ -INLINE void da_a(void) -{ -/*From several sources, since none said the same thing: - The decimal adjust instruction is associated with the use of the ADD and ADDC instructions. - The eight-bit value in the accumulator is adjusted to form two BCD digits of four bits each. - If the accumulator contents bits 0-3 are greater than 9, OR the AC flag is set, then six is added to - produce a proper BCD digit. - If the carry is set, OR the four high bits 4-7 exceed nine, six is added to the value of these bits. - The carry flag will be set if the result is > 0x99, but not cleared otherwise */ - - UINT16 new_acc = R_ACC & 0xff; - if(GET_AC || (new_acc & 0x0f) > 0x09) - new_acc += 0x06; - if(GET_CY || ((new_acc & 0xf0) > 0x90) || (new_acc & ~0xff)) - new_acc += 0x60; - SFR_W(ACC,new_acc&0xff); - if(new_acc & ~0xff) - SET_CY(1); -} - -//DEC A /* 1: 0001 0100 */ -INLINE void dec_a(void) -{ - SFR_W(ACC,R_ACC-1); -} - -//DEC data addr /* 1: 0001 0101 */ -INLINE void dec_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); - IRAM_W(addr,data-1); -} - -//DEC @R0/@R1 /* 1: 0001 011i */ -INLINE void dec_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); - IRAM_W(R_R(r),data-1); -} - -//DEC R0 to R7 /* 1: 0001 1rrr */ -INLINE void dec_r(int r) -{ - R_R(r) = R_R(r) - 1; -} - -//DIV AB /* 1: 1000 0100 */ -INLINE void div_ab(void) -{ - if( R_B == 0 ) { - //Overflow flag is set! - SET_OV(1); - //Really the values are undefined according to the manual, but we'll just leave them as is.. - //SFR_W(ACC,0xff); - //SFR_W(B,0xff); - } - else { - int a = (int)R_ACC/R_B; - int b = (int)R_ACC%R_B; - //A gets quotient byte, B gets remainder byte - SFR_W(ACC,a); - SFR_W(B, b); - //Overflow flag is cleared - SET_OV(0); - } - //Carry Flag is always cleared - SET_CY(0); -} - -//DJNZ data addr, code addr /* 1: 1101 0101 */ -INLINE void djnz_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - IRAM_W(addr,IRAM_R(addr) - 1); //Decrement value contained at data address - if(IRAM_R(addr) != 0) //Branch if contents of data address is not 0 - PC = PC + rel_addr; -} - -//DJNZ R0 to R7,code addr /* 1: 1101 1rrr */ -INLINE void djnz_r(int r) -{ - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - R_R(r) = R_R(r) - 1; //Decrement value - if(R_R(r) != 0) //Branch if contents of R0 - R7 is not 0 - PC = PC + rel_addr; -} - -//INC A /* 1: 0000 0100 */ -INLINE void inc_a(void) -{ - SFR_W(ACC,R_ACC+1); -} - -//INC data addr /* 1: 0000 0101 */ -INLINE void inc_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); - IRAM_W(addr,data+1); -} - -//INC @R0/@R1 /* 1: 0000 011i */ -INLINE void inc_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); - IRAM_W(R_R(r),data+1); -} - -//INC R0 to R7 /* 1: 0000 1rrr */ -INLINE void inc_r(int r) -{ - UINT8 data = R_R(r); - R_R(r) = data + 1; -} - -//INC DPTR /* 1: 1010 0011 */ -INLINE void inc_dptr(void) -{ - UINT16 dptr = (R_DPTR)+1; - DPTR_W(dptr); -} - -//JB bit addr, code addr /* 1: 0010 0000 */ -INLINE void jb(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab bit address - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - if(BIT_R(addr)) //If bit set at specified bit address, jump - PC = PC + rel_addr; -} - -//JBC bit addr, code addr /* 1: 0001 0000 */ -INLINE void jbc(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab bit address - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - if(BIT_R(addr)) { //If bit set at specified bit address, jump - PC = PC + rel_addr; - BIT_W(addr,0); //Clear Bit also - } -} - -//JC code addr /* 1: 0100 0000 */ -INLINE void jc(void) -{ - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - if(GET_CY) //Jump if Carry Flag Set - PC = PC + rel_addr; -} - -//JMP @A+DPTR /* 1: 0111 0011 */ -INLINE void jmp_iadptr(void) -{ - PC = R_ACC+R_DPTR; -} - -//JNB bit addr, code addr /* 1: 0011 0000 */ -INLINE void jnb(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab bit address - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - if(!BIT_R(addr)) //If bit NOT set at specified bit address, jump - PC = PC + rel_addr; -} - -//JNC code addr /* 1: 0101 0000 */ -INLINE void jnc(void) -{ - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - if(!GET_CY) //Jump if Carry Flag not set - PC = PC + rel_addr; -} - -//JNZ code addr /* 1: 0111 0000 */ -INLINE void jnz(void) -{ - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - if(R_ACC != 0) //Branch if ACC is not 0 - PC = PC+rel_addr; -} - -//JZ code addr /* 1: 0110 0000 */ -INLINE void jz(void) -{ - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - if(R_ACC == 0) //Branch if ACC is 0 - PC = PC+rel_addr; -} - -//LCALL code addr /* 1: 0001 0010 */ -INLINE void lcall(void) -{ - UINT8 addr_hi, addr_lo; - addr_hi = ROP_ARG(PC++); - addr_lo = ROP_ARG(PC++); - PUSH_PC - PC = (UINT16)((addr_hi<<8) | addr_lo); -} - -//LJMP code addr /* 1: 0000 0010 */ -INLINE void ljmp(void) -{ - UINT8 addr_hi, addr_lo; - addr_hi = ROP_ARG(PC++); - addr_lo = ROP_ARG(PC++); - PC = (UINT16)((addr_hi<<8) | addr_lo); -} - -//MOV A, #data /* 1: 0111 0100 */ -INLINE void mov_a_byte(void) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - SFR_W(ACC,data); //Store data to ACC -} - -//MOV A, data addr /* 1: 1110 0101 */ -INLINE void mov_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - SFR_W(ACC,IRAM_R(addr)); //Store contents of data address to ACC -} - -//MOV A,@RO/@R1 /* 1: 1110 011i */ -INLINE void mov_a_ir(int r) -{ - SFR_W(ACC,IRAM_IR(R_R(r))); //Store contents of address pointed by R0 or R1 to ACC -} - -//MOV A,R0 to R7 /* 1: 1110 1rrr */ -INLINE void mov_a_r(int r) -{ - SFR_W(ACC,R_R(r)); //Store contents of R0 - R7 to ACC -} - -//MOV data addr, #data /* 1: 0111 0101 */ -INLINE void mov_mem_byte(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = ROP_ARG(PC++); //Grab data - IRAM_W(addr,data); //Store data to data address location -} - -//MOV data addr, data addr /* 1: 1000 0101 */ -INLINE void mov_mem_mem(void) -{ - //1st address is src, 2nd is dst, but the mov command works as mov dst,src) - UINT8 src,dst; - src = ROP_ARG(PC++); //Grab source data address - dst = ROP_ARG(PC++); //Grab destination data address - IRAM_W(dst,IRAM_R(src)); //Read source address contents and store to destination address -} - -//MOV @R0/@R1, #data /* 1: 0111 011i */ -INLINE void mov_ir_byte(int r) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - IRAM_IW(R_R(r),data); //Store data to address pointed by R0 or R1 -} - -//MOV R0 to R7, #data /* 1: 0111 1rrr */ -INLINE void mov_r_byte(int r) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - R_R(r) = data; //Store to R0 - R7 -} - -//MOV data addr, @R0/@R1 /* 1: 1000 011i */ -INLINE void mov_mem_ir(int r) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - IRAM_W(addr,IRAM_IR(R_R(r))); //Store contents pointed to by R0 or R1 to data address -} - -//MOV data addr,R0 to R7 /* 1: 1000 1rrr */ -INLINE void mov_mem_r(int r) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - IRAM_W(addr,R_R(r)); //Store contents of R0 - R7 to data address -} - -//MOV DPTR, #data16 /* 1: 1001 0000 */ -INLINE void mov_dptr_byte(void) -{ - UINT8 data_hi, data_lo; - data_hi = ROP_ARG(PC++); //Grab hi byte - data_lo = ROP_ARG(PC++); //Grab lo byte - DPTR_W((UINT16)((data_hi<<8)|data_lo)); //Store to DPTR -} - -//MOV bit addr, C /* 1: 1001 0010 */ -INLINE void mov_bitaddr_c(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab bit address - BIT_W(addr,GET_CY); //Store Carry Flag to Bit Address -} - -//MOV @R0/@R1, data addr /* 1: 1010 011i */ -INLINE void mov_ir_mem(int r) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - IRAM_IW(R_R(r),IRAM_R(addr)); //Store data from data address to address pointed to by R0 or R1 -} - -//MOV R0 to R7, data addr /* 1: 1010 1rrr */ -INLINE void mov_r_mem(int r) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - R_R(r) = IRAM_R(addr); //Store to R0 - R7 -} - -//MOV data addr, A /* 1: 1111 0101 */ -INLINE void mov_mem_a(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - IRAM_W(addr,R_ACC); //Store A to data address -} - -//MOV @R0/@R1, A /* 1: 1111 011i */ -INLINE void mov_ir_a(int r) -{ - IRAM_IW(R_R(r),R_ACC); //Store A to location pointed to by R0 or R1 -} - -//MOV R0 to R7, A /* 1: 1111 1rrr */ -INLINE void mov_r_a(int r) -{ - R_R(r) = R_ACC; //Store A to R0-R7 -} - -//MOVC A, @A + PC /* 1: 1000 0011 */ -INLINE void movc_a_iapc(void) -{ - UINT8 data; - data = CODEMEM_R(R_ACC+PC); //Move a byte from CODE(Program) Memory and store to ACC - SFR_W(ACC,data); -} - -//MOV C, bit addr /* 1: 1010 0010 */ -INLINE void mov_c_bitaddr(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab bit address - SET_CY( (BIT_R(addr)) ); //Store Bit from Bit Address to Carry Flag -} - -//MOVC A, @A + DPTR /* 1: 1001 0011 */ -INLINE void movc_a_iadptr(void) -{ - UINT8 data; - data = CODEMEM_R(R_ACC+R_DPTR); //Move a byte from CODE(Program) Memory and store to ACC - SFR_W(ACC,data); -} - -//MOVX A,@DPTR /* 1: 1110 0000 */ -//(Move External Ram 16 bit address to A) -INLINE void movx_a_idptr(void) -{ -// UINT8 byte = DATAMEM_R(R_DPTR); //Grab 1 byte from External DATA memory pointed to by dptr - UINT32 addr = ERAM_ADDR(R_DPTR,0xFFFF); - UINT8 byte = DATAMEM_R(addr); //Grab 1 byte from External DATA memory pointed to by dptr - SFR_W(ACC,byte); //Store to ACC -} - -//MOVX A, @R0/@R1 /* 1: 1110 001i */ -//(Move External Ram 8 bit address to A) -INLINE void movx_a_ir(int r) -{ - UINT32 addr = ERAM_ADDR(R_R(r),0xFF); //Grab address by reading location pointed to by R0 or R1 - UINT8 byte = DATAMEM_R(addr); //Grab 1 byte from External DATA memory pointed to by address - SFR_W(ACC,byte); //Store to ACC -} - -//MOVX @DPTR,A /* 1: 1111 0000 */ -//(Move A to External Ram 16 bit address) -INLINE void movx_idptr_a(void) -{ -// DATAMEM_W(R_DPTR, R_ACC); //Store ACC to External DATA memory address pointed to by DPTR - UINT32 addr = ERAM_ADDR(R_DPTR,0xFFFF); - DATAMEM_W(addr, R_ACC); //Store ACC to External DATA memory address pointed to by DPTR -} - -//MOVX @R0/@R1,A /* 1: 1111 001i */ -//(Move A to External Ram 8 bit address) -INLINE void movx_ir_a(int r) -{ - UINT32 addr = ERAM_ADDR(R_R(r),0xFF); //Grab address by reading location pointed to by R0 or R1 - DATAMEM_W(addr, R_ACC); //Store ACC to External DATA memory address -} - -//MUL AB /* 1: 1010 0100 */ -INLINE void mul_ab(void) -{ - UINT16 result = R_ACC * R_B; - //A gets lo bits, B gets hi bits of result - SFR_W(B,(UINT8)((result & 0xFF00) >> 8)); - SFR_W(ACC,(UINT8)(result & 0x00FF)); - //Set flags - SET_OV( ((result & 0x100) >> 8) ); //Set/Clear Overflow Flag if result > 255 - SET_CY(0); //Carry Flag always cleared -} - -//NOP /* 1: 0000 0000 */ -INLINE void nop(void) -{ -} - -//ORL data addr, A /* 1: 0100 0010 */ -INLINE void orl_mem_a(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - IRAM_W(addr,data | R_ACC); //Set data address value to it's value Logical OR with ACC -} - -//ORL data addr, #data /* 1: 0100 0011 */ -INLINE void orl_mem_byte(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = ROP_ARG(PC++); //Grab data - UINT8 srcdata = IRAM_R(addr); //Grab data from data address - IRAM_W(addr,srcdata | data); //Set data address value to it's value Logical OR with Data -} - -//ORL A, #data /* 1: 0100 0100 */ -INLINE void orl_a_byte(void) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - SFR_W(ACC,R_ACC | data); //Set ACC to value of ACC Logical OR with Data -} - -//ORL A, data addr /* 1: 0100 0101 */ -INLINE void orl_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - SFR_W(ACC,R_ACC | data); //Set ACC to value of ACC Logical OR with Data -} - -//ORL A, @RO/@R1 /* 1: 0100 011i */ -INLINE void orl_a_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); //Grab data from address R0 or R1 points to - SFR_W(ACC,R_ACC | data); //Set ACC to value of ACC Logical OR with Data -} - -//ORL A, RO to R7 /* 1: 0100 1rrr */ -INLINE void orl_a_r(int r) -{ - UINT8 data = R_R(r); //Grab data from R0 - R7 - SFR_W(ACC,R_ACC | data); //Set ACC to value of ACC Logical OR with Data -} - -//ORL C, bit addr /* 1: 0111 0010 */ -INLINE void orl_c_bitaddr(void) -{ - int cy = GET_CY; - UINT8 addr = ROP_ARG(PC++); //Grab bit address - UINT8 bit = BIT_R(addr); //Grab bit data from bit address - SET_CY( (cy | bit) ); //Set Carry flag to Carry Flag Value Logical OR with Bit -} - -//ORL C, /bit addr /* 1: 1010 0000 */ -INLINE void orl_c_nbitaddr(void) -{ - int cy = GET_CY; - UINT8 addr = ROP_ARG(PC++); //Grab bit address - UINT8 bit = BIT_R(addr); //Grab bit data from bit address - bit = ((~bit)&1); //Complement bit - SET_CY( (cy | bit) ); //Set Carry flag to Carry Flag Value Logical OR with Complemented Bit -} - -//POP data addr /* 1: 1101 0000 */ -INLINE void pop(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - IRAM_W(addr, IRAM_IR(R_SP)); //Store to contents of data addr, data pointed to by Stack - IRAM_IR needed to access upper 128 bytes of stack - //IRAM_IW(addr, IRAM_IR(R_SP)); //Store to contents of data addr, data pointed to by Stack - doesn't work, sfr's are not restored this way and it's not an indirect access anyway - SFR_W(SP,R_SP-1); //Decrement SP -} - -//PUSH data addr /* 1: 1100 0000 */ -INLINE void push(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 tmpSP = R_SP; //Grab and Increment Stack Pointer - tmpSP++; // "" - SFR_W(SP,tmpSP); // "" - if (tmpSP == R_SP) //Ensure it was able to write to new stack location - IRAM_IW(tmpSP, IRAM_R(addr)); //Store to stack contents of data address - IRAM_IW needed to store to upper 128 bytes of stack, however, can't use IRAM_IR because that won't store the sfrs and it's not an indirect access anyway -} - -//RET /* 1: 0010 0010 */ -INLINE void ret(void) -{ - POP_PC -} - -//RETI /* 1: 0011 0010 */ -INLINE void reti(void) -{ - POP_PC - CLEAR_CURRENT_IRQ -} - -//RL A /* 1: 0010 0011 */ -INLINE void rl_a(void) -{ - //Left Shift A, Bit 7 carries to Bit 0 - int carry = ((R_ACC & 0x80) >> 7); - int data = (R_ACC<<1) & 0xfe; - SFR_W(ACC, data | carry); -} - -//RLC A /* 1: 0011 0011 */ -INLINE void rlc_a(void) -{ - //Left Shift A, Bit 7 goes to Carry Flag, Original Carry Flag goes to Bit 0 of ACC - int carry = ((R_ACC & 0x80) >> 7); - int data = ((R_ACC<<1) & 0xfe) | GET_CY; - SFR_W(ACC, data); - SET_CY(carry); -} - -//RR A /* 1: 0000 0011 */ -INLINE void rr_a(void) -{ - //Right Shift A, Bit 0 carries to Bit 7 - int carry = ((R_ACC & 1) << 7); - int data = (R_ACC>>1) & 0x7f; - SFR_W(ACC, data | carry); -} - -//RRC A /* 1: 0001 0011 */ -INLINE void rrc_a(void) -{ - //Right Shift A, Bit 0 goes to Carry Flag, Bit 7 of ACC gets set to original Carry Flag - int carry = (R_ACC & 1); - int data = ((R_ACC>>1) & 0x7f) | (GET_CY<<7); - SFR_W(ACC, data); - SET_CY(carry); -} - -//SETB C /* 1: 1101 0011 */ -INLINE void setb_c(void) -{ - SET_CY(1); //Set Carry Flag -} - -//SETB bit addr /* 1: 1101 0010 */ -INLINE void setb_bitaddr(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab bit address - BIT_W(addr,1); //Set Bit at Bit Address -} - -//SJMP code addr /* 1: 1000 0000 */ -INLINE void sjmp(void) -{ - INT8 rel_addr = ROP_ARG(PC++); //Grab relative code address - PC = PC + rel_addr; //Update PC -} - -//SUBB A, #data /* 1: 1001 0100 */ -INLINE void subb_a_byte(void) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - UINT8 result = R_ACC - data - GET_CY; //Subtract data & carry flag from accumulator - DO_SUB_FLAGS(R_ACC,data,GET_CY); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC - -} - -//SUBB A, data addr /* 1: 1001 0101 */ -INLINE void subb_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - UINT8 result = R_ACC - data - GET_CY; //Subtract data & carry flag from accumulator - DO_SUB_FLAGS(R_ACC,data,GET_CY); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//SUBB A, @R0/@R1 /* 1: 1001 011i */ -INLINE void subb_a_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); //Grab data from memory pointed to by R0 or R1 - UINT8 result = R_ACC - data - GET_CY; //Subtract data & carry flag from accumulator - DO_SUB_FLAGS(R_ACC,data,GET_CY); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//SUBB A, R0 to R7 /* 1: 1001 1rrr */ -INLINE void subb_a_r(int r) -{ - UINT8 data = R_R(r); //Grab data from R0 - R7 - UINT8 result = R_ACC - data - GET_CY; //Subtract data & carry flag from accumulator - DO_SUB_FLAGS(R_ACC,data,GET_CY); //Set Flags - SFR_W(ACC,result); //Store 8 bit result of addtion in ACC -} - -//SWAP A /* 1: 1100 0100 */ -INLINE void swap_a(void) -{ - UINT8 a_nib_lo, a_nib_hi; - a_nib_hi = (R_ACC & 0x0f) << 4; //Grab lo byte of ACC and move to hi - a_nib_lo = (R_ACC & 0xf0) >> 4; //Grab hi byte of ACC and move to lo - SFR_W(ACC, a_nib_hi | a_nib_lo); -} - -//XCH A, data addr /* 1: 1100 0101 */ -INLINE void xch_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data - UINT8 oldACC = R_ACC; //Hold value of ACC - SFR_W(ACC,data); //Sets ACC to data - IRAM_W(addr,oldACC); //Sets data address to old value of ACC -} - -//XCH A, @RO/@R1 /* 1: 1100 011i */ -INLINE void xch_a_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); //Grab data pointed to by R0 or R1 - UINT8 oldACC = R_ACC; //Hold value of ACC - SFR_W(ACC,data); //Sets ACC to data - IRAM_W(R_R(r),oldACC); //Sets data address to old value of ACC -} - -//XCH A, RO to R7 /* 1: 1100 1rrr */ -INLINE void xch_a_r(int r) -{ - UINT8 data = R_R(r); //Grab data from R0-R7 - UINT8 oldACC = R_ACC; //Hold value of ACC - SFR_W(ACC,data); //Sets ACC to data - R_R(r) = oldACC; //Sets data address to old value of ACC -} - -//XCHD A, @R0/@R1 /* 1: 1101 011i */ -INLINE void xchd_a_ir(int r) -{ - UINT8 acc, ir_data; - ir_data = IRAM_IR(R_R(r)); //Grab data pointed to by R0 or R1 - acc = R_ACC; //Grab ACC value - SFR_W(ACC, (acc & 0xf0) | (ir_data & 0x0f) ); //Set ACC to lower nibble of data pointed to by R0 or R1 - IRAM_W(R_R(r), (ir_data & 0xf0) | (acc & 0x0f) ); //Set data pointed to by R0 or R1 to lower nibble of ACC -} - -//XRL data addr, A /* 1: 0110 0010 */ -INLINE void xrl_mem_a(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - IRAM_W(addr,data ^ R_ACC); //Set data address value to it's value Logical XOR with ACC -} - -//XRL data addr, #data /* 1: 0110 0011 */ -INLINE void xrl_mem_byte(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = ROP_ARG(PC++); //Grab data - UINT8 srcdata = IRAM_R(addr); //Grab data from data address - IRAM_W(addr,srcdata ^ data); //Set data address value to it's value Logical XOR with Data -} - -//XRL A, #data /* 1: 0110 0100 */ -INLINE void xrl_a_byte(void) -{ - UINT8 data = ROP_ARG(PC++); //Grab data - SFR_W(ACC,R_ACC ^ data); //Set ACC to value of ACC Logical XOR with Data -} - -//XRL A, data addr /* 1: 0110 0101 */ -INLINE void xrl_a_mem(void) -{ - UINT8 addr = ROP_ARG(PC++); //Grab data address - UINT8 data = IRAM_R(addr); //Grab data from data address - SFR_W(ACC,R_ACC ^ data); //Set ACC to value of ACC Logical XOR with Data -} - -//XRL A, @R0/@R1 /* 1: 0110 011i */ -INLINE void xrl_a_ir(int r) -{ - UINT8 data = IRAM_IR(R_R(r)); //Grab data from address R0 or R1 points to - SFR_W(ACC,R_ACC ^ data); //Set ACC to value of ACC Logical XOR with Data -} - -//XRL A, R0 to R7 /* 1: 0110 1rrr */ -INLINE void xrl_a_r(int r) -{ - UINT8 data = R_R(r); //Grab data from R0 - R7 - SFR_W(ACC,R_ACC ^ data); //Set ACC to value of ACC Logical XOR with Data -} - -//illegal opcodes -INLINE void illegal(void) -{ - LOG(("ds5002fp #%d: illegal opcode at 0x%03x: %02x\n", cpu_getactivecpu(), PC, ROP(PC))); -} diff --git a/src/emu/cpu/mcs51/mcs51.c b/src/emu/cpu/mcs51/mcs51.c index 7dbce15814b..e203ad74fdd 100644 --- a/src/emu/cpu/mcs51/mcs51.c +++ b/src/emu/cpu/mcs51/mcs51.c @@ -30,11 +30,51 @@ * *****************************************************************************/ +/***************************************************************************** + * DS5002FP emulator by Manuel Abadia + * + * October 2008, couriersud: Merged back in mcs51 + * + * What has been added? + * - Extra SFRs + * - Bytewide Bus Support + * - Memory Partition and Memory Range + * - Bootstrap Configuration + * - Power Fail Interrupt + * - Timed Access + * - Stop Mode + * - Idle Mode + * + * What is not implemented? + * - Peripherals and Reprogrammable Peripheral Controller + * - CRC-16 + * - Watchdog timer + * + * The main features of the DS5002FP are: + * - 100% code-compatible with 8051 + * - Directly addresses 64kB program/64kB data memory + * - Nonvolatile memory control circuitry + * - 10-year data retention in the absence of power + * - In-system reprogramming via serial port + * - Dedicated memory bus, preserving four 8-bit ports for general purpose I/O + * - Power-fail reset + * - Early warning power-fail interrupt + * - Watchdog timer + * - Accesses up to 128kB on the bytewide bus + * - Decodes memory for 32kB x 8 or 128kB x 8 SRAMs + * - Four additional decoded peripheral-chip enables + * - CRC hardware for checking memory validity + * - Optionally emulates an 8042-style slave interface + * - Memory encryption using an 80-bit encryption key + * - Automatic random generation of encryption keys + * - Self-destruct input for tamper protection + * - Optional top-coating prevents microprobe + * + *****************************************************************************/ + /****************************************************************************** * Notes: - * *Important*: Internal ROM needs to be treated the same as external rom by the programmer - * creating the driver (ie, use standard cpu rom region) - * + * * The term cycles is used here to really refer to clock oscilations, because 1 machine cycle * actually takes 12 oscilations. * @@ -53,12 +93,6 @@ * July 28,2004: Fixed MOVX command and added External Ram Paging Support * July 31,2004: Added Serial Mode 0 Support & Fixed Interrupt Flags for Serial Port * - * NOW Implemented: RAM paging using hardware configured addressing... - * (July 28,2004) the "MOVX a,@R0/R1" and "MOVX @R0/R1,a" commands can use any of the other ports - * to output a page offset into external ram, but it is totally based on the hardware setup. - * - * Timing needs to be implemented via MAME timers perhaps? - * * October, 2008, Couriersud - Major rewrite * *****************************************************************************/ @@ -69,17 +103,20 @@ * - T0 output clock ? * * - Implement 80C52 extended serial capabilities - * - Full Timer support (all modes) * - Fix serial communication - This is a big hack (but working) right now. * - Implement 83C751 in sslam.c * - Fix cardline.c - * - Fix sslam.c and cardline.c * most likely due to different behaviour of I/O pins. The boards * actually use 80CXX, i.e. CMOS versions. * "Normal" 805X will return a 0 if reading from a output port which has * a 0 written to it's latch. At least cardline expects a 1 here. * - * Done: + * Done: (Couriersud) + * - Merged DS5002FP + * - Disassembler now uses type specific memory names + * - Merged DS5002FP disasm + * - added 83C751 memory names to disassembler + * - Pointer-ified * - Implemented cmos features * - Implemented 80C52 interrupt handling * - Fix segas18.c (segaic16.c) memory handling. @@ -592,19 +629,6 @@ struct _mcs51_regs #define PUSH_PC() push_pc(mcs51) #define POP_PC() pop_pc(mcs51) -#if 0 -/* Any pending IRQ */ -#define SERIALPORT_IRQ ((R_SCON & 0x03) && GET_ES) -#define TIMERS_IRQ ((GET_TF0 && GET_ET0) || (GET_TF1 && GET_ET1)) -#define EXTERNAL_IRQ ((GET_IE0 && GET_EX0) || (GET_IE1 && GET_EX1)) - -#if (HAS_I8052 || HAS_I8752) -#define NO_PENDING_IRQ !(TIMERS_IRQ) && !(EXTERNAL_IRQ) && !(SERIALPORT_IRQ) && !(GET_ET2 && (GET_TF2 || GET_EXF2)) -#else -#define NO_PENDING_IRQ !(TIMERS_IRQ) && !(EXTERNAL_IRQ) && !(SERIALPORT_IRQ) -#endif -#endif - /* Clear Current IRQ */ #define CLEAR_CURRENT_IRQ() clear_current_irq(mcs51) @@ -712,12 +736,6 @@ INLINE offs_t external_ram_iaddr(mcs51_regs *mcs51, offs_t offset, offs_t mem_ma if (mem_mask == 0x00ff) return (offset & mem_mask) | (P2 << 8); } -#if 0 - if(mcs51->eram_iaddr_callback) - return mcs51->eram_iaddr_callback(machine,offset,mem_mask); - else - if (mem_mask <= 0x100) LOG(("mcs51 #%d: external ram address requested (8 bit offset=%02x), but no callback available! at PC:%04x\n", cpu_getactivecpu(), offset, PC)); -#endif return offset; } @@ -1961,7 +1979,6 @@ static void mcs51_sfr_write(mcs51_regs *mcs51, size_t offset, UINT8 data) /* update register */ assert(offset >= 0x80 && offset <= 0xff); - /* TODO: Move to memory map */ switch (offset) { case ADDR_P0: OUT(MCS51_PORT_P0,data); break; @@ -2278,7 +2295,7 @@ static CPU_INIT( i80c31 ) /**************************************************************************** * DS5002FP Section ****************************************************************************/ -#ifdef MCS51_TO_BE_ENABLED_LATER +#if 1 //#ifdef MCS51_TO_BE_ENABLED_LATER #define DS5_LOGW(a, d) LOG(("ds5002fp #%d: write to " # a " register at 0x%04x, data=%x\n", cpu_getactivecpu(), PC, d)) @@ -2331,19 +2348,19 @@ static UINT8 ds5002fp_sfr_read(mcs51_regs *mcs51, size_t offset) { switch (offset) { - case ADDR_CRCR: DS5_LOGR(CRCR, data); break; + case ADDR_CRCR: DS5_LOGR(CRCR, data); break; case ADDR_CRCL: DS5_LOGR(CRCL, data); break; - case ADDR_CRCH: DS5_LOGR(CRCH, data); break; + case ADDR_CRCH: DS5_LOGR(CRCH, data); break; case ADDR_MCON: DS5_LOGR(MCON, data); break; - case ADDR_TA: DS5_LOGR(TA, data); break; + case ADDR_TA: DS5_LOGR(TA, data); break; case ADDR_RNR: DS5_LOGR(RNR, data); break; - case ADDR_RPCTL: DS5_LOGR(RPCTL, data); break; + case ADDR_RPCTL: DS5_LOGR(RPCTL, data); break; case ADDR_RPS: DS5_LOGR(RPS, data); break; case ADDR_PCON: SET_PFW(0); /* reset PFW flag */ - return mcs51_sfr_read(mcs51, offset); /* FIXME: cmos features ??? */ + return mcs51_sfr_read(mcs51, offset); default: - return mcs51_sfr_read(mcs51, offset); /* FIXME: cmos features ??? */ + return mcs51_sfr_read(mcs51, offset); } return data_read_byte_8le((size_t) offset | 0x100); } @@ -2355,7 +2372,7 @@ static CPU_INIT( ds5002fp ) const ds5002fp_config *sconfig = config ? config : &default_config; mcs51_regs *mcs51 = device->token; - mcs51_init(index, clock, config, irqcallback); + CPU_INIT_CALL( mcs51 ); mcs51->ds5002fp.config = sconfig; mcs51->features |= (FEATURE_DS5002FP | FEATURE_CMOS); @@ -2373,8 +2390,6 @@ static CPU_INIT( ds5002fp ) ADDRESS MAPS ***************************************************************************/ - -/* FIXME: the memory maps should probably support rom banking for EA */ static ADDRESS_MAP_START(program_12bit, ADDRESS_SPACE_PROGRAM, 8) AM_RANGE(0x00, 0x0fff) AM_ROM ADDRESS_MAP_END @@ -2467,69 +2482,69 @@ static void mcs51_get_info(UINT32 state, cpuinfo *info) switch (state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(mcs51_regs); break; - case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; - case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break; - case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; - case CPUINFO_INT_CLOCK_DIVIDER: info->i = 12; break; - case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; - case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 5; break; - case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; - case CPUINFO_INT_MAX_CYCLES: info->i = 20; /* rough guess */ break; - case CPUINFO_INT_INPUT_LINES: info->i = 3; break; - - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8; break; + case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(mcs51_regs); break; + case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; + case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break; + case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; + case CPUINFO_INT_CLOCK_DIVIDER: info->i = 12; break; + case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; + case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 5; break; + case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; + case CPUINFO_INT_MAX_CYCLES: info->i = 20; /* rough guess */ break; + case CPUINFO_INT_INPUT_LINES: info->i = 3; break; + + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8; break; case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 9; /* due to sfr mapping */ break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 17; break; - case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; - - case CPUINFO_INT_PREVIOUSPC: info->i = PPC; break; - case CPUINFO_INT_PC: info->i = PC; break; - case CPUINFO_INT_SP: info->i = SP; break; - - case CPUINFO_INT_REGISTER + MCS51_PC: info->i = PC; break; - case CPUINFO_INT_REGISTER + MCS51_SP: info->i = SP; break; - case CPUINFO_INT_REGISTER + MCS51_PSW: info->i = PSW; break; - case CPUINFO_INT_REGISTER + MCS51_ACC: info->i = ACC; break; - case CPUINFO_INT_REGISTER + MCS51_B: info->i = B; break; - case CPUINFO_INT_REGISTER + MCS51_DPH: info->i = DPH; break; - case CPUINFO_INT_REGISTER + MCS51_DPL: info->i = DPL; break; - case CPUINFO_INT_REGISTER + MCS51_IE: info->i = IE; break; - case CPUINFO_INT_REGISTER + MCS51_R0: info->i = R_REG(0); break; - case CPUINFO_INT_REGISTER + MCS51_R1: info->i = R_REG(1); break; - case CPUINFO_INT_REGISTER + MCS51_R2: info->i = R_REG(2); break; - case CPUINFO_INT_REGISTER + MCS51_R3: info->i = R_REG(3); break; - case CPUINFO_INT_REGISTER + MCS51_R4: info->i = R_REG(4); break; - case CPUINFO_INT_REGISTER + MCS51_R5: info->i = R_REG(5); break; - case CPUINFO_INT_REGISTER + MCS51_R6: info->i = R_REG(6); break; - case CPUINFO_INT_REGISTER + MCS51_R7: info->i = R_REG(7); break; - case CPUINFO_INT_REGISTER + MCS51_RB: info->i = R_REG(8); break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 18; /* 128k for ds5002fp */ break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; + + case CPUINFO_INT_PREVIOUSPC: info->i = PPC; break; + case CPUINFO_INT_PC: info->i = PC; break; + case CPUINFO_INT_SP: info->i = SP; break; + + case CPUINFO_INT_REGISTER + MCS51_PC: info->i = PC; break; + case CPUINFO_INT_REGISTER + MCS51_SP: info->i = SP; break; + case CPUINFO_INT_REGISTER + MCS51_PSW: info->i = PSW; break; + case CPUINFO_INT_REGISTER + MCS51_ACC: info->i = ACC; break; + case CPUINFO_INT_REGISTER + MCS51_B: info->i = B; break; + case CPUINFO_INT_REGISTER + MCS51_DPH: info->i = DPH; break; + case CPUINFO_INT_REGISTER + MCS51_DPL: info->i = DPL; break; + case CPUINFO_INT_REGISTER + MCS51_IE: info->i = IE; break; + case CPUINFO_INT_REGISTER + MCS51_R0: info->i = R_REG(0); break; + case CPUINFO_INT_REGISTER + MCS51_R1: info->i = R_REG(1); break; + case CPUINFO_INT_REGISTER + MCS51_R2: info->i = R_REG(2); break; + case CPUINFO_INT_REGISTER + MCS51_R3: info->i = R_REG(3); break; + case CPUINFO_INT_REGISTER + MCS51_R4: info->i = R_REG(4); break; + case CPUINFO_INT_REGISTER + MCS51_R5: info->i = R_REG(5); break; + case CPUINFO_INT_REGISTER + MCS51_R6: info->i = R_REG(6); break; + case CPUINFO_INT_REGISTER + MCS51_R7: info->i = R_REG(7); break; + case CPUINFO_INT_REGISTER + MCS51_RB: info->i = R_REG(8); break; /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_PTR_SET_INFO: info->setinfo = mcs51_set_info; break; - case CPUINFO_PTR_GET_CONTEXT: info->getcontext = mcs51_get_context; break; - case CPUINFO_PTR_SET_CONTEXT: info->setcontext = mcs51_set_context; break; - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(mcs51); break; - case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(mcs51); break; - case CPUINFO_PTR_EXIT: info->exit = CPU_EXIT_NAME(mcs51); break; - case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(mcs51); break; - case CPUINFO_PTR_BURN: info->burn = NULL; break; - case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i8051_dasm; break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &mcs51->icount; break; + case CPUINFO_PTR_SET_INFO: info->setinfo = mcs51_set_info; break; + case CPUINFO_PTR_GET_CONTEXT: info->getcontext = mcs51_get_context; break; + case CPUINFO_PTR_SET_CONTEXT: info->setcontext = mcs51_set_context; break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(mcs51); break; + case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(mcs51); break; + case CPUINFO_PTR_EXIT: info->exit = CPU_EXIT_NAME(mcs51); break; + case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(mcs51); break; + case CPUINFO_PTR_BURN: info->burn = NULL; break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i8051_dasm; break; + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &mcs51->icount; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = NULL; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = NULL; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_IO: info->internal_map8 = NULL; break; - case CPUINFO_STR_NAME: strcpy(info->s, "I8051"); break; - case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "MCS-51"); break; - case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break; - case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8051"); break; + case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "MCS-51"); break; + case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break; + case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Steve Ellenoff"); break; case CPUINFO_STR_FLAGS: @@ -2545,21 +2560,21 @@ static void mcs51_get_info(UINT32 state, cpuinfo *info) break; case CPUINFO_STR_REGISTER + MCS51_PC: sprintf(info->s, "PC:%04X", mcs51->pc); break; - case CPUINFO_STR_REGISTER + MCS51_SP: sprintf(info->s, "SP:%02X", SP); break; - case CPUINFO_STR_REGISTER + MCS51_PSW: sprintf(info->s, "PSW:%02X", PSW); break; - case CPUINFO_STR_REGISTER + MCS51_ACC: sprintf(info->s, "A:%02X", ACC); break; - case CPUINFO_STR_REGISTER + MCS51_B: sprintf(info->s, "B:%02X", B); break; - case CPUINFO_STR_REGISTER + MCS51_DPH: sprintf(info->s, "DPH:%02X", DPH); break; - case CPUINFO_STR_REGISTER + MCS51_DPL: sprintf(info->s, "DPL:%02X", DPL); break; - case CPUINFO_STR_REGISTER + MCS51_IE: sprintf(info->s, "IE:%02X", IE); break; - case CPUINFO_STR_REGISTER + MCS51_R0: sprintf(info->s, "R0:%02X", R_REG(0)); break; - case CPUINFO_STR_REGISTER + MCS51_R1: sprintf(info->s, "R1:%02X", R_REG(1)); break; - case CPUINFO_STR_REGISTER + MCS51_R2: sprintf(info->s, "R2:%02X", R_REG(2)); break; - case CPUINFO_STR_REGISTER + MCS51_R3: sprintf(info->s, "R3:%02X", R_REG(3)); break; - case CPUINFO_STR_REGISTER + MCS51_R4: sprintf(info->s, "R4:%02X", R_REG(4)); break; - case CPUINFO_STR_REGISTER + MCS51_R5: sprintf(info->s, "R5:%02X", R_REG(5)); break; - case CPUINFO_STR_REGISTER + MCS51_R6: sprintf(info->s, "R6:%02X", R_REG(6)); break; - case CPUINFO_STR_REGISTER + MCS51_R7: sprintf(info->s, "R7:%02X", R_REG(7)); break; + case CPUINFO_STR_REGISTER + MCS51_SP: sprintf(info->s, "SP:%02X", SP); break; + case CPUINFO_STR_REGISTER + MCS51_PSW: sprintf(info->s, "PSW:%02X", PSW); break; + case CPUINFO_STR_REGISTER + MCS51_ACC: sprintf(info->s, "A:%02X", ACC); break; + case CPUINFO_STR_REGISTER + MCS51_B: sprintf(info->s, "B:%02X", B); break; + case CPUINFO_STR_REGISTER + MCS51_DPH: sprintf(info->s, "DPH:%02X", DPH); break; + case CPUINFO_STR_REGISTER + MCS51_DPL: sprintf(info->s, "DPL:%02X", DPL); break; + case CPUINFO_STR_REGISTER + MCS51_IE: sprintf(info->s, "IE:%02X", IE); break; + case CPUINFO_STR_REGISTER + MCS51_R0: sprintf(info->s, "R0:%02X", R_REG(0)); break; + case CPUINFO_STR_REGISTER + MCS51_R1: sprintf(info->s, "R1:%02X", R_REG(1)); break; + case CPUINFO_STR_REGISTER + MCS51_R2: sprintf(info->s, "R2:%02X", R_REG(2)); break; + case CPUINFO_STR_REGISTER + MCS51_R3: sprintf(info->s, "R3:%02X", R_REG(3)); break; + case CPUINFO_STR_REGISTER + MCS51_R4: sprintf(info->s, "R4:%02X", R_REG(4)); break; + case CPUINFO_STR_REGISTER + MCS51_R5: sprintf(info->s, "R5:%02X", R_REG(5)); break; + case CPUINFO_STR_REGISTER + MCS51_R6: sprintf(info->s, "R6:%02X", R_REG(6)); break; + case CPUINFO_STR_REGISTER + MCS51_R7: sprintf(info->s, "R7:%02X", R_REG(7)); break; case CPUINFO_STR_REGISTER + MCS51_RB: sprintf(info->s, "RB:%02X", ((PSW & 0x18)>>3)); break; } } @@ -2573,9 +2588,8 @@ void i8031_get_info(UINT32 state, cpuinfo *info) switch (state) { case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_7bit; break; - - case CPUINFO_STR_NAME: strcpy(info->s, "I8031"); break; - default: mcs51_get_info(state, info); break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8031"); break; + default: mcs51_get_info(state, info); break; } /* --- the following bits of info are returned as NULL-terminated strings --- */ } @@ -2586,9 +2600,8 @@ void i8051_get_info(UINT32 state, cpuinfo *info) { case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_12bit; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_7bit; break; - - case CPUINFO_STR_NAME: strcpy(info->s, "I8051"); break; - default: mcs51_get_info(state, info); break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8051"); break; + default: mcs51_get_info(state, info); break; } /* --- the following bits of info are returned as NULL-terminated strings --- */ } @@ -2597,13 +2610,11 @@ void i8032_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i8052); break; - + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i8052); break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_8bit; break; - - case CPUINFO_STR_NAME: strcpy(info->s, "I8032"); break; - - default: mcs51_get_info(state, info); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i8052_dasm; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8032"); break; + default: mcs51_get_info(state, info); break; } } @@ -2611,14 +2622,12 @@ void i8052_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i8052); break; - + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i8052); break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_13bit; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_8bit; break; - - case CPUINFO_STR_NAME: strcpy(info->s, "I8052"); break; - - default: mcs51_get_info(state, info); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i8052_dasm; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8052"); break; + default: mcs51_get_info(state, info); break; } } @@ -2628,10 +2637,8 @@ void i8751_get_info(UINT32 state, cpuinfo *info) { case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_12bit; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_7bit; break; - - case CPUINFO_STR_NAME: strcpy(info->s, "I8751"); break; - - default: mcs51_get_info(state, info); break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8751"); break; + default: mcs51_get_info(state, info); break; } } @@ -2639,14 +2646,12 @@ void i8752_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i8052); break; - + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i8052); break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_13bit; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_8bit; break; - - case CPUINFO_STR_NAME: strcpy(info->s, "I8752"); break; - - default: mcs51_get_info(state, info); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i8052_dasm; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8752"); break; + default: mcs51_get_info(state, info); break; } } @@ -2660,13 +2665,12 @@ void i80c31_get_info(UINT32 state, cpuinfo *info) * of i80c52 with 128 bytes internal ram */ switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c31); break; - + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c31); break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = NULL; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_7bit; break; - - case CPUINFO_STR_NAME: strcpy(info->s, "I80C31"); break; - default: i8031_get_info(state, info); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i80c51_dasm; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I80C31"); break; + default: i8031_get_info(state, info); break; } } @@ -2674,9 +2678,10 @@ void i80c51_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c51); break; - case CPUINFO_STR_NAME: strcpy(info->s, "I80C51"); break; - default: i8051_get_info(state, info); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c51); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i80c51_dasm; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I80C51"); break; + default: i8051_get_info(state, info); break; } } @@ -2684,9 +2689,10 @@ void i80c32_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c52); break; - case CPUINFO_STR_NAME: strcpy(info->s, "I80C32"); break; - default: i8032_get_info(state, info); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c52); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i80c52_dasm; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I80C32"); break; + default: i8032_get_info(state, info); break; } } @@ -2694,9 +2700,10 @@ void i80c52_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c52); break; - case CPUINFO_STR_NAME: strcpy(info->s, "I80C52"); break; - default: i8052_get_info(state, info); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c52); break; + case CPUINFO_STR_NAME: strcpy(info->s, "I80C52"); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i80c52_dasm; break; + default: i8052_get_info(state, info); break; } } @@ -2704,9 +2711,10 @@ void i87c51_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c51); break; - case CPUINFO_STR_NAME: strcpy(info->s, "I87C51"); break; - default: i8751_get_info(state, info); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c51); break; + case CPUINFO_STR_NAME: strcpy(info->s, "I87C51"); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i80c51_dasm; break; + default: i8751_get_info(state, info); break; } } @@ -2714,9 +2722,10 @@ void i87c52_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c52); break; - case CPUINFO_STR_NAME: strcpy(info->s, "I87C52"); break; - default: i8752_get_info(state, info); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c52); break; + case CPUINFO_STR_NAME: strcpy(info->s, "I87C52"); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i80c52_dasm; break; + default: i8752_get_info(state, info); break; } } @@ -2728,8 +2737,24 @@ void at89c4051_get_info(UINT32 state, cpuinfo *info) { switch (state) { - case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c51); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i80c51); break; case CPUINFO_STR_NAME: strcpy(info->s, "AT89C4051"); break; - default: i8051_get_info(state, info); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i80c51_dasm; break; + default: i8051_get_info(state, info); break; + } +} + +void ds5002fp_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(ds5002fp); break; + case CPUINFO_STR_NAME: strcpy(info->s, "DS5002FP"); break; + case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Dallas"); break; + case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break; + case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; + case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Manuel Abadia"); break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = ds5002fp_dasm; break; + default: i8051_get_info(state, info); break; } } diff --git a/src/emu/cpu/mcs51/mcs51.h b/src/emu/cpu/mcs51/mcs51.h index 3ac15c61ac6..06ba1e98595 100644 --- a/src/emu/cpu/mcs51/mcs51.h +++ b/src/emu/cpu/mcs51/mcs51.h @@ -66,11 +66,11 @@ enum enum { - MCS51_PORT_P0 = 0x10000, - MCS51_PORT_P1 = 0x10001, - MCS51_PORT_P2 = 0x10002, - MCS51_PORT_P3 = 0x10003, - MCS51_PORT_TX = 0x10004, /* P3.1 */ + MCS51_PORT_P0 = 0x20000, + MCS51_PORT_P1 = 0x20001, + MCS51_PORT_P2 = 0x20002, + MCS51_PORT_P3 = 0x20003, + MCS51_PORT_TX = 0x20004, /* P3.1 */ }; /*************************************************************************** @@ -119,10 +119,33 @@ void i87c52_get_info(UINT32 state, cpuinfo *info); /* 4k internal perom and 128 internal ram and 2 analog comparators */ void at89c4051_get_info(UINT32 state, cpuinfo *info); +/* + * The DS5002FP has 2 16 bits data address buses (the byte-wide bus and the expanded bus). The exact memory position accessed depends on the + * partition mode, the memory range and the expanded bus select. The partition mode and the expanded bus select can be changed at any time. + * + * In order to simplify memory mapping to the data address bus, the following address map is assumed for partitioned mode: + + * 0x00000-0x0ffff -> data memory on the expanded bus + * 0x10000-0x1ffff -> data memory on the byte-wide bus + + * For non-partitioned mode the following memory map is assumed: + + * 0x0000-0xffff -> data memory (the bus used to access it does not matter) + * + * Internal ram 128k and security features + */ + +void ds5002fp_get_info(UINT32 state, cpuinfo *info); + + /**************************************************************************** * Disassembler ****************************************************************************/ offs_t i8051_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram); +offs_t i80c51_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram); +offs_t i8052_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram); +offs_t i80c52_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram); +offs_t ds5002fp_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opram); #endif /* __MCS51_H__ */ diff --git a/src/emu/cpu/mcs51/mcs51dasm.c b/src/emu/cpu/mcs51/mcs51dasm.c index c8b08676d0a..aca0b7d4cbd 100644 --- a/src/emu/cpu/mcs51/mcs51dasm.c +++ b/src/emu/cpu/mcs51/mcs51dasm.c @@ -36,6 +36,17 @@ #include "debugger.h" #include "mcs51.h" +enum +{ + FEATURE_NONE = 0x00, + FEATURE_I8052 = 0x01, + FEATURE_CMOS = 0x02, + FEATURE_I80C52 = 0x04, + FEATURE_DS5002FP = 0x08, + FEATURE_I83C751 = 0x08, +}; + + #define SHOW_MEMORY_NAMES 1 #ifdef SHOW_MEMORY_NAMES @@ -43,143 +54,244 @@ /*Display the memory address names for data & bit address access*/ //SFR Names -static const char sfr[128][7] = { - "p0", "sp", "dpl", "dph", /* 80 - 83 */ - "adat", "85h", "86h", "pcon", /* 84 - 87 */ - "tcon", "tmod", "tl0", "tl1", /* 88 - 8b */ - "th0", "th1", "pwcm", "pwmp", /* 8a - 8f */ - "p1", "91h", "92h", "93h", /* 90 - 93 */ - "94h", "95h", "96h", "97h", /* 94 - 97 */ - "scon", "sbuf", "9ah", "9bh", /* 98 - 9b */ - "9ch", "9dh", "9eh", "9fh", /* 9c - 9f */ - "p2", "0a1h", "0a2h", "0a3h", /* a0 - a3 */ - "0a4h", "0a5h", "0a6h", "0a7h", /* a4 - a7 */ - "ie", "cml0", "cml1", "cml2", /* a8 - ab */ - "ctl0", "ctl1", "ctl2", "ctl3", /* ac - af */ - "p3", "0b1h", "0b2h", "0b3h", /* b0 - b3 */ - "0b4h", "0b5h", "0b6h", "0b7h", /* b4 - b7 */ - "ip", "0b9h", "0bah", "0bbh", /* b8 - bb */ - "0bch", "0bdh", "0beh", "0bfh", /* bc - bf */ - "p4", "0c1h", "0c2h", "0c3h", /* c0 - c3 */ - "p5", "adcon", "adch", "0c7h", /* c4 - c7 */ - "t2con", "cmh0", "rcap2l", "rcap2h", /* c8 - cb */ - "tl2", "th2", "cth2", "cth3", /* cc - cf */ - "psw", "0d1h", "0d2h", "0d3h", /* d0 - d3 */ - "0d4h", "0d5h", "0d6h", "0d7h", /* d4 - d7 */ - "i2cfg", "s1sta", "s1dat", "s1adr", /* d8 - db */ - "0dch", "0ddh", "0deh", "0dfh", /* dc - df */ - "acc", "0e1h", "0e2h", "0e3h", /* e0 - e3 */ - "0e4h", "0e5h", "0e6h", "0e7h", /* e4 - e7 */ - "csr", "0e9h", "tm2con", "ctcon", /* e8 - eb */ - "tml2", "tmh2", "ste", "rte", /* ec - ef */ - "b", "0f1h", "0f2h", "0f3h", /* f0 - f3 */ - "0f4h", "0f5h", "0f6h", "0f7h", /* f4 - f7 */ - "i2sta", "0f9h", "0fah", "0fbh", /* f8 - fb */ - "pwm0", "pwm1", "pwena", "t3" /* fc - ff */ -}; - -//SFR Addressable bits -static const char sfrbits[128][8] = { - "p0.0", "p0.1", "p0.2", "p0.3", /* 80 - 83 */ - "p0.4", "p0.5", "p0.6", "p0.7", /* 84 - 87 */ - "it0", "ie0", "it1", "ie1", /* 88 - 8b */ - "tr0", "tf0", "tr1", "tf1", /* 8c - 8f */ - "p1.0", "p1.1", "p1.2", "p1.3", /* 90 - 93 */ - "p1.4", "p1.5", "p1.6", "p1.7", /* 94 - 97 */ - "ri", "ti", "rb8", "tb8", /* 98 - 9b */ - "ren", "sm2", "sm1", "sm0", /* 9c - 9f */ - "p2.0", "p2.1", "p2.2", "p2.3", /* a0 - a3 */ - "p2.4", "p2.5", "p2.6", "p2.7", /* a4 - a7 */ - "ex0", "et0", "ex1", "et1", /* a8 - ab */ - "es", "ie.5", "ie.6", "ea", /* ac - af */ - "rxd", "txd", "int0", "int1", /* b0 - b3 */ - "t0", "t1", "wr", "rd", /* b4 - b7 */ - "px0", "pt0", "px1", "pt1", /* b8 - bb */ - "ps", "ip.5", "ip.6", "ip.7", /* bc - bf */ - "0c0h.0", "0c0h.1", "0c0h.2", "0c0h.3", /* c0 - c3 */ - "0c0h.4", "0c0h.5", "0c0h.6", "0c0h.7", /* c4 - c7 */ - "cprl2", "ct2", "tr2", "exen2", /* c8 - cb */ - "tclk", "rclk", "exf2", "tf2", /* cc - cf */ - "p", "psw.1", "ov", "rs0", /* d0 - d3 */ - "rs1", "f0", "ac", "cy", /* d4 - d7 */ - "ct0", "ct1", "i2cfg.2","i2cfg.3",/* d8 - db */ - "tirun", "clrti", "mastrq", "slaven", /* dc - df */ - "acc.0", "acc.1", "acc.2", "acc.3", /* e0 - e3 */ - "acc.4", "acc.5", "acc.6", "acc.7", /* e4 - e7 */ - "ibf", "obf", "idsm", "obfc", /* e8 - eb */ - "ma0", "ma1", "mb0", "mb1", /* ec - ef */ - "b.0", "b.1", "b.2", "b.3", /* f0 - f3 */ - "b.4", "b.5", "b.6", "b.7", /* f4 - f7 */ - "xstp", "xstr", "makstp", "makstr", /* f8 - fb */ - "xactv", "xdata", "idle", "i2sta.7" /* fc - ff */ -} ; - -//Names for bit addressable memory -static const char membits[128][6] = { - "20h.0", "20h.1", "20h.2", "20h.3", - "20h.4", "20h.5", "20h.6", "20h.7", - "21h.0", "21h.1", "21h.2", "21h.3", - "21h.4", "21h.5", "21h.6", "21h.7", - "22h.0", "22h.1", "22h.2", "22h.3", - "22h.4", "22h.5", "22h.6", "22h.7", - "23h.0", "23h.1", "23h.2", "23h.3", - "23h.4", "23h.5", "23h.6", "23h.7", - "24h.0", "24h.1", "24h.2", "24h.3", - "24h.4", "24h.5", "24h.6", "24h.7", - "25h.0", "25h.1", "25h.2", "25h.3", - "25h.4", "25h.5", "25h.6", "25h.7", - "26h.0", "26h.1", "26h.2", "26h.3", - "26h.4", "26h.5", "26h.6", "26h.7", - "27h.0", "27h.1", "27h.2", "27h.3", - "27h.4", "27h.5", "27h.6", "27h.7", - "28h.0", "28h.1", "28h.2", "28h.3", - "28h.4", "28h.5", "28h.6", "28h.7", - "29h.0", "29h.1", "29h.2", "29h.3", - "29h.4", "29h.5", "29h.6", "29h.7", - "2ah.0", "2ah.1", "2ah.2", "2ah.3", - "2ah.4", "2ah.5", "2ah.6", "2ah.7", - "2bh.0", "2bh.1", "2bh.2", "2bh.3", - "2bh.4", "2bh.5", "2bh.6", "2bh.7", - "2ch.0", "2ch.1", "2ch.2", "2ch.3", - "2ch.4", "2ch.5", "2ch.6", "2ch.7", - "2dh.0", "2dh.1", "2dh.2", "2dh.3", - "2dh.4", "2dh.5", "2dh.6", "2dh.7", - "2eh.0", "2eh.1", "2eh.2", "2eh.3", - "2eh.4", "2eh.5", "2eh.6", "2eh.7", - "2fh.0", "2fh.1", "2fh.2", "2fh.3", - "2fh.4", "2fh.5", "2fh.6", "2fh.7" -}; -//Regiser Bank memory names -static const char regbank[][6] = { - "rb0r0", "rb0r1", "rb0r2", "rb0r3", - "rb0r4", "rb0r5", "rb0r6", "rb0r7", - "rb1r0", "rb1r1", "rb1r2", "rb1r3", - "rb1r4", "rb1r5", "rb1r6", "rb1r7", - "rb2r0", "rb2r1", "rb2r2", "rb2r3", - "rb2r4", "rb2r5", "rb2r6", "rb2r7", - "rb3r0", "rb3r1", "rb3r2", "rb3r3", - "rb3r4", "rb3r5", "rb3r6", "rb3r7" +static struct { + int feature; + int addr; + const char *name; +} mem_name_feature[] = +{ + { FEATURE_NONE, 0x00, "rb0r0" }, + { FEATURE_NONE, 0x01, "rb0r1" }, + { FEATURE_NONE, 0x02, "rb0r2" }, + { FEATURE_NONE, 0x03, "rb0r3" }, + { FEATURE_NONE, 0x04, "rb0r4" }, + { FEATURE_NONE, 0x05, "rb0r5" }, + { FEATURE_NONE, 0x06, "rb0r6" }, + { FEATURE_NONE, 0x07, "rb0r7" }, + { FEATURE_NONE, 0x08, "rb1r0" }, + { FEATURE_NONE, 0x09, "rb1r1" }, + { FEATURE_NONE, 0x0a, "rb1r2" }, + { FEATURE_NONE, 0x0b, "rb1r3" }, + { FEATURE_NONE, 0x0c, "rb1r4" }, + { FEATURE_NONE, 0x0d, "rb1r5" }, + { FEATURE_NONE, 0x0e, "rb1r6" }, + { FEATURE_NONE, 0x0f, "rb1r7" }, + { FEATURE_NONE, 0x10, "rb2r0" }, + { FEATURE_NONE, 0x11, "rb2r1" }, + { FEATURE_NONE, 0x12, "rb2r2" }, + { FEATURE_NONE, 0x13, "rb2r3" }, + { FEATURE_NONE, 0x14, "rb2r4" }, + { FEATURE_NONE, 0x15, "rb2r5" }, + { FEATURE_NONE, 0x16, "rb2r6" }, + { FEATURE_NONE, 0x17, "rb2r7" }, + { FEATURE_NONE, 0x18, "rb3r0" }, + { FEATURE_NONE, 0x19, "rb3r1" }, + { FEATURE_NONE, 0x1a, "rb3r2" }, + { FEATURE_NONE, 0x1b, "rb3r3" }, + { FEATURE_NONE, 0x1c, "rb3r4" }, + { FEATURE_NONE, 0x1d, "rb3r5" }, + { FEATURE_NONE, 0x1e, "rb3r6" }, + { FEATURE_NONE, 0x1f, "rb3r7" }, + + { FEATURE_NONE, 0x80, "p0" }, + { FEATURE_NONE, 0x81, "sp" }, + { FEATURE_NONE, 0x82, "dpl" }, + { FEATURE_NONE, 0x83, "dph" }, + { FEATURE_NONE, 0x87, "pcon" }, + { FEATURE_NONE, 0x88, "tcon" }, + { FEATURE_NONE, 0x89, "tmod" }, + { FEATURE_NONE, 0x8a, "tl0" }, + { FEATURE_NONE, 0x8b, "tl1" }, + { FEATURE_NONE, 0x8c, "th0" }, + { FEATURE_NONE, 0x8d, "th1" }, + { FEATURE_NONE, 0x90, "p1" }, + { FEATURE_NONE, 0x98, "scon" }, + { FEATURE_NONE, 0x99, "sbuf" }, + { FEATURE_NONE, 0xa0, "p2" }, + { FEATURE_NONE, 0xa8, "ie" }, + { FEATURE_NONE, 0xb0, "p3" }, + { FEATURE_NONE, 0xb8, "ip" }, + { FEATURE_NONE, 0xd0, "psw" }, + { FEATURE_NONE, 0xe0, "acc" }, + { FEATURE_NONE, 0xf0, "b" }, + + { FEATURE_I8052, 0xc8, "t2con" }, + { FEATURE_I8052, 0xca, "rcap2l" }, + { FEATURE_I8052, 0xcb, "rcap2h" }, + { FEATURE_I8052, 0xcc, "tl2" }, + { FEATURE_I8052, 0xcd, "th2" }, + + { FEATURE_I80C52, 0xb7, "iph" }, + { FEATURE_I80C52, 0xa9, "saddr" }, + { FEATURE_I80C52, 0xb9, "saden" }, + + { FEATURE_DS5002FP, 0x8e, "pwcm" }, + { FEATURE_DS5002FP, 0x8f, "pwmp" }, + { FEATURE_DS5002FP, 0xc1, "crcr" }, + { FEATURE_DS5002FP, 0xc2, "crcl" }, + { FEATURE_DS5002FP, 0xc3, "crch" }, + { FEATURE_DS5002FP, 0xc6, "mcon" }, + { FEATURE_DS5002FP, 0xc7, "ta" }, + { FEATURE_DS5002FP, 0xcf, "rnr" }, + { FEATURE_DS5002FP, 0xd8, "rpctl" }, + { FEATURE_DS5002FP, 0xd9, "rps" }, + + { FEATURE_I83C751, 0x98, "i2con" }, + { FEATURE_I83C751, 0x99, "i2dat" }, + { FEATURE_I83C751, 0xd8, "i2cfg" }, + { FEATURE_I83C751, 0xf8, "i2sta" }, /* read only */ + + /* bit addresses */ + + { FEATURE_NONE, 0x188, "it0" }, + { FEATURE_NONE, 0x189, "ie0" }, + { FEATURE_NONE, 0x18a, "it1" }, + { FEATURE_NONE, 0x18b, "ie1" }, + { FEATURE_NONE, 0x18c, "tr0" }, + { FEATURE_NONE, 0x18d, "tf0" }, + { FEATURE_NONE, 0x18e, "tr1" }, + { FEATURE_NONE, 0x18f, "tf1" }, + + { FEATURE_NONE, 0x198, "ri" }, + { FEATURE_NONE, 0x199, "ti" }, + { FEATURE_NONE, 0x19a, "rb8" }, + { FEATURE_NONE, 0x19b, "tb8" }, + { FEATURE_NONE, 0x19c, "ren" }, + { FEATURE_NONE, 0x19d, "sm2" }, + { FEATURE_NONE, 0x19e, "sm1" }, + { FEATURE_NONE, 0x19f, "sm0" }, + + { FEATURE_I83C751, 0x198, "xstp" }, /* read: no function */ + { FEATURE_I83C751, 0x199, "xstr" }, /* read: MASTER */ + { FEATURE_I83C751, 0x19a, "cstp" }, /* read: STP */ + { FEATURE_I83C751, 0x19b, "cstr" }, /* read: STR */ + { FEATURE_I83C751, 0x19c, "carl" }, /* read: ARL */ + { FEATURE_I83C751, 0x19d, "cdr" }, /* read: DRDY */ + { FEATURE_I83C751, 0x19e, "idle" }, /* read: ATN */ + { FEATURE_I83C751, 0x19f, "cxa" }, /* read: RDAT */ + + { FEATURE_NONE, 0x1a8, "ex0" }, + { FEATURE_NONE, 0x1a9, "et0" }, + { FEATURE_NONE, 0x1aa, "ex1" }, + { FEATURE_NONE, 0x1ab, "et1" }, + { FEATURE_NONE, 0x1ac, "es" }, + { FEATURE_NONE, 0x1ad, "ie.5" }, + { FEATURE_NONE, 0x1ae, "ie.6" }, + { FEATURE_NONE, 0x1af, "ea" }, + + { FEATURE_I83C751, 0x1ac, "ei2" }, + { FEATURE_I8052, 0x1ad, "et2" }, + + /* FIXME: port 3 - depends on external circuits and not really + * implemented in the core. TBD */ + { FEATURE_NONE, 0x1b0, "rxd" }, + { FEATURE_NONE, 0x1b1, "txd" }, + { FEATURE_NONE, 0x1b2, "int0" }, + { FEATURE_NONE, 0x1b3, "int1" }, + { FEATURE_NONE, 0x1b4, "t0" }, + { FEATURE_NONE, 0x1b5, "t1" }, + { FEATURE_NONE, 0x1b6, "wr" }, + { FEATURE_NONE, 0x1b7, "rd" }, + + { FEATURE_NONE, 0x1b8, "px0" }, + { FEATURE_NONE, 0x1b9, "pt0" }, + { FEATURE_NONE, 0x1ba, "px1" }, + { FEATURE_NONE, 0x1bb, "pt1" }, + { FEATURE_NONE, 0x1bc, "ps" }, + { FEATURE_NONE, 0x1bd, "ip.5" }, + { FEATURE_NONE, 0x1be, "ip.6" }, + { FEATURE_NONE, 0x1bf, "ip.7" }, + + { FEATURE_I8052, 0x1bd, "pt2" }, + { FEATURE_I83C751, 0x1bc, "pi2" }, + + { FEATURE_I8052, 0x1c8, "cprl2" }, + { FEATURE_I8052, 0x1c9, "ct2" }, + { FEATURE_I8052, 0x1ca, "tr2" }, + { FEATURE_I8052, 0x1cb, "exen2" }, + { FEATURE_I8052, 0x1cc, "tclk" }, + { FEATURE_I8052, 0x1cd, "rclk" }, + { FEATURE_I8052, 0x1ce, "exf2" }, + { FEATURE_I8052, 0x1cf, "tf2" }, + + { FEATURE_NONE, 0x1d0, "p" }, + { FEATURE_NONE, 0x1d1, "psw.1" }, + { FEATURE_NONE, 0x1d2, "ov" }, + { FEATURE_NONE, 0x1d3, "rs0" }, + { FEATURE_NONE, 0x1d4, "rs1" }, + { FEATURE_NONE, 0x1d5, "f0" }, + { FEATURE_NONE, 0x1d6, "ac" }, + { FEATURE_NONE, 0x1d7, "cy" }, + + { FEATURE_DS5002FP, 0x1d8, "rg0" }, + { FEATURE_DS5002FP, 0x1d9, "rpc" }, + { FEATURE_DS5002FP, 0x1da, "dma" }, + { FEATURE_DS5002FP, 0x1db, "ibi" }, + { FEATURE_DS5002FP, 0x1dc, "ae" }, + { FEATURE_DS5002FP, 0x1dd, "exbs" }, + { FEATURE_DS5002FP, 0x1de, "d8.6" }, + { FEATURE_DS5002FP, 0x1df, "rnr" }, + + { FEATURE_I83C751, 0x1d8, "ct0" }, + { FEATURE_I83C751, 0x1d9, "ct1" }, + { FEATURE_I83C751, 0x1da, "i2cfg.2" }, + { FEATURE_I83C751, 0x1db, "i2cfg.3" }, + { FEATURE_I83C751, 0x1dc, "tirun" }, + { FEATURE_I83C751, 0x1dd, "clrti" }, + { FEATURE_I83C751, 0x1de, "masterq" }, + { FEATURE_I83C751, 0x1df, "slaven" }, + + { FEATURE_I83C751, 0x1f8, "xstp" }, + { FEATURE_I83C751, 0x1f9, "xstr" }, + { FEATURE_I83C751, 0x1fa, "makstp" }, + { FEATURE_I83C751, 0x1fb, "makstr" }, + { FEATURE_I83C751, 0x1fc, "xactv" }, + { FEATURE_I83C751, 0x1fd, "xdata" }, + { FEATURE_I83C751, 0x1fe, "idle" }, + { FEATURE_I83C751, 0x1ff, "i2sta.7" }, + + /* unkown + * "ibf", "obf", "idsm", "obfc", e8 - eb + * "ma0", "ma1", "mb0", "mb1", ec - ef + */ + + { -1 } }; -static const char *get_data_address( UINT8 arg ) +static void init_mem_names(int feature_set, const char **mem_names) { - char *buffer = cpuintrf_temp_str(); + int i; + int feature; + + /* Set defaults / i8051 */ + for (i = 0; feature = mem_name_feature[i].feature, feature >= 0; i++) + { + if ( feature == FEATURE_NONE ) + mem_names[mem_name_feature[i].addr] = mem_name_feature[i].name; + } - if(arg < 0x80) + /* Set specific memory names */ + for (i = 0; feature = mem_name_feature[i].feature, feature >= 0; i++) { - //Ram locations 0-0x1F are considered register access in 3 banks - if(arg < 0x1f) - sprintf(buffer,"%s",regbank[arg]); - else - sprintf(buffer,"$%02X",arg); + if (feature & feature_set) + mem_names[mem_name_feature[i].addr] = mem_name_feature[i].name; } + +} + +static const char *get_data_address( const char **mem_names, UINT8 arg ) +{ + char *buffer = cpuintrf_temp_str(); + + if (mem_names[arg] == NULL) + sprintf(buffer,"$%02X",arg); else - sprintf(buffer,"%s",sfr[arg-0x80]); + sprintf(buffer,"%s", mem_names[arg]); return buffer; } -static const char *get_bit_address( UINT8 arg ) +static const char *get_bit_address( const char **mem_names, UINT8 arg ) { char *buffer = cpuintrf_temp_str(); @@ -187,12 +299,22 @@ static const char *get_bit_address( UINT8 arg ) { //Bit address 0-7F can be referred to as 20.0, 20.1, to 20.7 for address 0, and 2f.0,2f.1 to 2f.7 for address 7f if(arg < 0x7f) - sprintf(buffer,"%s",membits[arg]); + sprintf(buffer,"$%02X.%d",(arg >> 3) | 0x20, arg & 0x07); else sprintf(buffer,"$%02X",arg); } else - sprintf(buffer,"%s",sfrbits[arg-0x80]); + { + if (mem_names[arg | 0x100] == NULL) + { + if (mem_names[arg & 0xf8] == NULL) + sprintf(buffer,"$%02X.%d", arg & 0xf8, arg & 0x07); + else + sprintf(buffer,"%s.%d", mem_names[arg & 0xf8], arg & 0x07); + } + else + sprintf(buffer,"%s", mem_names[arg | 0x100]); + } return buffer; } @@ -216,8 +338,7 @@ static const char *get_bit_address( UINT8 arg ) #endif - -unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opram) +static offs_t mcs51_dasm( const char **mem_names, char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opram) { UINT32 flags = 0; unsigned PC = pc; @@ -267,7 +388,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //INC data addr case 0x05: /* 1: 0000 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "inc %s", sym); break; @@ -291,7 +412,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //JBC bit addr, code addr case 0x10: /* 1: 0001 0000 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); rel = opram[PC++ - pc]; sprintf(dst, "jbc %s,$%04X", sym, PC + rel); break; @@ -330,7 +451,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //DEC data addr case 0x15: /* 1: 0001 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "dec %s", sym); break; @@ -355,7 +476,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //JB bit addr, code addr case 0x20: /* 1: 0010 0000 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); rel = opram[PC++ - pc]; sprintf(dst, "jb %s,$%04X", sym, (PC + rel)); break; @@ -378,7 +499,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //ADD A, data addr case 0x25: /* 1: 0010 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "add a,%s", sym); break; @@ -403,7 +524,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //JNB bit addr, code addr case 0x30: /* 1: 0011 0000 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); rel = opram[PC++ - pc]; sprintf(dst, "jnb %s,$%04X", sym, (PC + rel)); break; @@ -426,7 +547,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //ADDC A, data addr case 0x35: /* 1: 0011 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "addc a,%s", sym); break; @@ -456,13 +577,13 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //ORL data addr, A case 0x42: /* 1: 0100 0010 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "orl %s,a", sym); break; //ORL data addr, #data case 0x43: /* 1: 0100 0011 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "orl %s,#$%02X", sym, opram[PC++ - pc]); break; @@ -474,7 +595,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //ORL A, data addr case 0x45: /* 1: 0100 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "orl a,%s", sym); break; @@ -505,14 +626,14 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //Unable to test //ANL data addr, A case 0x52: /* 1: 0101 0010 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "anl %s,a", sym); break; //Unable to test //ANL data addr, #data case 0x53: /* 1: 0101 0011 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "anl %s,#$%02X", sym, opram[PC++ - pc]); break; @@ -523,7 +644,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //ANL A, data addr case 0x55: /* 1: 0101 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "anl a,%s", sym); break; @@ -555,13 +676,13 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //Unable to test //XRL data addr, A case 0x62: /* 1: 0110 0010 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "xrl %s,a", sym); break; //XRL data addr, #data case 0x63: /* 1: 0110 0011 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "xrl %s,#$%02X", sym, opram[PC++ - pc]); break; @@ -572,7 +693,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //XRL A, data addr case 0x65: /* 1: 0110 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "xrl a,%s", sym); break; @@ -604,7 +725,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //Unable to test //ORL C, bit addr case 0x72: /* 1: 0111 0010 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "orl c,%s", sym); break; @@ -621,7 +742,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //MOV data addr, #data case 0x75: /* 1: 0111 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov %s,#$%02X", sym, opram[PC++ - pc]); break; @@ -652,7 +773,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //ANL C, bit addr case 0x82: /* 1: 1000 0010 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "anl c,%s", sym); break; @@ -668,8 +789,8 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //MOV data addr, data addr (Note: 1st address is src, 2nd is dst, but the mov command works as mov dst,src) case 0x85: /* 1: 1000 0101 */ - sym = get_data_address(opram[PC++ - pc]); - sym2 = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); + sym2 = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov %s,%s", sym2, sym); break; @@ -677,7 +798,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //MOV data addr, @R0/@R1/* 1: 1000 011i */ case 0x86: case 0x87: - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov %s,@r%d", sym, op&1); break; @@ -690,7 +811,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr case 0x8d: case 0x8e: case 0x8f: - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov %s,r%d", sym, op&7); break; @@ -703,7 +824,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //MOV bit addr, C case 0x92: /* 1: 1001 0010 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov %s,c", sym); break; @@ -719,7 +840,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //SUBB A, data addr case 0x95: /* 1: 1001 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "subb a,%s", sym); break; @@ -745,13 +866,13 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //Unable to test //ORL C, /bit addr case 0xa0: /* 1: 1010 0000 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "orl c,/%s", sym); break; //MOV C, bit addr case 0xa2: /* 1: 1010 0010 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov c,%s", sym); break; @@ -774,7 +895,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //MOV @R0/@R1, data addr /* 1: 1010 011i */ case 0xa6: case 0xa7: - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov @r%d,%s", op&1, sym); break; @@ -787,19 +908,19 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr case 0xad: case 0xae: case 0xaf: - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov r%d,%s", op&7, sym); break; //ANL C,/bit addr case 0xb0: /* 1: 1011 0000 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "anl c,/%s", sym); break; //CPL bit addr case 0xb2: /* 1: 1011 0010 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "cpl %s", sym); break; @@ -818,7 +939,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //CJNE A, data addr, code addr case 0xb5: /* 1: 1011 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); rel = opram[PC++ - pc]; sprintf(dst, "cjne a,%s,$%04X", sym, PC + rel); break; @@ -848,13 +969,13 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //PUSH data addr case 0xc0: /* 1: 1100 0000 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "push %s", sym); break; //CLR bit addr case 0xc2: /* 1: 1100 0010 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "clr %s", sym); break; @@ -870,7 +991,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //XCH A, data addr case 0xc5: /* 1: 1100 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "xch a,%s", sym); break; @@ -894,13 +1015,13 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //POP data addr case 0xd0: /* 1: 1101 0000 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "pop %s", sym); break; //SETB bit addr case 0xd2: /* 1: 1101 0010 */ - sym = get_bit_address(opram[PC++ - pc]); + sym = get_bit_address(mem_names, opram[PC++ - pc]); sprintf(dst, "setb %s", sym); break; @@ -917,7 +1038,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //DJNZ data addr, code addr case 0xd5: /* 1: 1101 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); rel = opram[PC++ - pc]; sprintf(dst, "djnz %s,$%04X", sym, PC + rel); flags = DASMFLAG_STEP_OVER; @@ -962,7 +1083,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //MOV A, data addr case 0xe5: /* 1: 1110 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov a,%s", sym); break; @@ -1004,7 +1125,7 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr //MOV data addr, A case 0xf5: /* 1: 1111 0101 */ - sym = get_data_address(opram[PC++ - pc]); + sym = get_data_address(mem_names, opram[PC++ - pc]); sprintf(dst, "mov %s,a", sym); break; @@ -1030,4 +1151,70 @@ unsigned i8051_dasm(char *dst, unsigned pc, const UINT8 *oprom, const UINT8 *opr sprintf(dst, "illegal"); } return (PC - pc) | flags | DASMFLAG_SUPPORTED; + +} + +offs_t i8051_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opram) +{ + static const char *mem_names[0x200]; + static int mem_names_initialized = 0; + + if (!mem_names_initialized) + { + init_mem_names( FEATURE_NONE, mem_names); + mem_names_initialized = 1; + } + return mcs51_dasm(mem_names, dst, pc, oprom, opram); +} + +offs_t i8052_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opram) +{ + static const char *mem_names[0x200]; + static int mem_names_initialized = 0; + + if (!mem_names_initialized) + { + init_mem_names( FEATURE_I8052, mem_names); + mem_names_initialized = 1; + } + return mcs51_dasm(mem_names, dst, pc, oprom, opram); +} + +offs_t i80c51_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opram) +{ + static const char *mem_names[0x200]; + static int mem_names_initialized = 0; + + if (!mem_names_initialized) + { + init_mem_names( FEATURE_CMOS, mem_names); + mem_names_initialized = 1; + } + return mcs51_dasm(mem_names, dst, pc, oprom, opram); +} + +offs_t i80c52_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opram) +{ + static const char *mem_names[0x200]; + static int mem_names_initialized = 0; + + if (!mem_names_initialized) + { + init_mem_names( FEATURE_I8052 | FEATURE_CMOS | FEATURE_I80C52, mem_names); + mem_names_initialized = 1; + } + return mcs51_dasm(mem_names, dst, pc, oprom, opram); +} + +offs_t ds5002fp_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opram) +{ + static const char *mem_names[0x200]; + static int mem_names_initialized = 0; + + if (!mem_names_initialized) + { + init_mem_names( FEATURE_DS5002FP | FEATURE_CMOS, mem_names); + mem_names_initialized = 1; + } + return mcs51_dasm(mem_names, dst, pc, oprom, opram); } |