diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index 10e1fa5ea59..4080fa5c9c3 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -606,14 +606,19 @@ $(CPUOBJ)/i8085/i8085.o: $(CPUSRC)/i8085/i8085.c \ #------------------------------------------------- CPUDEFS += -DHAS_I8035=$(if $(filter I8035,$(CPUS)),1,0) -CPUDEFS += -DHAS_I8039=$(if $(filter I8039,$(CPUS)),1,0) +CPUDEFS += -DHAS_I8041=$(if $(filter I8041,$(CPUS)),1,0) CPUDEFS += -DHAS_I8048=$(if $(filter I8048,$(CPUS)),1,0) +CPUDEFS += -DHAS_I8648=$(if $(filter I8648,$(CPUS)),1,0) +CPUDEFS += -DHAS_I8748=$(if $(filter I8748,$(CPUS)),1,0) +CPUDEFS += -DHAS_MB8884=$(if $(filter MB8884,$(CPUS)),1,0) + +CPUDEFS += -DHAS_I8039=$(if $(filter I8039,$(CPUS)),1,0) +CPUDEFS += -DHAS_I8049=$(if $(filter I8049,$(CPUS)),1,0) CPUDEFS += -DHAS_I8749=$(if $(filter I8749,$(CPUS)),1,0) CPUDEFS += -DHAS_N7751=$(if $(filter N7751,$(CPUS)),1,0) -CPUDEFS += -DHAS_MB8884=$(if $(filter MB8884,$(CPUS)),1,0) CPUDEFS += -DHAS_M58715=$(if $(filter M58715,$(CPUS)),1,0) -ifneq ($(filter I8035 I8039 I8048 I8749 N7751 MB8884 M58715,$(CPUS)),) +ifneq ($(filter I8035 I8041 I8048 I8648 I8748 MB8884 I8039 I8049 I8749 N7751 M58715,$(CPUS)),) OBJDIRS += $(CPUOBJ)/i8039 CPUOBJS += $(CPUOBJ)/i8039/i8039.o DBGOBJS += $(CPUOBJ)/i8039/8039dasm.o diff --git a/src/emu/cpu/i8039/i8039.c b/src/emu/cpu/i8039/i8039.c index baeaf0e7f67..312d3c6706a 100644 --- a/src/emu/cpu/i8039/i8039.c +++ b/src/emu/cpu/i8039/i8039.c @@ -34,6 +34,29 @@ ****************************************************************************/ +/**************************************************************************** + + Chip RAM ROM I/O + ---- --- --- --- + 8021 64 1k 21 (ROM, reduced instruction set) + + 8035 64 0 27 (external ROM) + 8041 64 1k 18 (ROM) + 8048 64 1k 27 (ROM) + 8648 64 1k 27 (OTPROM) + 8741 64 1k 18 (EPROM) + 8748 64 1k 27 (EPROM) + 8884 64 1k + N7751 128 2k + + 8039 128 0 27 (external ROM) + 8049 128 2k 27 (ROM) + 8749 128 2k 27 (EPROM) + M58715 128 0 (external ROM) + +****************************************************************************/ + + #include "debugger.h" #include "i8039.h" @@ -75,8 +98,8 @@ static int Timer_IRQ(void); #define bus_r() I8039_In(I8039_bus) #define bus_w(V) I8039_Out(I8039_bus,V) -#define INTRAM_R(A) (intRAM[(A) & R.ram_mask]) -#define INTRAM_W(A,V) do { intRAM[(A) & R.ram_mask] = V; } while (0); +#define INTRAM_R(A) data_read_byte_8le(A) +#define INTRAM_W(A,V) data_write_byte_8le(A, V) #define C_FLAG 0x80 #define A_FLAG 0x40 @@ -87,15 +110,14 @@ typedef struct { PAIR PREVPC; /* previous program counter */ PAIR PC; /* program counter */ + UINT8 * regptr; /* pointer to r0-r7 */ UINT8 A, SP, PSW; - UINT8 RAM[128]; UINT8 bus, f1; /* Bus data, and flag1 */ UINT8 P1, P2; /* Internal Port 1 and 2 latched outputs */ UINT8 EA; /* latched EA input */ UINT8 cpu_feature; /* process feature */ - UINT8 ram_mask; /* internal ram size - 1 */ UINT16 int_rom_size; /* internal rom size */ - UINT8 pending_irq, irq_executing, masterClock, regPtr; + UINT8 pending_irq, irq_executing, masterClock; UINT8 t_flag, timer, timerON, countON, xirq_en, tirq_en; UINT16 A11; UINT8 irq_state, irq_extra_cycles; @@ -125,17 +147,19 @@ typedef struct { #define M_By ((R.PSW & B_FLAG)) #define M_Bn (!M_By) -#define intRAM R.RAM -#define regPTR R.regPtr +#define R0 R.regptr[0] +#define R1 R.regptr[1] +#define R2 R.regptr[2] +#define R3 R.regptr[3] +#define R4 R.regptr[4] +#define R5 R.regptr[5] +#define R6 R.regptr[6] +#define R7 R.regptr[7] -#define R0 intRAM[regPTR ] -#define R1 intRAM[regPTR+1] -#define R2 intRAM[regPTR+2] -#define R3 intRAM[regPTR+3] -#define R4 intRAM[regPTR+4] -#define R5 intRAM[regPTR+5] -#define R6 intRAM[regPTR+6] -#define R7 intRAM[regPTR+7] +INLINE void update_regptr(void) +{ + R.regptr = memory_get_write_ptr(cpu_getactivecpu(), ADDRESS_SPACE_DATA, (M_By) ? 24 : 0); +} INLINE UINT8 ea_r(void) { @@ -174,7 +198,7 @@ INLINE unsigned M_RDMEM_OPCODE (void) INLINE void push(UINT8 d) { - intRAM[8+R.SP++] = d; + INTRAM_W(8+R.SP++, d); R.SP = R.SP & 0x0f; R.PSW = R.PSW & 0xf8; R.PSW = R.PSW | (R.SP >> 1); @@ -184,8 +208,8 @@ INLINE UINT8 pull(void) { R.SP = (R.SP + 15) & 0x0f; /* if (--R.SP < 0) R.SP = 15; */ R.PSW = R.PSW & 0xf8; R.PSW = R.PSW | (R.SP >> 1); - /* regPTR = ((M_By) ? 24 : 0); regPTR should not change */ - return intRAM[8+R.SP]; + /* update_regptr(); regPTR should not change */ + return INTRAM_R(8+R.SP); } INLINE void daa_a(void) @@ -425,7 +449,7 @@ static void mov_r4_a(void) { R4 = R.A; } static void mov_r5_a(void) { R5 = R.A; } static void mov_r6_a(void) { R6 = R.A; } static void mov_r7_a(void) { R7 = R.A; } -static void mov_psw_a(void) { R.PSW = R.A; regPTR = ((M_By) ? 24 : 0); R.SP = (R.PSW & 7) << 1; } +static void mov_psw_a(void) { R.PSW = R.A; update_regptr(); R.SP = (R.PSW & 7) << 1; } static void mov_r0_n(void) { R0 = M_RDMEM_OPCODE(); } static void mov_r1_n(void) { R1 = M_RDMEM_OPCODE(); } static void mov_r2_n(void) { R2 = M_RDMEM_OPCODE(); } @@ -494,7 +518,7 @@ static void retr(void) R.PC.w.l = ((i & 0x0f) << 8) | pull(); change_pc(R.PC.w.l); R.PSW = (R.PSW & 0x0f) | (i & 0xf0); /* Stack is already changed by pull */ - regPTR = ((M_By) ? 24 : 0); + update_regptr(); R.irq_executing = I8039_NO_INT; @@ -514,8 +538,8 @@ static void rr_a(void) { UINT8 i=R.A & 1; R.A >>= 1; if (i) R.A |= 0x80; else static void rrc_a(void) { UINT8 i=M_Cy; if (R.A & 1) SET(C_FLAG); else CLR(C_FLAG); R.A >>= 1; if (i) R.A |= 0x80; else R.A &= 0x7f; } static void sel_mb0(void) { R.A11 = 0x000; } static void sel_mb1(void) { R.A11 = 0x800; } -static void sel_rb0(void) { CLR(B_FLAG); regPTR = 0; } -static void sel_rb1(void) { SET(B_FLAG); regPTR = 24; } +static void sel_rb0(void) { CLR(B_FLAG); update_regptr(); } +static void sel_rb1(void) { SET(B_FLAG); update_regptr(); } static void stop_tcnt(void) { R.timerON = R.countON = 0; } static void strt_cnt(void) { R.countON = 1; R.timerON = 0; R.Old_T1 = test_r(1); } /* NS990113 */ static void strt_t(void) { R.timerON = 1; R.countON = 0; R.masterClock = 0; } /* NS990113 */ @@ -586,8 +610,11 @@ static const s_opcode opcode_main[256]= /**************************************************************************** * Initialize emulation ****************************************************************************/ -static void i8039_init (int index, int clock, const void *config, int (*irqcallback)(int)) + +static void generic_init(int index, int clock, const void *config, int (*irqcallback)(int), UINT16 romsize) { + R.int_rom_size = romsize; + R.irq_callback = irqcallback; state_save_register_item("i8039", index, R.PC.w.l); @@ -595,7 +622,6 @@ static void i8039_init (int index, int clock, const void *config, int (*irqcallb state_save_register_item("i8039", index, R.A); state_save_register_item("i8039", index, R.SP); state_save_register_item("i8039", index, R.PSW); - state_save_register_item_array("i8039", index, R.RAM); state_save_register_item("i8039", index, R.bus); state_save_register_item("i8039", index, R.f1); state_save_register_item("i8039", index, R.P1); @@ -603,7 +629,6 @@ static void i8039_init (int index, int clock, const void *config, int (*irqcallb state_save_register_item("i8039", index, R.pending_irq); state_save_register_item("i8039", index, R.irq_executing); state_save_register_item("i8039", index, R.masterClock); - state_save_register_item("i8039", index, R.regPtr); state_save_register_item("i8039", index, R.t_flag); state_save_register_item("i8039", index, R.timer); state_save_register_item("i8039", index, R.timerON); @@ -616,39 +641,32 @@ static void i8039_init (int index, int clock, const void *config, int (*irqcallb state_save_register_item("i8039", index, R.Old_T1); R.cpu_feature = 0; - R.ram_mask = 0x7F; - R.int_rom_size = 0x800; - /* not changed on reset*/ - memset(R.RAM, 0x00, 128); R.timer = 0; } -#if (HAS_I8035||HAS_I8048||HAS_MB8884) +#if (HAS_I8035 || HAS_I8041 || HAS_I8048 || HAS_I8648 || HAS_I8748 || HAS_MB8884) static void i8035_init (int index, int clock, const void *config, int (*irqcallback)(int)) { - i8039_init(index, clock, config, irqcallback); - R.ram_mask = 0x3F; - R.int_rom_size = 0x400; + generic_init(index, clock, config, irqcallback, 0x400); } #endif -#if (HAS_I8749) -static void i8749_init (int index, int clock, const void *config, int (*irqcallback)(int)) +#if (HAS_I8039 || HAS_I8049 || HAS_I8749 || HAS_N7751) +static void i8039_init (int index, int clock, const void *config, int (*irqcallback)(int)) { - i8039_init(index, clock, config, irqcallback); - - R.ram_mask = 0x7f; - R.int_rom_size = 0x800; + generic_init(index, clock, config, irqcallback, 0x800); } #endif #if (HAS_M58715) static void m58715_init (int index, int clock, const void *config, int (*irqcallback)(int)) { - i8039_init(index, clock, config, irqcallback); + generic_init(index, clock, config, irqcallback, 0x800); R.cpu_feature = FEATURE_M58715; } -#endif /* HAS_M58715 */ +#endif + + /**************************************************************************** * Reset registers to their initial values @@ -830,7 +848,7 @@ static void i8039_set_context (void *src) if( src ) { R = *(I8039_Regs*)src; - regPTR = ((M_By) ? 24 : 0); + update_regptr(); R.SP = (R.PSW << 1) & 0x0f; change_pc(R.PC.w.l); } @@ -898,7 +916,24 @@ static void i8039_set_info(UINT32 state, cpuinfo *info) * Generic get_info **************************************************************************/ -void i8039_get_info(UINT32 state, cpuinfo *info) +static ADDRESS_MAP_START(program_10bit, ADDRESS_SPACE_PROGRAM, 8) + AM_RANGE(0x00, 0x3ff) AM_ROM +ADDRESS_MAP_END + +static ADDRESS_MAP_START(program_11bit, ADDRESS_SPACE_PROGRAM, 8) + AM_RANGE(0x00, 0x7ff) AM_ROM +ADDRESS_MAP_END + +static ADDRESS_MAP_START(data_6bit, ADDRESS_SPACE_DATA, 8) + AM_RANGE(0x00, 0x3f) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START(data_7bit, ADDRESS_SPACE_DATA, 8) + AM_RANGE(0x00, 0x7f) AM_RAM +ADDRESS_MAP_END + + +static void generic_get_info(UINT32 state, cpuinfo *info) { switch (state) { @@ -915,10 +950,10 @@ void i8039_get_info(UINT32 state, cpuinfo *info) case CPUINFO_INT_MAX_CYCLES: 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 = 12; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: /*info->i = 10 or 11 or 12;*/ break; case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: 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 = 6 or 7;*/ 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 = 9; break; @@ -951,16 +986,19 @@ void i8039_get_info(UINT32 state, cpuinfo *info) case CPUINFO_PTR_SET_INFO: info->setinfo = i8039_set_info; break; case CPUINFO_PTR_GET_CONTEXT: info->getcontext = i8039_get_context; break; case CPUINFO_PTR_SET_CONTEXT: info->setcontext = i8039_set_context; break; - case CPUINFO_PTR_INIT: info->init = i8039_init; break; + case CPUINFO_PTR_INIT: /*info->init = i8039_init;*/ break; case CPUINFO_PTR_RESET: info->reset = i8039_reset; break; case CPUINFO_PTR_EXIT: info->exit = i8039_exit; break; case CPUINFO_PTR_EXECUTE: info->execute = i8039_execute; break; case CPUINFO_PTR_BURN: info->burn = NULL; break; case CPUINFO_PTR_DISASSEMBLE: info->disassemble = i8039_dasm; break; case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &i8039_ICount; break; + + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: /*info->internal_map8 = address_map_program_10bit;*/ break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: /*info->internal_map8 = address_map_data_7bit;*/ break; /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "I8039"); break; + case CPUINFO_STR_NAME: /*strcpy(info->s, "I8039");*/ break; case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Intel 8039"); break; case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.2"); break; case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; @@ -986,119 +1024,195 @@ void i8039_get_info(UINT32 state, cpuinfo *info) case CPUINFO_STR_REGISTER + I8039_TC: sprintf(info->s, "TC:%02X", R.timer); break; case CPUINFO_STR_REGISTER + I8039_P1: sprintf(info->s, "P1:%02X", R.P1); break; case CPUINFO_STR_REGISTER + I8039_P2: sprintf(info->s, "P2:%02X", R.P2); break; - case CPUINFO_STR_REGISTER + I8039_R0: sprintf(info->s, "R0:%02X", R.RAM[R.regPtr+0]); break; - case CPUINFO_STR_REGISTER + I8039_R1: sprintf(info->s, "R1:%02X", R.RAM[R.regPtr+1]); break; - case CPUINFO_STR_REGISTER + I8039_R2: sprintf(info->s, "R2:%02X", R.RAM[R.regPtr+2]); break; - case CPUINFO_STR_REGISTER + I8039_R3: sprintf(info->s, "R3:%02X", R.RAM[R.regPtr+3]); break; - case CPUINFO_STR_REGISTER + I8039_R4: sprintf(info->s, "R4:%02X", R.RAM[R.regPtr+4]); break; - case CPUINFO_STR_REGISTER + I8039_R5: sprintf(info->s, "R5:%02X", R.RAM[R.regPtr+5]); break; - case CPUINFO_STR_REGISTER + I8039_R6: sprintf(info->s, "R6:%02X", R.RAM[R.regPtr+6]); break; - case CPUINFO_STR_REGISTER + I8039_R7: sprintf(info->s, "R7:%02X", R.RAM[R.regPtr+7]); break; + case CPUINFO_STR_REGISTER + I8039_R0: sprintf(info->s, "R0:%02X", R0); break; + case CPUINFO_STR_REGISTER + I8039_R1: sprintf(info->s, "R1:%02X", R1); break; + case CPUINFO_STR_REGISTER + I8039_R2: sprintf(info->s, "R2:%02X", R2); break; + case CPUINFO_STR_REGISTER + I8039_R3: sprintf(info->s, "R3:%02X", R3); break; + case CPUINFO_STR_REGISTER + I8039_R4: sprintf(info->s, "R4:%02X", R4); break; + case CPUINFO_STR_REGISTER + I8039_R5: sprintf(info->s, "R5:%02X", R5); break; + case CPUINFO_STR_REGISTER + I8039_R6: sprintf(info->s, "R6:%02X", R6); break; + case CPUINFO_STR_REGISTER + I8039_R7: sprintf(info->s, "R7:%02X", R7); break; case CPUINFO_STR_REGISTER + I8039_EA: sprintf(info->s, "EA:%02X", R.EA); break; } } -#if (HAS_I8035) /************************************************************************** * CPU-specific get_info/set_info **************************************************************************/ + +#if (HAS_I8035) void i8035_get_info(UINT32 state, cpuinfo *info) { switch (state) { - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "I8035"); break; - case CPUINFO_PTR_INIT: info->init = i8035_init; break; - - default: i8039_get_info(state, info); break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 12; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_6bit; break; + case CPUINFO_PTR_INIT: info->init = i8035_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8035"); break; + default: generic_get_info(state, info); break; } } #endif +#if (HAS_I8041) +void i8041_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_10bit; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_6bit; break; + case CPUINFO_PTR_INIT: info->init = i8035_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8041"); break; + default: generic_get_info(state, info); break; + } +} +#endif #if (HAS_I8048) -/************************************************************************** - * CPU-specific get_info/set_info - **************************************************************************/ void i8048_get_info(UINT32 state, cpuinfo *info) { switch (state) { - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "I8048"); break; - case CPUINFO_PTR_INIT: info->init = i8035_init; break; - - default: i8039_get_info(state, info); break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_10bit; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_6bit; break; + case CPUINFO_PTR_INIT: info->init = i8035_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8048"); break; + default: generic_get_info(state, info); break; } } #endif -#if (HAS_I8749) -/************************************************************************** - * CPU-specific get_info/set_info - **************************************************************************/ -void i8749_get_info(UINT32 state, cpuinfo *info) +#if (HAS_I8648) +void i8648_get_info(UINT32 state, cpuinfo *info) { switch (state) { - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "I8749"); break; - case CPUINFO_PTR_INIT: info->init = i8749_init; break; - - default: i8039_get_info(state, info); break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_10bit; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_6bit; break; + case CPUINFO_PTR_INIT: info->init = i8035_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8648"); break; + default: generic_get_info(state, info); break; } } #endif -#if (HAS_N7751) -/************************************************************************** - * CPU-specific get_info/set_info - **************************************************************************/ -void n7751_get_info(UINT32 state, cpuinfo *info) +#if (HAS_I8748) +void i8748_get_info(UINT32 state, cpuinfo *info) { switch (state) { - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "N7751"); break; - case CPUINFO_PTR_INIT: info->init = i8039_init; break; - - default: i8039_get_info(state, info); break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_10bit; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_6bit; break; + case CPUINFO_PTR_INIT: info->init = i8035_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8748"); break; + default: generic_get_info(state, info); break; } } #endif #if (HAS_MB8884) -/************************************************************************** - * CPU-specific get_info/set_info - **************************************************************************/ void mb8884_get_info(UINT32 state, cpuinfo *info) { switch (state) { - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "MB8884"); break; - case CPUINFO_PTR_INIT: info->init = i8035_init; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_10bit; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_6bit; break; + case CPUINFO_PTR_INIT: info->init = i8035_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "MB8884"); break; + default: generic_get_info(state, info); break; + } +} +#endif - default: i8039_get_info(state, info); break; +#if (HAS_N7751) +void n7751_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_10bit; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_6bit; break; + case CPUINFO_PTR_INIT: info->init = i8035_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "N7751"); break; + default: generic_get_info(state, info); break; + } +} +#endif + + + +#if (HAS_I8039) +void i8039_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 12; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_7bit; break; + case CPUINFO_PTR_INIT: info->init = i8039_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8039"); break; + default: generic_get_info(state, info); break; + } +} +#endif + +#if (HAS_I8049) +void i8049_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 11; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_11bit; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_7bit; break; + case CPUINFO_PTR_INIT: info->init = i8039_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8049"); break; + default: generic_get_info(state, info); break; + } +} +#endif + +#if (HAS_I8749) +void i8749_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 11; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_program_11bit; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_7bit; break; + case CPUINFO_PTR_INIT: info->init = i8039_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8749"); break; + default: generic_get_info(state, info); break; } } #endif #if (HAS_M58715) -/************************************************************************** - * CPU-specific get_info/set_info - **************************************************************************/ void m58715_get_info(UINT32 state, cpuinfo *info) { switch (state) { - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "M58715"); break; - case CPUINFO_PTR_INIT: info->init = m58715_init; break; - - default: i8039_get_info(state, info); break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 12; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = address_map_data_7bit; break; + case CPUINFO_PTR_INIT: info->init = m58715_init; break; + case CPUINFO_STR_NAME: strcpy(info->s, "M58715"); break; + default: generic_get_info(state, info); break; } } #endif diff --git a/src/emu/cpuexec.h b/src/emu/cpuexec.h index f51a0cd2b56..cdb5a21019e 100644 --- a/src/emu/cpuexec.h +++ b/src/emu/cpuexec.h @@ -77,11 +77,15 @@ enum _cpu_type CPU_V60, CPU_V70, CPU_I8035, - CPU_I8039, + CPU_I8041, CPU_I8048, - CPU_I8749, - CPU_N7751, + CPU_I8648, + CPU_I8748, CPU_MB8884, + CPU_N7751, + CPU_I8039, + CPU_I8049, + CPU_I8749, CPU_M58715, CPU_I8X41, CPU_I8051, diff --git a/src/emu/cpuintrf.c b/src/emu/cpuintrf.c index 574ee4be21f..efe5daa4e7b 100644 --- a/src/emu/cpuintrf.c +++ b/src/emu/cpuintrf.c @@ -50,11 +50,15 @@ void v35_get_info(UINT32 state, cpuinfo *info); void v60_get_info(UINT32 state, cpuinfo *info); void v70_get_info(UINT32 state, cpuinfo *info); void i8035_get_info(UINT32 state, cpuinfo *info); -void i8039_get_info(UINT32 state, cpuinfo *info); +void i8041_get_info(UINT32 state, cpuinfo *info); void i8048_get_info(UINT32 state, cpuinfo *info); +void i8648_get_info(UINT32 state, cpuinfo *info); +void i8748_get_info(UINT32 state, cpuinfo *info); +void mb8884_get_info(UINT32 state, cpuinfo *info); +void i8039_get_info(UINT32 state, cpuinfo *info); +void i8049_get_info(UINT32 state, cpuinfo *info); void i8749_get_info(UINT32 state, cpuinfo *info); void n7751_get_info(UINT32 state, cpuinfo *info); -void mb8884_get_info(UINT32 state, cpuinfo *info); void m58715_get_info(UINT32 state, cpuinfo *info); void i8x41_get_info(UINT32 state, cpuinfo *info); void i8051_get_info(UINT32 state, cpuinfo *info); @@ -377,20 +381,32 @@ static const struct #if (HAS_I8035) { CPU_I8035, i8035_get_info }, #endif -#if (HAS_I8039) - { CPU_I8039, i8039_get_info }, +#if (HAS_I8041) + { CPU_I8041, i8041_get_info }, #endif #if (HAS_I8048) { CPU_I8048, i8048_get_info }, #endif -#if (HAS_I8749) - { CPU_I8749, i8749_get_info }, +#if (HAS_I8648) + { CPU_I8648, i8648_get_info }, +#endif +#if (HAS_I8748) + { CPU_I8748, i8748_get_info }, +#endif +#if (HAS_MB8884) + { CPU_MB8884, mb8884_get_info }, #endif #if (HAS_N7751) { CPU_N7751, n7751_get_info }, #endif -#if (HAS_MB8884) - { CPU_MB8884, mb8884_get_info }, +#if (HAS_I8039) + { CPU_I8039, i8039_get_info }, +#endif +#if (HAS_I8049) + { CPU_I8049, i8049_get_info }, +#endif +#if (HAS_I8749) + { CPU_I8749, i8749_get_info }, #endif #if (HAS_M58715) { CPU_M58715, m58715_get_info }, diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h index ba1484d8955..a7bc5f721f4 100644 --- a/src/emu/drivers/xtal.h +++ b/src/emu/drivers/xtal.h @@ -54,6 +54,7 @@ enum XTAL_3_6864MHz = 3686400, /* CPS3 */ XTAL_4MHz = 4000000, XTAL_4_224MHz = 4224000, /* Used to drive OKI M6295 chips, usually with /4 divider */ + XTAL_4_41MHz = 4410000, /* Pioneer PR-8210 ldplayer */ XTAL_4_43361MHz = 4433610, /* Cidelsa Draco */ XTAL_4_433619MHz = 4433619, /* PAL color subcarrier */ XTAL_4_9152MHz = 4915200, diff --git a/src/ldplayer/ldplayer.c b/src/ldplayer/ldplayer.c index 88528b23061..ecc0867dc6f 100644 --- a/src/ldplayer/ldplayer.c +++ b/src/ldplayer/ldplayer.c @@ -11,10 +11,15 @@ #include "driver.h" #include "uimenu.h" +#include "cpu/i8039/i8039.h" #include "machine/laserdsc.h" #include +#define TEST_PR8210_ROM 0 + + + /************************************* * * Constants @@ -67,6 +72,16 @@ static UINT8 pr8210_command_buffer[10]; static void (*execute_command)(const device_config *laserdisc, int command); +#if TEST_PR8210_ROM + +static UINT8 pia[0x100]; +static UINT8 pr8210_porta; +static UINT8 pr8210_portb; +static UINT8 pr8210_pia_porta; +static UINT8 pr8210_pia_portb; + +#endif + /************************************* @@ -230,7 +245,11 @@ static TIMER_CALLBACK( pr8210_bit_callback ) else if (bitsleft == 0 && pr8210_command_buffer_in != pr8210_command_buffer_out) { data = pr8210_command_buffer[pr8210_command_buffer_out++ % ARRAY_LENGTH(pr8210_command_buffer)]; +#if TEST_PR8210_ROM + pr8210_pia_porta = BITSWAP8(data, 0,1,2,3,4,5,6,7); +#else bitsleft = 12; +#endif } timer_adjust_oneshot(pr8210_bit_timer, duration, (bitsleft << 16) | data); } @@ -446,6 +465,175 @@ INPUT_PORTS_END +/************************************* + * + * Test PR-8210 ROM emulation + * + *************************************/ + +#if TEST_PR8210_ROM + +static READ8_HANDLER( pr8210_pia_r ) +{ + UINT8 result = pia[offset]; + switch (offset) + { + case 0xa0: +// printf("%03X:pia_r(%02X) = %02X\n", activecpu_get_pc(), offset, pr8210_pia_porta); + result = pr8210_pia_porta; + pr8210_pia_porta = 0; + break; + + default: + printf("%03X:pia_r(%02X)\n", activecpu_get_pc(), offset); + break; + } + return result; +} + +static WRITE8_HANDLER( pr8210_pia_w ) +{ + /* + $22-26 (R) = read and copied to memory $23-27 + $23 (R) = something compared against $F4 + $22-26 (W) = SRCH. text + $27-2B (W) = FRAME/CHAP. text + $2C-30 (W) = frame or chapter number + $40 (W) = $CF at initialization, tracked by ($78) + $60 (W) = port B output, tracked by ($77) + $80 = n/c + $40 = (out) LED3 + $20 = (out) LED2 + $10 = (out) LED1 + 123 -> LHL = Play + -> HLL = Slow fwd + -> LLL = Slow rev + -> HHL = Still + -> LLH = Pause + -> HHH = all off + $08 = (out) CAV LED + $04 = (out) CLV LED + $02 = (out) A2 LED/AUDIO 2 + $01 = (out) A1 LED/AUDIO 1 + $80 (W) = 0 or 1 + $A0 (R) = port A input + $C0 (R) = stored to ($2E) + $E0 (R) = stored to ($2F) + */ + if (pia[offset] != data) + { + switch (offset) + { + case 0x60: + printf("%03X:pia_w(%02X) = %02X (PORT B LEDS:", activecpu_get_pc(), offset, data); + if (!(data & 0x01)) printf(" AUDIO1"); + if (!(data & 0x02)) printf(" AUDIO2"); + if (!(data & 0x04)) printf(" CLV"); + if (!(data & 0x08)) printf(" CAV"); + printf(" LED123=%c%c%c", (data & 0x10) ? 'H' : 'L', (data & 0x20) ? 'H' : 'L', (data & 0x40) ? 'H' : 'L'); + if (!(data & 0x80)) printf(" ???"); + printf(")\n"); + pr8210_pia_portb = data; + break; + + default: + printf("%03X:pia_w(%02X) = %02X\n", activecpu_get_pc(), offset, data); + break; + } + pia[offset] = data; + } +} + +static READ8_HANDLER( pr8210_bus_r ) +{ + /* + $80 = n/c + $40 = (in) slide pot interrupt source (slider position limit detector, inside and outside) + $20 = n/c + $10 = (in) /FOCUS LOCK + $08 = (in) /SPDL LOCK + $04 = (in) SIZE 8/12 + $02 = (in) FG via op-amp (spindle motor stop detector) + $01 = (in) SLOW TIMER OUT + */ + offs_t pc = activecpu_get_pc(); + if (pc != 0x11c) + printf("%03X:bus_r\n", pc); + + /* loop at beginning waits for $40=0, $02=1 */ + return 0xff & ~0x40 & ~0x04; +} + +static WRITE8_HANDLER( pr8210_porta_w ) +{ + /* + $80 = (out) SCAN C (F/R) + $40 = (out) AUDIO SQ + $20 = (out) VIDEO SQ + $10 = (out) /SPDL ON + $08 = (out) /FOCUS ON + $04 = (out) SCAN B (L/H) + $02 = (out) SCAN A (/SCAN) + $01 = (out) JUMP TRG (jump back trigger, clock on high->low) + */ + if (data != pr8210_porta) + { + printf("%03X:porta_w = %02X", activecpu_get_pc(), data); + if (!(data & 0x01)) printf(" JUMPTRG"); + if (!(data & 0x02)) + { + printf(" SCAN:%c:%c", (data & 0x80) ? 'F' : 'R', (data & 0x04) ? 'L' : 'H'); + } + if (!(data & 0x08)) printf(" /FOCUSON"); + if (!(data & 0x10)) printf(" /SPDLON"); + if (data & 0x20) printf(" VIDEOSQ"); + if (data & 0x40) printf(" AUDIOSQ"); + printf("\n"); + pr8210_porta = data; + } +} + +static WRITE8_HANDLER( pr8210_portb_w ) +{ + /* + $80 = (out) /CS on PIA + $40 = (out) 0 to self-generate IRQ + $20 = (out) SLOW TRG + $10 = (out) STANDBY LED + $08 = (out) TP2 + $04 = (out) TP1 + $02 = (out) ??? + $01 = (out) LASER ON + */ + cputag_set_input_line(machine, "pr8210", 0, (data & 0x40) ? CLEAR_LINE : ASSERT_LINE); + if ((data & 0x7f) != (pr8210_portb & 0x7f)) + { + printf("%03X:portb_w = %02X", activecpu_get_pc(), data); + if (!(data & 0x01)) printf(" LASERON"); + if (!(data & 0x02)) printf(" ???"); + if (!(data & 0x04)) printf(" TP1"); + if (!(data & 0x08)) printf(" TP2"); + if (!(data & 0x10)) printf(" STANDBYLED"); + if (!(data & 0x20)) printf(" SLOWTRG"); + if (!(data & 0x40)) printf(" IRQGEN"); +// if (data & 0x80) printf(" PIASEL"); + printf("\n"); + pr8210_portb = data; + } +} + + +static ADDRESS_MAP_START( pr8210_portmap, ADDRESS_SPACE_IO, 8 ) + AM_RANGE(0x00, 0xff) AM_READWRITE(pr8210_pia_r, pr8210_pia_w) + AM_RANGE(I8039_bus, I8039_bus) AM_READ(pr8210_bus_r) + AM_RANGE(I8039_p1, I8039_p1) AM_WRITE(pr8210_porta_w) + AM_RANGE(I8039_p2, I8039_p2) AM_WRITE(pr8210_portb_w) +ADDRESS_MAP_END + +#endif + + + /************************************* * * Machine drivers @@ -484,6 +672,11 @@ static MACHINE_DRIVER_START( pr8210 ) MDRV_MACHINE_START(pr8210) MDRV_MACHINE_RESET(pr8210) MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210) + +#if TEST_PR8210_ROM + MDRV_CPU_ADD("pr8210", I8049, XTAL_4_41MHz) + MDRV_CPU_IO_MAP(pr8210_portmap,0) +#endif MACHINE_DRIVER_END @@ -501,6 +694,11 @@ ROM_END ROM_START( pr8210 ) DISK_REGION( "laserdisc" ) + +#if TEST_PR8210_ROM + ROM_REGION( 0x800, "pr8210", 0 ) + ROM_LOAD( "pr-8210_mcu_ud6005a.bin", 0x000, 0x800, CRC(120fa83b) SHA1(b514326ca1f52d6d89056868f9d17eabd4e3f31d) ) +#endif ROM_END diff --git a/src/ldplayer/ldplayer.mak b/src/ldplayer/ldplayer.mak index c95644e5f88..b388a60e978 100644 --- a/src/ldplayer/ldplayer.mak +++ b/src/ldplayer/ldplayer.mak @@ -22,6 +22,8 @@ OBJDIRS += \ # specify required CPU cores (none) #------------------------------------------------- +CPUS += I8049 + #------------------------------------------------- diff --git a/src/mame/audio/segag80r.c b/src/mame/audio/segag80r.c index 14efd205eae..0b7969bdae0 100644 --- a/src/mame/audio/segag80r.c +++ b/src/mame/audio/segag80r.c @@ -799,10 +799,6 @@ static const tms36xx_interface monsterb_tms3617_interface = * *************************************/ -static ADDRESS_MAP_START( monsterb_7751_map, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x03ff) AM_ROM -ADDRESS_MAP_END - static ADDRESS_MAP_START( monsterb_7751_portmap, ADDRESS_SPACE_IO, 8 ) AM_RANGE(I8039_t1, I8039_t1) AM_READ(n7751_t1_r) AM_RANGE(I8039_p2, I8039_p2) AM_READ(n7751_command_r) @@ -839,7 +835,6 @@ MACHINE_DRIVER_START( monsterb_sound_board ) /* basic machine hardware */ MDRV_CPU_ADD("audio", N7751, 6000000) - MDRV_CPU_PROGRAM_MAP(monsterb_7751_map,0) MDRV_CPU_IO_MAP(monsterb_7751_portmap,0) /* sound hardware */ diff --git a/src/mame/drivers/chinagat.c b/src/mame/drivers/chinagat.c index 23760f07581..ffa8786dab1 100644 --- a/src/mame/drivers/chinagat.c +++ b/src/mame/drivers/chinagat.c @@ -549,7 +549,7 @@ static MACHINE_DRIVER_START( saiyugb1 ) MDRV_CPU_ADD("audio", Z80, 3579545) /* 3.579545 MHz oscillator */ MDRV_CPU_PROGRAM_MAP(saiyugb1_sound_map,0) - MDRV_CPU_ADD("mcu", I8048,9263750/3) /* 3.087916 MHz (9.263750 MHz oscillator) */ + MDRV_CPU_ADD("mcu", I8048, 9263750) /* 9.263750 MHz oscillator, divided by 3*5 internally */ MDRV_CPU_PROGRAM_MAP(i8748_map,0) MDRV_CPU_IO_MAP(i8748_portmap,0) diff --git a/src/mame/drivers/segas16a.c b/src/mame/drivers/segas16a.c index 7457bee2f3e..a6bc9084668 100644 --- a/src/mame/drivers/segas16a.c +++ b/src/mame/drivers/segas16a.c @@ -848,11 +848,6 @@ ADDRESS_MAP_END * *************************************/ -static ADDRESS_MAP_START( n7751_map, ADDRESS_SPACE_PROGRAM, 8 ) - ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x0000, 0x03ff) AM_ROM -ADDRESS_MAP_END - static ADDRESS_MAP_START( n7751_portmap, ADDRESS_SPACE_IO, 8 ) AM_RANGE(I8039_bus,I8039_bus) AM_READ(n7751_rom_r) AM_RANGE(I8039_t1, I8039_t1) AM_READ(n7751_t1_r) @@ -1780,7 +1775,6 @@ static MACHINE_DRIVER_START( system16a ) MDRV_CPU_IO_MAP(sound_portmap,0) MDRV_CPU_ADD("n7751", N7751, 6000000) - MDRV_CPU_PROGRAM_MAP(n7751_map,0) MDRV_CPU_IO_MAP(n7751_portmap,0) MDRV_MACHINE_RESET(system16a) diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 51fa7f2b4de..4f7b0c6560b 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -68,11 +68,15 @@ CPUS += V35 CPUS += V60 CPUS += V70 CPUS += I8035 -CPUS += I8039 +CPUS += I8041 CPUS += I8048 +CPUS += I8648 +CPUS += I8748 +CPUS += MB8884 +CPUS += I8039 +CPUS += I8049 CPUS += I8749 CPUS += N7751 -CPUS += MB8884 CPUS += M58715 CPUS += I8X41 CPUS += I8051