Big H8 update

H8:
- Added support for 8-bit H8 family MCUs, starting with the H8/3344
- Pointer-ified all H8 cores
- Some cleanup and renames toward additional future work

System 23:
- Added extremely preliminary support for I/O boards with the H8/3344
- Added new game: Motocross Go! (MG3 Ver. A) [credit Guru]
This commit is contained in:
R. Belmont 2008-11-19 03:29:10 +00:00
parent 13bd16a090
commit 6c1655976f
23 changed files with 5304 additions and 4471 deletions

6
.gitattributes vendored
View File

@ -113,9 +113,11 @@ src/emu/cpu/h6280/h6280.c svneol=native#text/plain
src/emu/cpu/h6280/h6280.h svneol=native#text/plain
src/emu/cpu/h6280/h6280ops.h svneol=native#text/plain
src/emu/cpu/h6280/tblh6280.c svneol=native#text/plain
src/emu/cpu/h83002/h83002.c svneol=native#text/plain
src/emu/cpu/h83002/h83002.h svneol=native#text/plain
src/emu/cpu/h83002/h8.h svneol=native#text/plain
src/emu/cpu/h83002/h8_16.c svneol=native#text/plain
src/emu/cpu/h83002/h8_8.c svneol=native#text/plain
src/emu/cpu/h83002/h8disasm.c svneol=native#text/plain
src/emu/cpu/h83002/h8ops.h svneol=native#text/plain
src/emu/cpu/h83002/h8periph.c svneol=native#text/plain
src/emu/cpu/h83002/h8priv.h svneol=native#text/plain
src/emu/cpu/hd6309/6309dasm.c svneol=native#text/plain

View File

@ -470,21 +470,21 @@ $(CPUOBJ)/hd6309/hd6309.o: $(CPUSRC)/hd6309/hd6309.c \
$(CPUSRC)/hd6309/6309tbl.c
#-------------------------------------------------
# Hitachi H8/3002
# Hitachi H8/30xx (16/32-bit H8/3xx series)
#-------------------------------------------------
CPUDEFS += -DHAS_H83002=$(if $(filter H83002,$(CPUS)),1,0)
ifneq ($(filter H83002,$(CPUS)),)
OBJDIRS += $(CPUOBJ)/h83002
CPUOBJS += $(CPUOBJ)/h83002/h83002.o $(CPUOBJ)/h83002/h8periph.o
CPUOBJS += $(CPUOBJ)/h83002/h8_16.o $(CPUOBJ)/h83002/h8periph.o
DBGOBJS += $(CPUOBJ)/h83002/h8disasm.o
endif
$(CPUOBJ)/h83002/h83002.o: $(CPUSRC)/h83002/h83002.c \
$(CPUSRC)/h83002/h83002.h \
$(CPUOBJ)/h83002/h8_16.o: $(CPUSRC)/h83002/h8_16.c \
$(CPUSRC)/h83002/h8.h \
$(CPUSRC)/h83002/h8ops.h \
$(CPUSRC)/h83002/h8priv.h
$(CPUOBJ)/h83002/h8disasm.o: $(CPUSRC)/h83002/h8disasm.c
@ -493,6 +493,28 @@ $(CPUOBJ)/h83002/h8periph.o: $(CPUSRC)/h83002/h8periph.c \
$(CPUSRC)/h83002/h8priv.h
#-------------------------------------------------
# Hitachi H8/3344 (8/16-bit H8/3xx series)
#-------------------------------------------------
CPUDEFS += -DHAS_H83344=$(if $(filter H83344,$(CPUS)),1,0)
ifneq ($(filter H83344,$(CPUS)),)
OBJDIRS += $(CPUOBJ)/h83002
CPUOBJS += $(CPUOBJ)/h83002/h8_8.o $(CPUOBJ)/h83002/h8periph.o
DBGOBJS += $(CPUOBJ)/h83002/h8disasm.o
endif
$(CPUOBJ)/h83002/h8_8.o: $(CPUSRC)/h83002/h8_8.c \
$(CPUSRC)/h83002/h8.h \
$(CPUSRC)/h83002/h8ops.h \
$(CPUSRC)/h83002/h8priv.h
$(CPUOBJ)/h83002/h8disasm.o: $(CPUSRC)/h83002/h8disasm.c
$(CPUOBJ)/h83002/h8periph.o: $(CPUSRC)/h83002/h8periph.c \
$(CPUSRC)/h83002/h8priv.h
#-------------------------------------------------
# Hitachi SH1/SH2
#-------------------------------------------------

View File

@ -35,7 +35,7 @@ enum
H8_CCR
};
// external interrupt lines
// external input lines
enum
{
H8_IRQ0 = 0,
@ -43,20 +43,33 @@ enum
H8_IRQ2,
H8_IRQ3,
H8_IRQ4,
H8_IRQ5
H8_IRQ5,
H8_IRQ6, // IRQs 6+ only available on 8-bit H8/3xx
H8_IRQ7,
H8_NMI,
H8_METRO_TIMER_HACK, // as described. this needs to be fixed.
H8_SCI_0_RX, // incoming character on SCI 0
H8_SCI_1_RX, // incoming character on SCI 1
};
// I/O ports
enum
{
// digital I/O ports
H8_PORT4 = 0, // 0
H8_PORT6, // 1
H8_PORT7, // 2
H8_PORT8, // 3
H8_PORT9, // 4
H8_PORTA, // 5
H8_PORTB, // 6
// ports 4-B are valid on 16-bit H8/3xx, ports 1-9 on 8-bit H8/3xx
H8_PORT_1 = 0, // 0
H8_PORT_2, // 1
H8_PORT_3, // 2
H8_PORT_4, // 3
H8_PORT_5, // 4
H8_PORT_6, // 5
H8_PORT_7, // 6
H8_PORT_8, // 7
H8_PORT_9, // 8
H8_PORT_A, // 9
H8_PORT_B, // A
// analog inputs
H8_ADC_0_H = 0x10,
@ -69,12 +82,12 @@ enum
H8_ADC_3_L,
// serial ports
H8_SERIAL_A = 0x20,
H8_SERIAL_B
H8_SERIAL_0 = 0x20,
H8_SERIAL_1,
};
CPU_GET_INFO( h8_300 );
CPU_GET_INFO( h8_3002 );
void h8_3002_InterruptRequest(UINT8 source);
CPU_GET_INFO( h8_3344 );
#endif /* __H83002_H__ */

File diff suppressed because it is too large Load Diff

653
src/emu/cpu/h83002/h8_16.c Normal file
View File

@ -0,0 +1,653 @@
/***************************************************************************
h8_16.c: Hitachi H8/3xx series 16/32-bit microcontroller emulator
Original by The_Author & DynaChicken for the ZiNc emulator.
MAME changes by R. Belmont, Luca Elia, and Tomasz Slanina.
TS 20060412 Added exts.l, sub.l, divxs.w (buggy), jsr @reg, rotxl.l reg, mov.l @(adr, reg), reg
LE 20070903 Added divxu.b shal.l extu.w dec.l #Imm,Rd subx.b
LE 20080202 Separated 3002/3044/3007, Added or.l shal.l rotl.l not.l neg.l exts.w
sub/or/xor.l #Imm:32,ERd bset/bnot/bclr.b Rn,@ERd bst/bist.b #Imm:3,@ERd bnot.b #Imm:3,@ERd
****************************************************************************/
#include "debugger.h"
#include "h8.h"
#include "h8priv.h"
#define H8_SP (7)
#define h8_mem_read8(x) program_read_byte_16be(x)
#define h8_mem_read16(x) program_read_word_16be(x)
#define h8_mem_write8(x, y) program_write_byte_16be(x, y)
#define h8_mem_write16(x, y) program_write_word_16be(x, y)
#define h8_readop16(x) program_decrypted_read_word(x)
// timing macros
// note: we assume a system 12 - type setup where external access is 3+1 states
// timing will be off somewhat for other configurations.
#define H8_IFETCH_TIMING(x) h8->cyccnt -= (x) * 4;
#define H8_BRANCH_TIMING(x) h8->cyccnt -= (x) * 4;
#define H8_STACK_TIMING(x) h8->cyccnt -= (x) * 4;
#define H8_BYTE_TIMING(x, adr) if (address24 >= 0xffff10) h8->cyccnt -= (x) * 3; else h8->cyccnt -= (x) * 4;
#define H8_WORD_TIMING(x, adr) if (address24 >= 0xffff10) h8->cyccnt -= (x) * 3; else h8->cyccnt -= (x) * 4;
#define H8_IOP_TIMING(x) h8->cyccnt -= (x);
INLINE UINT32 h8_mem_read32(offs_t address)
{
UINT32 result = program_read_word_16be(address) << 16;
return result | program_read_word_16be(address + 2);
}
INLINE void h8_mem_write32(offs_t address, UINT32 data)
{
program_write_word_16be(address, data >> 16);
program_write_word_16be(address + 2, data);
}
static void *token;
static void h8_check_irqs(h83xx_state *h8);
/* implementation */
extern offs_t h8_disasm(char *output, offs_t address, const UINT8 *oprom, const UINT8 *opram, UINT32 addr_mask);
// disassembly hook for varients with 24-bit address bus (e.g. H8/3044)
static CPU_DISASSEMBLE(h8_24)
{
return h8_disasm(buffer, pc, oprom, opram, 0xffffff);
}
// disassembly hook for full 32-bit address bus
static CPU_DISASSEMBLE(h8_32)
{
return h8_disasm(buffer, pc, oprom, opram, 0xffffffff);
}
void h8_3002_InterruptRequest(h83xx_state *h8, UINT8 source)
{
if(source>31)
{
h8->h8_IRQrequestH |= (1<<(source-32));
}
else
{
h8->h8_IRQrequestL |= (1<<source);
}
}
static UINT8 h8_get_ccr(h83xx_state *h8)
{
h8->ccr = 0;
if(h8->h8nflag)h8->ccr |= NFLAG;
if(h8->h8zflag)h8->ccr |= ZFLAG;
if(h8->h8vflag)h8->ccr |= VFLAG;
if(h8->h8cflag)h8->ccr |= CFLAG;
if(h8->h8uflag)h8->ccr |= UFLAG;
if(h8->h8hflag)h8->ccr |= HFLAG;
if(h8->h8uiflag)h8->ccr |= UIFLAG;
if(h8->h8iflag)h8->ccr |= IFLAG;
return h8->ccr;
}
static char *h8_get_ccr_str(h83xx_state *h8)
{
static char res[8];
memset(res, 0, 8);
if(h8->h8iflag) strcat(res, "I"); else strcat(res, "i");
if(h8->h8uiflag)strcat(res, "U"); else strcat(res, "u");
if(h8->h8hflag) strcat(res, "H"); else strcat(res, "h");
if(h8->h8uflag) strcat(res, "U"); else strcat(res, "u");
if(h8->h8nflag) strcat(res, "N"); else strcat(res, "n");
if(h8->h8zflag) strcat(res, "Z"); else strcat(res, "z");
if(h8->h8vflag) strcat(res, "V"); else strcat(res, "v");
if(h8->h8cflag) strcat(res, "C"); else strcat(res, "c");
return res;
}
static void h8_set_ccr(h83xx_state *h8, UINT8 data)
{
h8->ccr = data;
h8->h8nflag = 0;
h8->h8zflag = 0;
h8->h8vflag = 0;
h8->h8cflag = 0;
h8->h8hflag = 0;
h8->h8iflag = 0;
h8->h8uflag = 0;
h8->h8uiflag = 0;
if(h8->ccr & NFLAG) h8->h8nflag = 1;
if(h8->ccr & ZFLAG) h8->h8zflag = 1;
if(h8->ccr & VFLAG) h8->h8vflag = 1;
if(h8->ccr & CFLAG) h8->h8cflag = 1;
if(h8->ccr & HFLAG) h8->h8hflag = 1;
if(h8->ccr & UFLAG) h8->h8uflag = 1;
if(h8->ccr & UIFLAG) h8->h8uiflag = 1;
if(h8->ccr & IFLAG) h8->h8iflag = 1;
h8_check_irqs(h8);
}
static INT16 h8_getreg16(h83xx_state *h8, UINT8 reg)
{
if(reg > 7)
{
return h8->regs[reg-8]>>16;
}
else
{
return h8->regs[reg];
}
}
static void h8_setreg16(h83xx_state *h8, UINT8 reg, UINT16 data)
{
if(reg > 7)
{
h8->regs[reg-8] &= 0xffff;
h8->regs[reg-8] |= data<<16;
}
else
{
h8->regs[reg] &= 0xffff0000;
h8->regs[reg] |= data;
}
}
static UINT8 h8_getreg8(h83xx_state *h8, UINT8 reg)
{
if(reg > 7)
{
return h8->regs[reg-8];
}
else
{
return h8->regs[reg]>>8;
}
}
static void h8_setreg8(h83xx_state *h8, UINT8 reg, UINT8 data)
{
if(reg > 7)
{
h8->regs[reg-8] &= 0xffffff00;
h8->regs[reg-8] |= data;
}
else
{
h8->regs[reg] &= 0xffff00ff;
h8->regs[reg] |= data<<8;
}
}
static UINT32 h8_getreg32(h83xx_state *h8, UINT8 reg)
{
return h8->regs[reg];
}
static void h8_setreg32(h83xx_state *h8, UINT8 reg, UINT32 data)
{
h8->regs[reg] = data;
}
static STATE_POSTLOAD( h8_onstateload )
{
h83xx_state *h8 = (h83xx_state *)param;
h8_set_ccr(h8, h8->ccr);
}
static CPU_INIT(h8)
{
h83xx_state *h8 = device->token;
token = device->token;
h8->h8iflag = 1;
h8->irq_cb = irqcallback;
h8->device = device;
h8->h8300_mode = 0;
state_save_register_item("H8/3002", device->tag, 0, h8->h8err);
state_save_register_item_array("H8/3002", device->tag, 0, h8->regs);
state_save_register_item("H8/3002", device->tag, 0, h8->pc);
state_save_register_item("H8/3002", device->tag, 0, h8->ppc);
state_save_register_item("H8/3002", device->tag, 0, h8->h8_IRQrequestH);
state_save_register_item("H8/3002", device->tag, 0, h8->h8_IRQrequestL);
state_save_register_item("H8/3002", device->tag, 0, h8->ccr);
state_save_register_item("H8/3002", device->tag, 0, h8->h8300_mode);
state_save_register_item_array("H8/3002", device->tag, 0, h8->per_regs);
state_save_register_item("H8/3002", device->tag, 0, h8->h8TSTR);
state_save_register_item_array("H8/3002", device->tag, 0, h8->h8TCNT);
state_save_register_postload(device->machine, h8_onstateload, h8);
h8_itu_init(h8);
}
static CPU_INIT(h8_3007)
{
h83xx_state *h8 = device->token;
token = device->token;
CPU_INIT_CALL(h8);
h8_3007_itu_init(h8);
}
static CPU_RESET(h8)
{
h83xx_state *h8 = device->token;
h8->h8err = 0;
h8->pc = h8_mem_read32(0) & 0xffffff;
change_pc(h8->pc);
// disable timers
h8->h8TSTR = 0;
h8_itu_reset(h8);
}
static void h8_GenException(h83xx_state *h8, UINT8 vectornr)
{
// push PC on stack
// extended mode stack push!
h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-4);
h8_mem_write32(h8_getreg32(h8, H8_SP), h8->pc);
// push ccr
h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-2);
h8_mem_write16(h8_getreg32(h8, H8_SP), h8_get_ccr(h8));
// generate address from vector
h8_set_ccr(h8, h8_get_ccr(h8) | 0x80);
if (h8->h8uiflag == 0)
h8_set_ccr(h8, h8_get_ccr(h8) | 0x40);
h8->pc = h8_mem_read32(vectornr * 4) & 0xffffff;
change_pc(h8->pc);
// I couldn't find timing info for exceptions, so this is a guess (based on JSR/BSR)
H8_IFETCH_TIMING(2);
H8_STACK_TIMING(2);
}
static int h8_get_priority(h83xx_state *h8, UINT8 bit)
{
int res = 0;
switch(bit)
{
case 12: // IRQ0
if (h8->per_regs[0xF8]&0x80) res = 1; break;
case 13: // IRQ1
if (h8->per_regs[0xF8]&0x40) res = 1; break;
case 14: // IRQ2
case 15: // IRQ3
if (h8->per_regs[0xF8]&0x20) res = 1; break;
case 16: // IRQ4
case 17: // IRQ5
if (h8->per_regs[0xF8]&0x10) res = 1; break;
}
return res;
}
static void h8_check_irqs(h83xx_state *h8)
{
int lv = -1;
if (h8->h8iflag == 0)
{
lv = 0;
}
else
{
if ((h8->per_regs[0xF2]&0x08)/*SYSCR*/ == 0)
{
if (h8->h8uiflag == 0)
lv = 1;
}
}
// any interrupts wanted and can accept ?
if(((h8->h8_IRQrequestH != 0) || (h8->h8_IRQrequestL != 0)) && (lv >= 0))
{
UINT8 bit, source;
// which one ?
for(bit = 0, source = 0xff; source == 0xff && bit < 32; bit++)
{
if( h8->h8_IRQrequestL & (1<<bit) )
{
if (h8_get_priority(h8, bit) >= lv)
{
// mask off
h8->h8_IRQrequestL &= ~(1<<bit);
source = bit;
}
}
}
// which one ?
for(bit = 0; source == 0xff && bit < 32; bit++)
{
if( h8->h8_IRQrequestH & (1<<bit) )
{
if (h8_get_priority(h8, bit + 32) >= lv)
{
// mask off
h8->h8_IRQrequestH &= ~(1<<bit);
source = bit + 32;
}
}
}
// call the MAME callback if it's one of the 6
// external IRQs
if (source >= 12 && source <= 17)
{
(*h8->irq_cb)(h8->device, source - 12 + H8_IRQ0);
}
if (source != 0xff)
h8_GenException(h8, source);
}
}
#define H8_ADDR_MASK 0xffffff
#include "h8ops.h"
// MAME interface stuff
static CPU_GET_CONTEXT( h8 )
{
}
static CPU_SET_CONTEXT( h8 )
{
if (src)
{
token = src;
}
}
static CPU_SET_INFO( h8 )
{
h83xx_state *h8 = device->token;
switch(state) {
case CPUINFO_INT_PC: h8->pc = info->i; change_pc(h8->pc); break;
case CPUINFO_INT_REGISTER + H8_PC: h8->pc = info->i; change_pc(h8->pc); break;
case CPUINFO_INT_REGISTER + H8_CCR: h8_set_ccr(h8, info->i); break;
case CPUINFO_INT_REGISTER + H8_E0: h8->regs[0] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E1: h8->regs[1] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E2: h8->regs[2] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E3: h8->regs[3] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E4: h8->regs[4] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E5: h8->regs[5] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E6: h8->regs[6] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E7: h8->regs[7] = info->i; break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ0: if (info->i) h8_3002_InterruptRequest(h8, 12); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ1: if (info->i) h8_3002_InterruptRequest(h8, 13); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ2: if (info->i) h8_3002_InterruptRequest(h8, 14); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ3: if (info->i) h8_3002_InterruptRequest(h8, 15); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ4: if (info->i) h8_3002_InterruptRequest(h8, 16); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ5: if (info->i) h8_3002_InterruptRequest(h8, 17); break;
case CPUINFO_INT_INPUT_STATE + H8_METRO_TIMER_HACK: if (info->i) h8_3002_InterruptRequest(h8, 24); break;
case CPUINFO_INT_INPUT_STATE + H8_SCI_0_RX: if (info->i) h8_3002_InterruptRequest(h8, 53); break;
case CPUINFO_INT_INPUT_STATE + H8_SCI_1_RX: if (info->i) h8_3002_InterruptRequest(h8, 57); break;
default:
fatalerror("h8_set_info unknown request %x", state);
break;
}
}
static READ16_HANDLER( h8_itu_r )
{
h83xx_state *h8 = (h83xx_state *)space->cpu->token;
if (mem_mask == 0xffff)
{
// 16-bit read
return h8_register_read8(h8, offset*2 + 0xffff10)<<8 | h8_register_read8(h8, (offset*2) + 1 + 0xffff10);
}
else if (mem_mask == 0xff00)
{
return h8_register_read8(h8, offset*2 + 0xffff10)<<8;
}
else if (mem_mask == 0x00ff)
{
return h8_register_read8(h8, (offset*2) + 1 + 0xffff10);
}
return 0;
}
static WRITE16_HANDLER( h8_itu_w )
{
h83xx_state *h8 = (h83xx_state *)space->cpu->token;
if (mem_mask == 0xffff)
{
// 16-bit write
h8_register_write8(h8, offset*2 + 0xffff10, data>>8);
h8_register_write8(h8, (offset*2) + 1 + 0xffff10, data&0xff);
}
else if (mem_mask == 0xff00)
{
h8_register_write8(h8, offset*2 + 0xffff10, data>>8);
}
else if (mem_mask == 0x00ff)
{
h8_register_write8(h8, (offset*2) + 1 + 0xffff10, data&0xff);
}
}
static READ16_HANDLER( h8_3007_itu_r )
{
h83xx_state *h8 = (h83xx_state *)space->cpu->token;
if (mem_mask == 0xffff)
{
// 16-bit read
return h8_3007_register_read8(h8, offset*2 + 0xffff20)<<8 | h8_3007_register_read8(h8, (offset*2) + 1 + 0xffff20);
}
else if (mem_mask == 0xff00)
{
return h8_3007_register_read8(h8, offset*2 + 0xffff20)<<8;
}
else if (mem_mask == 0x00ff)
{
return h8_3007_register_read8(h8, (offset*2) + 1 + 0xffff20);
}
return 0;
}
static WRITE16_HANDLER( h8_3007_itu_w )
{
h83xx_state *h8 = (h83xx_state *)space->cpu->token;
if (mem_mask == 0xffff)
{
// 16-bit write
h8_3007_register_write8(h8, offset*2 + 0xffff20, data>>8);
h8_3007_register_write8(h8, (offset*2) + 1 + 0xffff20, data&0xff);
}
else if (mem_mask == 0xff00)
{
h8_3007_register_write8(h8, offset*2 + 0xffff20, data>>8);
}
else if (mem_mask == 0x00ff)
{
h8_3007_register_write8(h8, (offset*2) + 1 + 0xffff20, data&0xff);
}
}
static READ16_HANDLER( h8_3007_itu1_r )
{
h83xx_state *h8 = (h83xx_state *)space->cpu->token;
if (mem_mask == 0xffff)
{
// 16-bit read
return h8_3007_register1_read8(h8, offset*2 + 0xfee000)<<8 | h8_3007_register1_read8(h8, (offset*2) + 1 + 0xfee000);
}
else if (mem_mask == 0xff00)
{
return h8_3007_register1_read8(h8, offset*2 + 0xfee000)<<8;
}
else if (mem_mask == 0x00ff)
{
return h8_3007_register1_read8(h8, (offset*2) + 1 + 0xfee000);
}
return 0;
}
static WRITE16_HANDLER( h8_3007_itu1_w )
{
h83xx_state *h8 = (h83xx_state *)space->cpu->token;
if (mem_mask == 0xffff)
{
// 16-bit write
h8_3007_register1_write8(h8, offset*2 + 0xfee000, data>>8);
h8_3007_register1_write8(h8, (offset*2) + 1 + 0xfee000, data&0xff);
}
else if (mem_mask == 0xff00)
{
h8_3007_register1_write8(h8, offset*2 + 0xfee000, data>>8);
}
else if (mem_mask == 0x00ff)
{
h8_3007_register1_write8(h8, (offset*2) + 1 + 0xfee000, data&0xff);
}
}
// On-board RAM and peripherals
static ADDRESS_MAP_START( h8_3002_internal_map, ADDRESS_SPACE_PROGRAM, 16 )
// 512B RAM
AM_RANGE(0xfffd10, 0xffff0f) AM_RAM
AM_RANGE(0xffff10, 0xffffff) AM_READWRITE( h8_itu_r, h8_itu_w )
ADDRESS_MAP_END
static ADDRESS_MAP_START( h8_3044_internal_map, ADDRESS_SPACE_PROGRAM, 16 )
// 32k ROM, 2k RAM
AM_RANGE(0xfff710, 0xffff0f) AM_RAM
AM_RANGE(0xffff1c, 0xffffff) AM_READWRITE( h8_itu_r, h8_itu_w )
ADDRESS_MAP_END
static ADDRESS_MAP_START( h8_3007_internal_map, ADDRESS_SPACE_PROGRAM, 16 )
// ROM-less, 4k RAM
AM_RANGE(0xfee000, 0xfee0ff) AM_READWRITE( h8_3007_itu1_r, h8_3007_itu1_w )
AM_RANGE(0xffef20, 0xffff1f) AM_RAM
AM_RANGE(0xffff20, 0xffffe9) AM_READWRITE( h8_3007_itu_r, h8_3007_itu_w )
ADDRESS_MAP_END
CPU_GET_INFO( h8_3002 )
{
h83xx_state *h8 = (device != NULL) ? device->token : NULL;
switch(state) {
// Interface functions and variables
case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(h8); break;
case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(h8); break;
case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(h8); break;
case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(h8); break;
case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(h8); break;
case CPUINFO_PTR_EXIT: info->exit = 0; break;
case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(h8); break;
case CPUINFO_PTR_BURN: info->burn = 0; break;
case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(h8_32); break;
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &h8->cyccnt; break;
case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(h83xx_state); break;
case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break;
case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 10; break;
// Bus sizes
case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break;
case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 24; 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_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;
// Internal maps
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(h8_3002_internal_map); break;
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map16 = NULL; break;
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_IO: info->internal_map16 = NULL; break;
// CPU misc parameters
case CPUINFO_STR_NAME: strcpy(info->s, "H8/3002"); break;
case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
case CPUINFO_STR_FLAGS: strcpy(info->s, h8_get_ccr_str(h8)); break;
case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break;
case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
case CPUINFO_INT_INPUT_LINES: info->i = 16; break;
case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = -1; break;
// CPU main state
case CPUINFO_INT_PC: info->i = h8->pc; break;
case CPUINFO_INT_PREVIOUSPC: info->i = h8->ppc; break;
case CPUINFO_INT_REGISTER + H8_PC: info->i = h8->pc; break;
case CPUINFO_INT_REGISTER + H8_CCR: info->i = h8_get_ccr(h8); break;
case CPUINFO_INT_REGISTER + H8_E0: info->i = h8->regs[0]; break;
case CPUINFO_INT_REGISTER + H8_E1: info->i = h8->regs[1]; break;
case CPUINFO_INT_REGISTER + H8_E2: info->i = h8->regs[2]; break;
case CPUINFO_INT_REGISTER + H8_E3: info->i = h8->regs[3]; break;
case CPUINFO_INT_REGISTER + H8_E4: info->i = h8->regs[4]; break;
case CPUINFO_INT_REGISTER + H8_E5: info->i = h8->regs[5]; break;
case CPUINFO_INT_REGISTER + H8_E6: info->i = h8->regs[6]; break;
case CPUINFO_INT_REGISTER + H8_E7: info->i = h8->regs[7]; break;
// CPU debug stuff
case CPUINFO_STR_REGISTER + H8_PC: sprintf(info->s, "PC :%08x", h8->pc); break;
case CPUINFO_STR_REGISTER + H8_CCR: sprintf(info->s, "CCR :%08x", h8_get_ccr(h8)); break;
case CPUINFO_STR_REGISTER + H8_E0: sprintf(info->s, "ER0 :%08x", h8->regs[0]); break;
case CPUINFO_STR_REGISTER + H8_E1: sprintf(info->s, "ER1 :%08x", h8->regs[1]); break;
case CPUINFO_STR_REGISTER + H8_E2: sprintf(info->s, "ER2 :%08x", h8->regs[2]); break;
case CPUINFO_STR_REGISTER + H8_E3: sprintf(info->s, "ER3 :%08x", h8->regs[3]); break;
case CPUINFO_STR_REGISTER + H8_E4: sprintf(info->s, "ER4 :%08x", h8->regs[4]); break;
case CPUINFO_STR_REGISTER + H8_E5: sprintf(info->s, "ER5 :%08x", h8->regs[5]); break;
case CPUINFO_STR_REGISTER + H8_E6: sprintf(info->s, "ER6 :%08x", h8->regs[6]); break;
case CPUINFO_STR_REGISTER + H8_E7: sprintf(info->s, " SP :%08x", h8->regs[7]); break;
}
}
CPU_GET_INFO( h8_3044 )
{
switch (state)
{
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(h8_3044_internal_map); break;
case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(h8_24); break;
case CPUINFO_STR_NAME: strcpy(info->s, "H8/3044"); break;
default:
CPU_GET_INFO_CALL(h8_3002);
}
}
CPU_GET_INFO( h8_3007 )
{
switch (state)
{
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = address_map_h8_3007_internal_map; break;
case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(h8_3007); break;
case CPUINFO_STR_NAME: strcpy(info->s, "H8/3007"); break;
default:
CPU_GET_INFO_CALL(h8_3002);
}
}

603
src/emu/cpu/h83002/h8_8.c Normal file
View File

@ -0,0 +1,603 @@
/***************************************************************************
h8_8.c: Hitachi H8/3xx 8/16-bit microcontroller emulator
Based on H8/300 series 16/32-bit emulator h83002.c.
Reference: Renesas Technology H8/3337 Group Hardware Manual
By R. Belmont
****************************************************************************/
#include "debugger.h"
#include "deprecat.h"
#include "h8.h"
#include "h8priv.h"
#define H8_SP (7)
#define h8_mem_read8(x) program_read_byte_8be(x)
#define h8_mem_write8(x, y) program_write_byte_8be(x, y)
// timing macros
#define H8_IFETCH_TIMING(x) h8->cyccnt -= (x) * 4;
#define H8_BRANCH_TIMING(x) h8->cyccnt -= (x) * 4;
#define H8_STACK_TIMING(x) h8->cyccnt -= (x) * 4;
#define H8_BYTE_TIMING(x, adr) if (address24 >= 0xff90) h8->cyccnt -= (x) * 3; else h8->cyccnt -= (x) * 4;
#define H8_WORD_TIMING(x, adr) if (address24 >= 0xff90) h8->cyccnt -= (x) * 3; else h8->cyccnt -= (x) * 4;
#define H8_IOP_TIMING(x) h8->cyccnt -= (x);
INLINE UINT16 h8_mem_read16(offs_t address)
{
UINT16 result = program_read_byte_8be(address)<<8;
return result | program_read_byte_8be(address+1);
}
INLINE UINT16 h8_readop16(offs_t address)
{
UINT16 result = program_decrypted_read_byte(address)<<8;
return result | program_decrypted_read_byte(address+1);
}
INLINE void h8_mem_write16(offs_t address, UINT16 data)
{
program_write_byte_8be(address, data >> 8);
program_write_byte_8be(address+1, data);
}
INLINE UINT32 h8_mem_read32(offs_t address)
{
UINT32 result = program_read_byte_8be(address) << 24;
result |= program_read_byte_8be(address+1) << 16;
result |= program_read_byte_8be(address+2) << 8;
result |= program_read_byte_8be(address+3);
return result;
}
INLINE void h8_mem_write32(offs_t address, UINT32 data)
{
program_write_byte_8be(address, data >> 24);
program_write_byte_8be(address+1, data >> 16);
program_write_byte_8be(address+2, data >> 8);
program_write_byte_8be(address+3, data);
}
static void *token;
static void h8_check_irqs(h83xx_state *h8);
/* implementation */
extern offs_t h8_disasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 addrmask);
static CPU_DISASSEMBLE(h8)
{
return h8_disasm(buffer, pc, oprom, opram, 0xffff);
}
void h8_300_InterruptRequest(h83xx_state *h8, UINT8 source)
{
if(source>31)
{
h8->h8_IRQrequestH |= (1<<(source-32));
}
else
{
h8->h8_IRQrequestL |= (1<<source);
}
}
static UINT8 h8_get_ccr(h83xx_state *h8)
{
h8->ccr = 0;
if(h8->h8nflag)h8->ccr |= NFLAG;
if(h8->h8zflag)h8->ccr |= ZFLAG;
if(h8->h8vflag)h8->ccr |= VFLAG;
if(h8->h8cflag)h8->ccr |= CFLAG;
if(h8->h8uflag)h8->ccr |= UFLAG;
if(h8->h8hflag)h8->ccr |= HFLAG;
if(h8->h8uiflag)h8->ccr |= UIFLAG;
if(h8->h8iflag)h8->ccr |= IFLAG;
return h8->ccr;
}
static char *h8_get_ccr_str(h83xx_state *h8)
{
static char res[8];
memset(res, 0, 8);
if(h8->h8iflag) strcat(res, "I"); else strcat(res, "i");
if(h8->h8uiflag)strcat(res, "U"); else strcat(res, "u");
if(h8->h8hflag) strcat(res, "H"); else strcat(res, "h");
if(h8->h8uflag) strcat(res, "U"); else strcat(res, "u");
if(h8->h8nflag) strcat(res, "N"); else strcat(res, "n");
if(h8->h8zflag) strcat(res, "Z"); else strcat(res, "z");
if(h8->h8vflag) strcat(res, "V"); else strcat(res, "v");
if(h8->h8cflag) strcat(res, "C"); else strcat(res, "c");
return res;
}
static void h8_set_ccr(h83xx_state *h8, UINT8 data)
{
h8->ccr = data;
h8->h8nflag = 0;
h8->h8zflag = 0;
h8->h8vflag = 0;
h8->h8cflag = 0;
h8->h8hflag = 0;
h8->h8iflag = 0;
h8->h8uflag = 0;
h8->h8uiflag = 0;
if(h8->ccr & NFLAG) h8->h8nflag = 1;
if(h8->ccr & ZFLAG) h8->h8zflag = 1;
if(h8->ccr & VFLAG) h8->h8vflag = 1;
if(h8->ccr & CFLAG) h8->h8cflag = 1;
if(h8->ccr & HFLAG) h8->h8hflag = 1;
if(h8->ccr & UFLAG) h8->h8uflag = 1;
if(h8->ccr & UIFLAG) h8->h8uiflag = 1;
if(h8->ccr & IFLAG) h8->h8iflag = 1;
h8_check_irqs(h8);
}
static INT16 h8_getreg16(h83xx_state *h8, UINT8 reg)
{
if(reg > 7)
{
return h8->regs[reg-8]>>16;
}
else
{
return h8->regs[reg];
}
}
static void h8_setreg16(h83xx_state *h8, UINT8 reg, UINT16 data)
{
if(reg > 7)
{
h8->regs[reg-8] &= 0xffff;
h8->regs[reg-8] |= data<<16;
}
else
{
h8->regs[reg] &= 0xffff0000;
h8->regs[reg] |= data;
}
}
static UINT8 h8_getreg8(h83xx_state *h8, UINT8 reg)
{
if(reg > 7)
{
return h8->regs[reg-8];
}
else
{
return h8->regs[reg]>>8;
}
}
static void h8_setreg8(h83xx_state *h8, UINT8 reg, UINT8 data)
{
if(reg > 7)
{
h8->regs[reg-8] &= 0xffffff00;
h8->regs[reg-8] |= data;
}
else
{
h8->regs[reg] &= 0xffff00ff;
h8->regs[reg] |= data<<8;
}
}
static UINT32 h8_getreg32(h83xx_state *h8, UINT8 reg)
{
return h8->regs[reg];
}
static void h8_setreg32(h83xx_state *h8, UINT8 reg, UINT32 data)
{
h8->regs[reg] = data;
}
static STATE_POSTLOAD( h8_onstateload )
{
h83xx_state *h8 = (h83xx_state *)param;
h8_set_ccr(h8, h8->ccr);
}
static CPU_INIT(h8bit)
{
h83xx_state *h8 = device->token;
h8->h8iflag = 1;
h8->irq_cb = irqcallback;
h8->device = device;
h8->h8300_mode = 1;
state_save_register_item("H8/300", device->tag, 0, h8->h8err);
state_save_register_item_array("H8/300", device->tag, 0, h8->regs);
state_save_register_item("H8/300", device->tag, 0, h8->pc);
state_save_register_item("H8/300", device->tag, 0, h8->ppc);
state_save_register_item("H8/300", device->tag, 0, h8->h8_IRQrequestH);
state_save_register_item("H8/300", device->tag, 0, h8->h8_IRQrequestL);
state_save_register_item("H8/300", device->tag, 0, h8->ccr);
state_save_register_item("H8/300", device->tag, 0, h8->h8300_mode);
state_save_register_item_array("H8/300", device->tag, 0, h8->per_regs);
state_save_register_item("H8/300", device->tag, 0, h8->h8TSTR);
state_save_register_item_array("H8/300", device->tag, 0, h8->h8TCNT);
state_save_register_postload(Machine, h8_onstateload, h8);
}
static CPU_RESET(h8bit)
{
h83xx_state *h8 = device->token;
h8->h8err = 0;
h8->pc = h8_mem_read16(0);
change_pc(h8->pc);
// disable timers
h8->h8TSTR = 0;
}
static void h8_GenException(h83xx_state *h8, UINT8 vectornr)
{
// push PC on stack
h8_setreg16(h8, H8_SP, h8_getreg16(h8, H8_SP)-2);
h8_mem_write16(h8_getreg16(h8, H8_SP), h8->pc);
// push ccr
h8_setreg16(h8, H8_SP, h8_getreg16(h8, H8_SP)-2);
h8_mem_write16(h8_getreg16(h8, H8_SP), h8_get_ccr(h8));
// generate address from vector
h8_set_ccr(h8, h8_get_ccr(h8) | 0x80);
if (h8->h8uiflag == 0)
h8_set_ccr(h8, h8_get_ccr(h8) | 0x40);
h8->pc = h8_mem_read16(vectornr * 2) & 0xffff;
change_pc(h8->pc);
// I couldn't find timing info for exceptions, so this is a guess (based on JSR/BSR)
H8_IFETCH_TIMING(2);
H8_STACK_TIMING(2);
}
static int h8_get_priority(h83xx_state *h8, UINT8 bit)
{
int res = 0;
switch(bit)
{
case 12: // IRQ0
if (h8->per_regs[0xF8]&0x80) res = 1; break;
case 13: // IRQ1
if (h8->per_regs[0xF8]&0x40) res = 1; break;
case 14: // IRQ2
case 15: // IRQ3
if (h8->per_regs[0xF8]&0x20) res = 1; break;
case 16: // IRQ4
case 17: // IRQ5
if (h8->per_regs[0xF8]&0x10) res = 1; break;
}
return res;
}
static void h8_check_irqs(h83xx_state *h8)
{
int lv = -1;
if (h8->h8iflag == 0)
{
lv = 0;
}
// any interrupts wanted and can accept ?
if(((h8->h8_IRQrequestH != 0) || (h8->h8_IRQrequestL != 0)) && (lv >= 0))
{
UINT8 bit, source;
// which one ?
for(bit = 0, source = 0xff; source == 0xff && bit < 32; bit++)
{
if( h8->h8_IRQrequestL & (1<<bit) )
{
if (h8_get_priority(h8, bit) >= lv)
{
// mask off
h8->h8_IRQrequestL &= ~(1<<bit);
source = bit;
}
}
}
// which one ?
for(bit = 0; source == 0xff && bit < 32; bit++)
{
if( h8->h8_IRQrequestH & (1<<bit) )
{
if (h8_get_priority(h8, bit + 32) >= lv)
{
// mask off
h8->h8_IRQrequestH &= ~(1<<bit);
source = bit + 32;
}
}
}
// call the MAME callback if it's one of the external IRQs
if (source >= 3 && source <= 11)
{
(*h8->irq_cb)(h8->device, source - 3 + H8_NMI);
}
if (source != 0xff)
{
h8_GenException(h8, source);
}
}
}
#define H8_ADDR_MASK 0xffff
#include "h8ops.h"
// MAME interface stuff
static CPU_GET_CONTEXT( h8 )
{
}
static CPU_SET_CONTEXT( h8 )
{
if (src)
{
token = src;
}
}
static CPU_SET_INFO( h8 )
{
h83xx_state *h8 = device->token;
switch(state) {
case CPUINFO_INT_PC: h8->pc = info->i; change_pc(h8->pc); break;
case CPUINFO_INT_REGISTER + H8_PC: h8->pc = info->i; change_pc(h8->pc); break;
case CPUINFO_INT_REGISTER + H8_CCR: h8_set_ccr(h8, info->i); break;
case CPUINFO_INT_REGISTER + H8_E0: h8->regs[0] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E1: h8->regs[1] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E2: h8->regs[2] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E3: h8->regs[3] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E4: h8->regs[4] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E5: h8->regs[5] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E6: h8->regs[6] = info->i; break;
case CPUINFO_INT_REGISTER + H8_E7: h8->regs[7] = info->i; break;
case CPUINFO_INT_INPUT_STATE + H8_NMI: if (info->i) h8_300_InterruptRequest(h8, 3); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ0: if (info->i) h8_300_InterruptRequest(h8, 4); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ1: if (info->i) h8_300_InterruptRequest(h8, 5); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ2: if (info->i) h8_300_InterruptRequest(h8, 6); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ3: if (info->i) h8_300_InterruptRequest(h8, 7); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ4: if (info->i) h8_300_InterruptRequest(h8, 8); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ5: if (info->i) h8_300_InterruptRequest(h8, 9); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ6: if (info->i) h8_300_InterruptRequest(h8, 10); break;
case CPUINFO_INT_INPUT_STATE + H8_IRQ7: if (info->i) h8_300_InterruptRequest(h8, 11); break;
case CPUINFO_INT_INPUT_STATE + H8_SCI_0_RX: if (info->i) h8_300_InterruptRequest(h8, 28); break;
case CPUINFO_INT_INPUT_STATE + H8_SCI_1_RX: if (info->i) h8_300_InterruptRequest(h8, 32); break;
default:
fatalerror("h8_set_info unknown request %x", state);
break;
}
}
static READ8_HANDLER( h8330_itu_r )
{
UINT8 val;
UINT8 reg;
h83xx_state *h8 = (h83xx_state *)space->cpu->token;
reg = (offset + 0x88) & 0xff;
switch(reg)
{
case 0x8d: // serial Rx 1
val = io_read_byte(H8_SERIAL_1);
break;
case 0xb2: // port 1 data
val = io_read_byte(H8_PORT_1);
break;
case 0xb3: // port 2 data
val = io_read_byte(H8_PORT_2);
break;
case 0xb6: // port 3 data
val = io_read_byte(H8_PORT_3);
break;
case 0xb7: // port 4 data
val = io_read_byte(H8_PORT_4);
break;
case 0xba: // port 5 data
val = io_read_byte(H8_PORT_5);
break;
case 0xbb: // port 6 data
val = io_read_byte(H8_PORT_6);
break;
case 0xbe: // port 7 data
val = io_read_byte(H8_PORT_7);
break;
case 0xbf: // port 8 data
val = io_read_byte(H8_PORT_8);
break;
case 0xc1: // port 9 data
val = io_read_byte(H8_PORT_9);
break;
case 0xdc: // serial status
val = 0x87;
break;
case 0xdd: // serial Rx 0
val = io_read_byte(H8_SERIAL_0);
break;
default:
val = h8->per_regs[reg];
break;
}
return val;
}
static WRITE8_HANDLER( h8330_itu_w )
{
UINT8 reg;
h83xx_state *h8 = (h83xx_state *)space->cpu->token;
reg = (offset + 0x88) & 0xff;
switch (reg)
{
case 0x8b: // serial Tx 1
io_write_byte(H8_SERIAL_1, data);
break;
case 0xb2: // port 1 data
io_write_byte(H8_PORT_1, data);
break;
case 0xb3: // port 2 data
io_write_byte(H8_PORT_2, data);
break;
case 0xb6: // port 3 data
io_write_byte(H8_PORT_3, data);
break;
case 0xb7: // port 4 data
io_write_byte(H8_PORT_4, data);
break;
case 0xba: // port 5 data
io_write_byte(H8_PORT_5, data);
break;
case 0xbb: // port 6 data
io_write_byte(H8_PORT_6, data);
break;
case 0xbe: // port 7 data
io_write_byte(H8_PORT_7, data);
break;
case 0xbf: // port 8 data
io_write_byte(H8_PORT_8, data);
break;
case 0xc1: // port 9 data
io_write_byte(H8_PORT_9, data);
break;
case 0xdb: // serial Tx 0
io_write_byte(H8_SERIAL_0, data);
break;
case 0xd8:
case 0xda:
case 0xdc:
case 0xd9:
break;
case 0x88:
case 0x8a:
case 0x8c:
case 0x89:
break;
case 0xc3:
break;
case 0xc7:
break;
}
h8->per_regs[reg] = data;
}
static ADDRESS_MAP_START( h8_3344_internal_map, ADDRESS_SPACE_PROGRAM, 8 )
// 512B RAM
AM_RANGE(0xfb80, 0xff7f) AM_RAM
AM_RANGE(0xff88, 0xffff) AM_READWRITE( h8330_itu_r, h8330_itu_w )
ADDRESS_MAP_END
CPU_GET_INFO( h8_3344 )
{
h83xx_state *h8 = (device != NULL) ? device->token : NULL;
switch(state) {
// Interface functions and variables
case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(h8); break;
case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(h8); break;
case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(h8); break;
case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(h8bit); break;
case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(h8bit); break;
case CPUINFO_PTR_EXIT: info->exit = 0; break;
case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(h8); break;
case CPUINFO_PTR_BURN: info->burn = 0; break;
case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(h8); break;
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &h8->cyccnt; break;
case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(h83xx_state); break;
case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break;
case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 10; break;
// Bus sizes
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 = 0; break;
case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; 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;
// Internal maps
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map8 = address_map_h8_3344_internal_map; 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_map16 = NULL; break;
// CPU misc parameters
case CPUINFO_STR_NAME: strcpy(info->s, "H8/3344"); break;
case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
case CPUINFO_STR_FLAGS: strcpy(info->s, h8_get_ccr_str(h8)); break;
case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break;
case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
case CPUINFO_INT_INPUT_LINES: info->i = 16; break;
case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = -1; break;
// CPU main state
case CPUINFO_INT_PC: info->i = h8->pc; break;
case CPUINFO_INT_PREVIOUSPC: info->i = h8->ppc; break;
case CPUINFO_INT_REGISTER + H8_PC: info->i = h8->pc; break;
case CPUINFO_INT_REGISTER + H8_CCR: info->i = h8_get_ccr(h8); break;
case CPUINFO_INT_REGISTER + H8_E0: info->i = h8->regs[0]; break;
case CPUINFO_INT_REGISTER + H8_E1: info->i = h8->regs[1]; break;
case CPUINFO_INT_REGISTER + H8_E2: info->i = h8->regs[2]; break;
case CPUINFO_INT_REGISTER + H8_E3: info->i = h8->regs[3]; break;
case CPUINFO_INT_REGISTER + H8_E4: info->i = h8->regs[4]; break;
case CPUINFO_INT_REGISTER + H8_E5: info->i = h8->regs[5]; break;
case CPUINFO_INT_REGISTER + H8_E6: info->i = h8->regs[6]; break;
case CPUINFO_INT_REGISTER + H8_E7: info->i = h8->regs[7]; break;
// CPU debug stuff
case CPUINFO_STR_REGISTER + H8_PC: sprintf(info->s, "PC :%08x", h8->pc); break;
case CPUINFO_STR_REGISTER + H8_CCR: sprintf(info->s, "CCR :%08x", h8_get_ccr(h8)); break;
case CPUINFO_STR_REGISTER + H8_E0: sprintf(info->s, " R0 :%08x", h8->regs[0]); break;
case CPUINFO_STR_REGISTER + H8_E1: sprintf(info->s, " R1 :%08x", h8->regs[1]); break;
case CPUINFO_STR_REGISTER + H8_E2: sprintf(info->s, " R2 :%08x", h8->regs[2]); break;
case CPUINFO_STR_REGISTER + H8_E3: sprintf(info->s, " R3 :%08x", h8->regs[3]); break;
case CPUINFO_STR_REGISTER + H8_E4: sprintf(info->s, " R4 :%08x", h8->regs[4]); break;
case CPUINFO_STR_REGISTER + H8_E5: sprintf(info->s, " R5 :%08x", h8->regs[5]); break;
case CPUINFO_STR_REGISTER + H8_E6: sprintf(info->s, " R6 :%08x", h8->regs[6]); break;
case CPUINFO_STR_REGISTER + H8_E7: sprintf(info->s, " SP :%08x", h8->regs[7]); break;
}
}

View File

@ -1,6 +1,6 @@
/***************************************************************************
h8disasm.c: Hitachi H8/3000 series disassembler
h8disasm.c: Hitachi H8/3xx series disassembler
Original by The_Author & DynaChicken for the ZiNc emulator.
@ -9,7 +9,7 @@
****************************************************************************/
#include "debugger.h"
#include "h83002.h"
#include "h8.h"
static const char *const bit_instr[8] = {"bset", "bnot", "bclr", "btst", "bor", "bxor", "band", "bld"};
static const char *const bit_instr2[8] = {"bset", "bnot", "bclr", "btst", "bior", "bixor", "biand", "bild"};
@ -20,16 +20,16 @@ static const char *const reg_names32[8] = {"ER0", "ER1", "ER2", "ER3", "ER4", "
static const char *const reg_names16[16] = {"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7"};
static const char *const reg_names8[16] = {"R0H", "R1H", "R2H", "R3H", "R4H", "R5H", "R6H", "R7H","R0L", "R1L", "R2L", "R3L", "R4L", "R5L", "R6L", "R7L"};
static UINT32 h8disasm_0(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom);
static UINT32 h8disasm_1(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom);
static UINT32 h8disasm_5(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom);
static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom);
static UINT32 h8disasm_7(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom);
static UINT32 h8disasm_0(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom);
static UINT32 h8disasm_1(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom);
static UINT32 h8disasm_5(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom);
static UINT32 h8disasm_6(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom, UINT32 addr_mask);
static UINT32 h8disasm_7(UINT32 address, UINT32 opcode, char *output, const UINT8 *oprom, UINT32 addr_mask);
#define h8_mem_read16(x) ((oprom[x] << 8) | oprom[(x) + 1])
#define h8_mem_read32(x) ((oprom[x] << 24) | (oprom[(x) + 1] << 16) | (oprom[(x) + 2] << 8) | oprom[(x) + 3])
CPU_DISASSEMBLE( h8 )
offs_t h8_disasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 addr_mask)
{
UINT32 size = 0;
UINT16 opcode;
@ -46,18 +46,18 @@ CPU_DISASSEMBLE( h8 )
break;
// mov.b @xx:8, Rd (abs)
case 0x2:
sprintf(buffer, "%4.4x mov.b @%8.8x, %s", opcode, 0xffff00 | (opcode & 0xff), reg_names8[(opcode>>8) & 0xf]);
sprintf(buffer, "%4.4x mov.b @%8.8x, %s", opcode, (0xffff00 | (opcode & 0xff))&addr_mask, reg_names8[(opcode>>8) & 0xf]);
size = 2;
break;
// mov.b Rs, @xx:8 (abs)
case 0x3:
sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[(opcode>>8) & 0xf], 0xfffff00 | (opcode & 0xff));
sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[(opcode>>8) & 0xf], (0xfffff00 | (opcode & 0xff))&addr_mask);
size = 2;
break;
// bcc @xx:8
case 0x4:
pc += 2;
sprintf(buffer, "%4.4x %s %8.8x", opcode, branch_instr[(opcode >> 8) & 0xf], pc + (INT8)(opcode &0xff));
sprintf(buffer, "%4.4x %s %8.8x", opcode, branch_instr[(opcode >> 8) & 0xf], (pc + (INT8)(opcode &0xff))&addr_mask);
size = 2;
break;
// group 5
@ -65,10 +65,10 @@ CPU_DISASSEMBLE( h8 )
size = h8disasm_5(pc, opcode, buffer, oprom);
break;
case 0x6:
size = h8disasm_6(pc, opcode, buffer, oprom);
size = h8disasm_6(pc, opcode, buffer, oprom, addr_mask);
break;
case 0x7:
size = h8disasm_7(pc, opcode, buffer, oprom);
size = h8disasm_7(pc, opcode, buffer, oprom, addr_mask);
break;
case 0x8:
// add.b #xx:8, Rd
@ -930,7 +930,7 @@ static UINT32 h8disasm_5(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op
return size;
}
static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom)
static UINT32 h8disasm_6(UINT32 address, UINT32 opcode, char *buffer, const UINT8 *oprom, UINT32 addr_mask)
{
UINT32 size = 2;
UINT32 data32;
@ -1011,17 +1011,17 @@ static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op
break;
case 0x2:
data32=h8_mem_read32(2);
sprintf(buffer, "%4.4x mov.b @%8.8x, %s", opcode, data32, reg_names8[opcode & 0xf]);
sprintf(buffer, "%4.4x mov.b @%8.8x, %s", opcode, data32&addr_mask, reg_names8[opcode & 0xf]);
size = 6;
break;
case 0x8:
data16=h8_mem_read16(2);
sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[opcode & 0xf], data16);
sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[opcode & 0xf], data16&addr_mask);
size = 4;
break;
case 0xa:
data32=h8_mem_read32(2);
sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[opcode & 0xf], data32);
sprintf(buffer, "%4.4x mov.b %s, @%8.8x", opcode, reg_names8[opcode & 0xf], data32&addr_mask);
size = 6;
break;
default:
@ -1036,22 +1036,22 @@ static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op
{
case 0x0:
data16=h8_mem_read16(2);
sprintf(buffer, "%4.4x mov.w @%8.8x, %s", opcode, data16, reg_names16[opcode & 0xf]);
sprintf(buffer, "%4.4x mov.w @%8.8x, %s", opcode, data16&addr_mask, reg_names16[opcode & 0xf]);
size = 4;
break;
case 0x2:
data32=h8_mem_read32(2);
sprintf(buffer, "%4.4x mov.w @%8.8x, %s", opcode, data32, reg_names16[opcode & 0xf]);
sprintf(buffer, "%4.4x mov.w @%8.8x, %s", opcode, data32&addr_mask, reg_names16[opcode & 0xf]);
size = 6;
break;
case 0x8:
data16=h8_mem_read16(2);
sprintf(buffer, "%4.4x mov.w %s, @%8.8x", opcode, reg_names16[opcode & 0xf], data16);
sprintf(buffer, "%4.4x mov.w %s, @%8.8x", opcode, reg_names16[opcode & 0xf], data16&addr_mask);
size = 4;
break;
case 0xa:
data32=h8_mem_read32(2);
sprintf(buffer, "%4.4x mov.w %s, @%8.8x", opcode, reg_names16[opcode & 0xf], data32);
sprintf(buffer, "%4.4x mov.w %s, @%8.8x", opcode, reg_names16[opcode & 0xf], data32&addr_mask);
size = 6;
break;
default:
@ -1092,7 +1092,7 @@ static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op
sprintf(buffer, "%4.4x mov.b %s,@(%x, %s)", opcode, reg_names8[opcode &0xf], data16, reg_names32[(opcode>>4)&7]);
}
else
{
{
sprintf(buffer, "%4.4x mov.b @(%x, %s), %s", opcode, data16, reg_names32[(opcode>>4)&7], reg_names8[opcode &0xf]);
}
size = 4;
@ -1117,7 +1117,7 @@ static UINT32 h8disasm_6(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op
return size;
}
static UINT32 h8disasm_7(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *oprom)
static UINT32 h8disasm_7(UINT32 address, UINT32 opcode, char *buffer, const UINT8 *oprom, UINT32 addr_mask)
{
UINT32 size = 2;
UINT32 data32;
@ -1255,11 +1255,11 @@ static UINT32 h8disasm_7(UINT32 pc, UINT32 opcode, char *buffer, const UINT8 *op
data16 = h8_mem_read16(2);
if(((data16>>4)&0x8) == 0)
{
sprintf(buffer, "%4.4x %4.4x %s.b #%1.1x, @%x", opcode, data16, bit_instr[(data16>>8)&7], (data16>>4)&7, 0xffffff00 + (opcode & 0xff));
sprintf(buffer, "%4.4x %4.4x %s.b #%1.1x, @%x", opcode, data16, bit_instr[(data16>>8)&7], (data16>>4)&7, (0xffffff00 + (opcode & 0xff))&addr_mask);
}
else
{
sprintf(buffer, "%4.4x %4.4x %s.b #%1.1x, @%x", opcode, data16, bit_instr2[(data16>>8)&7], (data16>>4)&7, 0xffffff00 + (opcode & 0xff));
sprintf(buffer, "%4.4x %4.4x %s.b #%1.1x, @%x", opcode, data16, bit_instr2[(data16>>8)&7], (data16>>4)&7, (0xffffff00 + (opcode & 0xff))&addr_mask);
}
size = 4;
break;

3551
src/emu/cpu/h83002/h8ops.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
#include "debugger.h"
#include "deprecat.h"
#include "cpuexec.h"
#include "h83002.h"
#include "h8.h"
#include "h8priv.h"
#define H8_REG_START (0x00ffff10)
@ -39,99 +39,135 @@ static const UINT8 tier[5] = { TIER0, TIER1, TIER2, TIER3, TIER4 };
static const UINT8 tcr[5] = { TCR0, TCR1, TCR2, TCR3, TCR4 };
static const int tscales[4] = { 1, 2, 4, 8 };
static TIMER_CALLBACK( h8itu_timer_cb )
{
extern void h8_3002_InterruptRequest(h83xx_state *h8, UINT8 source);
extern void *h8_token;
int which = (int)(FPTR)ptr;
timer_adjust_oneshot(h8.timer[which], attotime_never, 0);
h8.h8TCNT[which] = 0;
h8.per_regs[tsr[which]] |= 4;
static void h8itu_timer_expire(h83xx_state *h8, int which)
{
timer_adjust_oneshot(h8->timer[which], attotime_never, 0);
h8->h8TCNT[which] = 0;
h8->per_regs[tsr[which]] |= 4;
// interrupt on overflow ?
if(h8.per_regs[tier[which]] & 4)
if(h8->per_regs[tier[which]] & 4)
{
h8_3002_InterruptRequest(26 + 4*which);
h8_3002_InterruptRequest(h8, 26 + 4*which);
}
}
static void h8_itu_refresh_timer(int tnum)
static TIMER_CALLBACK( h8itu_timer_0_cb )
{
h83xx_state *h8 = (h83xx_state *)ptr;
h8itu_timer_expire(h8, 0);
}
static TIMER_CALLBACK( h8itu_timer_1_cb )
{
h83xx_state *h8 = (h83xx_state *)ptr;
h8itu_timer_expire(h8, 1);
}
static TIMER_CALLBACK( h8itu_timer_2_cb )
{
h83xx_state *h8 = (h83xx_state *)ptr;
h8itu_timer_expire(h8, 2);
}
static TIMER_CALLBACK( h8itu_timer_3_cb )
{
h83xx_state *h8 = (h83xx_state *)ptr;
h8itu_timer_expire(h8, 3);
}
static TIMER_CALLBACK( h8itu_timer_4_cb )
{
h83xx_state *h8 = (h83xx_state *)ptr;
h8itu_timer_expire(h8, 4);
}
static void h8_itu_refresh_timer(h83xx_state *h8, int tnum)
{
int ourTCR = 0;
int ourTVAL = 0;
attotime period;
ourTCR = h8.per_regs[tcr[tnum]];
ourTVAL = h8.h8TCNT[tnum];
ourTCR = h8->per_regs[tcr[tnum]];
ourTVAL = h8->h8TCNT[tnum];
period = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8.cpu_number])), tscales[ourTCR & 3] * (65536 - ourTVAL));
period = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8->cpu_number])), tscales[ourTCR & 3] * (65536 - ourTVAL));
if (ourTCR & 4)
{
logerror("H8/3002: Timer %d is using an external clock. Unsupported!\n", tnum);
}
timer_adjust_oneshot(h8.timer[tnum], period, 0);
timer_adjust_oneshot(h8->timer[tnum], period, 0);
}
static void h8_itu_sync_timers(int tnum)
static void h8_itu_sync_timers(h83xx_state *h8, int tnum)
{
int ourTCR = 0;
attotime cycle_time, cur;
UINT16 ratio;
ourTCR = h8.per_regs[tcr[tnum]];
ourTCR = h8->per_regs[tcr[tnum]];
// get the time per unit
cycle_time = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8.cpu_number])), tscales[ourTCR & 3]);
cur = timer_timeelapsed(h8.timer[tnum]);
cycle_time = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8->cpu_number])), tscales[ourTCR & 3]);
cur = timer_timeelapsed(h8->timer[tnum]);
ratio = attotime_to_double(cur) / attotime_to_double(cycle_time);
h8.h8TCNT[tnum] = ratio;
h8->h8TCNT[tnum] = ratio;
}
UINT8 h8_itu_read8(UINT8 reg)
UINT8 h8_itu_read8(h83xx_state *h8, UINT8 reg)
{
UINT8 val;
switch(reg)
{
case 0x60:
val = h8.h8TSTR;
val = h8->h8TSTR;
break;
case 0x68:
h8_itu_sync_timers(0);
val = h8.h8TCNT[0]>>8;
h8_itu_sync_timers(h8, 0);
val = h8->h8TCNT[0]>>8;
break;
case 0x69:
h8_itu_sync_timers(0);
val = h8.h8TCNT[0]&0xff;
h8_itu_sync_timers(h8, 0);
val = h8->h8TCNT[0]&0xff;
break;
case 0x72:
h8_itu_sync_timers(1);
val = h8.h8TCNT[1]>>8;
h8_itu_sync_timers(h8, 1);
val = h8->h8TCNT[1]>>8;
break;
case 0x73:
h8_itu_sync_timers(1);
val = h8.h8TCNT[1]&0xff;
h8_itu_sync_timers(h8, 1);
val = h8->h8TCNT[1]&0xff;
break;
case 0x7c:
h8_itu_sync_timers(2);
val = h8.h8TCNT[2]>>8;
h8_itu_sync_timers(h8, 2);
val = h8->h8TCNT[2]>>8;
break;
case 0x7d:
h8_itu_sync_timers(2);
val = h8.h8TCNT[2]&0xff;
h8_itu_sync_timers(h8, 2);
val = h8->h8TCNT[2]&0xff;
break;
case 0x86:
h8_itu_sync_timers(3);
val = h8.h8TCNT[3]>>8;
h8_itu_sync_timers(h8, 3);
val = h8->h8TCNT[3]>>8;
break;
case 0x87:
h8_itu_sync_timers(3);
val = h8.h8TCNT[3]&0xff;
h8_itu_sync_timers(h8, 3);
val = h8->h8TCNT[3]&0xff;
break;
default:
val = h8.per_regs[reg];
val = h8->per_regs[reg];
break;
}
@ -139,102 +175,102 @@ UINT8 h8_itu_read8(UINT8 reg)
return val;
}
void h8_itu_write8(UINT8 reg, UINT8 val)
void h8_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val)
{
h8.per_regs[reg] = val;
h8->per_regs[reg] = val;
switch(reg)
{
case 0x60:
if ((val & 1) && !(h8.h8TSTR & 1))
if ((val & 1) && !(h8->h8TSTR & 1))
{
h8_itu_refresh_timer(0);
h8_itu_refresh_timer(h8, 0);
}
if ((val & 2) && !(h8.h8TSTR & 2))
if ((val & 2) && !(h8->h8TSTR & 2))
{
h8_itu_refresh_timer(1);
h8_itu_refresh_timer(h8, 1);
}
if ((val & 4) && !(h8.h8TSTR & 4))
if ((val & 4) && !(h8->h8TSTR & 4))
{
h8_itu_refresh_timer(2);
h8_itu_refresh_timer(h8, 2);
}
if ((val & 8) && !(h8.h8TSTR & 8))
if ((val & 8) && !(h8->h8TSTR & 8))
{
h8_itu_refresh_timer(3);
h8_itu_refresh_timer(h8, 3);
}
if ((val & 0x10) && !(h8.h8TSTR & 0x10))
if ((val & 0x10) && !(h8->h8TSTR & 0x10))
{
h8_itu_refresh_timer(4);
h8_itu_refresh_timer(h8, 4);
}
h8.h8TSTR = val;
h8->h8TSTR = val;
break;
case 0x68:
h8.h8TCNT[0] = (val<<8) | (h8.h8TCNT[0] & 0xff);
if (h8.h8TSTR & 1)
h8->h8TCNT[0] = (val<<8) | (h8->h8TCNT[0] & 0xff);
if (h8->h8TSTR & 1)
{
h8_itu_refresh_timer(0);
h8_itu_refresh_timer(h8, 0);
}
break;
case 0x69:
h8.h8TCNT[0] = (val) | (h8.h8TCNT[0] & 0xff00);
if (h8.h8TSTR & 1)
h8->h8TCNT[0] = (val) | (h8->h8TCNT[0] & 0xff00);
if (h8->h8TSTR & 1)
{
h8_itu_refresh_timer(0);
h8_itu_refresh_timer(h8, 0);
}
break;
case 0x72:
h8.h8TCNT[1] = (val<<8) | (h8.h8TCNT[1] & 0xff);
if (h8.h8TSTR & 2)
h8->h8TCNT[1] = (val<<8) | (h8->h8TCNT[1] & 0xff);
if (h8->h8TSTR & 2)
{
h8_itu_refresh_timer(1);
h8_itu_refresh_timer(h8, 1);
}
break;
case 0x73:
h8.h8TCNT[1] = (val) | (h8.h8TCNT[1] & 0xff00);
if (h8.h8TSTR & 2)
h8->h8TCNT[1] = (val) | (h8->h8TCNT[1] & 0xff00);
if (h8->h8TSTR & 2)
{
h8_itu_refresh_timer(1);
h8_itu_refresh_timer(h8, 1);
}
break;
case 0x7c:
h8.h8TCNT[2] = (val<<8) | (h8.h8TCNT[2] & 0xff);
if (h8.h8TSTR & 4)
h8->h8TCNT[2] = (val<<8) | (h8->h8TCNT[2] & 0xff);
if (h8->h8TSTR & 4)
{
h8_itu_refresh_timer(2);
h8_itu_refresh_timer(h8, 2);
}
break;
case 0x7d:
h8.h8TCNT[2] = (val) | (h8.h8TCNT[2] & 0xff00);
if (h8.h8TSTR & 4)
h8->h8TCNT[2] = (val) | (h8->h8TCNT[2] & 0xff00);
if (h8->h8TSTR & 4)
{
h8_itu_refresh_timer(2);
h8_itu_refresh_timer(h8, 2);
}
break;
case 0x86:
h8.h8TCNT[3] = (val<<8) | (h8.h8TCNT[3] & 0xff);
if (h8.h8TSTR & 8)
h8->h8TCNT[3] = (val<<8) | (h8->h8TCNT[3] & 0xff);
if (h8->h8TSTR & 8)
{
h8_itu_refresh_timer(3);
h8_itu_refresh_timer(h8, 3);
}
break;
case 0x87:
h8.h8TCNT[3] = (val) | (h8.h8TCNT[3] & 0xff00);
if (h8.h8TSTR & 8)
h8->h8TCNT[3] = (val) | (h8->h8TCNT[3] & 0xff00);
if (h8->h8TSTR & 8)
{
h8_itu_refresh_timer(3);
h8_itu_refresh_timer(h8, 3);
}
break;
case 0x96:
h8.h8TCNT[4] = (val<<8) | (h8.h8TCNT[4] & 0xff);
if (h8.h8TSTR & 0x10)
h8->h8TCNT[4] = (val<<8) | (h8->h8TCNT[4] & 0xff);
if (h8->h8TSTR & 0x10)
{
h8_itu_refresh_timer(4);
h8_itu_refresh_timer(h8, 4);
}
break;
case 0x97:
h8.h8TCNT[4] = (val) | (h8.h8TCNT[4] & 0xff00);
if (h8.h8TSTR & 0x10)
h8->h8TCNT[4] = (val) | (h8->h8TCNT[4] & 0xff00);
if (h8->h8TSTR & 0x10)
{
h8_itu_refresh_timer(4);
h8_itu_refresh_timer(h8, 4);
}
break;
default:
@ -253,26 +289,26 @@ UINT8 h8_debugger_itu_read8(UINT8 reg)
#endif
static UINT8 h8_ISR_r(void)
static UINT8 h8_ISR_r(h83xx_state *h8)
{
UINT8 res = 0;
int i;
for (i = 0; i < 6; i++)
if (h8.h8_IRQrequestL & (1 << (12+i))) res |= (1 << i);
if (h8->h8_IRQrequestL & (1 << (12+i))) res |= (1 << i);
return res;
}
static void h8_ISR_w(UINT8 val)
static void h8_ISR_w(h83xx_state *h8, UINT8 val)
{
int i;
for (i = 0; i < 6; i++)
if ((~val) & (1 << i)) h8.h8_IRQrequestL &= ~(1 << (12+i));
if ((~val) & (1 << i)) h8->h8_IRQrequestL &= ~(1 << (12+i));
}
UINT8 h8_register_read8(UINT32 address)
UINT8 h8_register_read8(h83xx_state *h8, UINT32 address)
{
UINT8 val;
UINT8 reg;
@ -283,25 +319,25 @@ UINT8 h8_register_read8(UINT32 address)
if(reg >= 0x60 && reg <= 0x9f)
{
return h8_itu_read8(reg);
return h8_itu_read8(h8, reg);
}
else
{
switch(reg)
{
case 0xb4: // serial port A status
val = h8.per_regs[reg];
val = h8->per_regs[reg];
val |= 0xc4; // transmit finished, receive ready, no errors
break;
case 0xb5: // serial port A receive
val = io_read_byte(H8_SERIAL_A);
val = io_read_byte(H8_SERIAL_0);
break;
case 0xbc: // serial port B status
val = h8.per_regs[reg];
val = h8->per_regs[reg];
val |= 0xc4; // transmit finished, receive ready, no errors
break;
case 0xbd: // serial port B receive
val = io_read_byte(H8_SERIAL_B);
val = io_read_byte(H8_SERIAL_1);
break;
case 0xe0:
val = io_read_byte(H8_ADC_0_H);
@ -331,32 +367,32 @@ UINT8 h8_register_read8(UINT32 address)
val = 0x80;
break;
case 0xc7: // port 4 data
val = io_read_byte(H8_PORT4);
val = io_read_byte(H8_PORT_4);
break;
case 0xcb: // port 6 data
val = io_read_byte(H8_PORT6);
val = io_read_byte(H8_PORT_6);
break;
case 0xce: // port 7 data
val = io_read_byte(H8_PORT7);
val = io_read_byte(H8_PORT_7);
break;
case 0xcf: // port 8 data
val = io_read_byte(H8_PORT8);
val = io_read_byte(H8_PORT_8);
break;
case 0xd2: // port 9 data
val = io_read_byte(H8_PORT9);
val = io_read_byte(H8_PORT_9);
break;
case 0xd3: // port a data
val = io_read_byte(H8_PORTA);
val = io_read_byte(H8_PORT_A);
break;
case 0xd6: // port b data
val = io_read_byte(H8_PORTB);
val = io_read_byte(H8_PORT_B);
break;
case 0xf6:
val = h8_ISR_r();
val = h8_ISR_r(h8);
break;
default:
val = h8.per_regs[reg];
val = h8->per_regs[reg];
break;
}
}
@ -364,7 +400,7 @@ UINT8 h8_register_read8(UINT32 address)
return val;
}
void h8_register_write8(UINT32 address, UINT8 val)
void h8_register_write8(h83xx_state *h8, UINT32 address, UINT8 val)
{
UINT8 reg;
@ -374,167 +410,189 @@ void h8_register_write8(UINT32 address, UINT8 val)
if(reg >= 0x60 && reg <= 0x9f)
{
h8_itu_write8(reg, val);
h8_itu_write8(h8, reg, val);
}
switch (reg)
{
case 0xb3:
io_write_byte(H8_SERIAL_A, val);
io_write_byte(H8_SERIAL_0, val);
break;
case 0xbb:
io_write_byte(H8_SERIAL_B, val);
io_write_byte(H8_SERIAL_1, val);
break;
case 0xc7:
io_write_byte(H8_PORT4, val);
io_write_byte(H8_PORT_4, val);
break;
case 0xcb: // port 6 data
io_write_byte(H8_PORT6, val);
io_write_byte(H8_PORT_6, val);
break;
case 0xce: // port 7 data
io_write_byte(H8_PORT7, val);
io_write_byte(H8_PORT_7, val);
break;
case 0xcf: // port 8 data
io_write_byte(H8_PORT8, val);
io_write_byte(H8_PORT_8, val);
break;
case 0xd2: // port 9 data
io_write_byte(H8_PORT9, val);
io_write_byte(H8_PORT_9, val);
break;
case 0xd3: // port a data
io_write_byte(H8_PORTA, val);
io_write_byte(H8_PORT_A, val);
break;
case 0xd6: // port b data
io_write_byte(H8_PORTB, val);
io_write_byte(H8_PORT_B, val);
break;
case 0xf6:
h8_ISR_w(val);
h8_ISR_w(h8, val);
break;
}
h8.per_regs[reg] = val;
h8->per_regs[reg] = val;
}
static void h8_3007_itu_refresh_timer(int tnum)
static void h8_3007_itu_refresh_timer(h83xx_state *h8, int tnum)
{
attotime period;
int ourTCR = h8.per_regs[0x68+(tnum*8)];
int ourTCR = h8->per_regs[0x68+(tnum*8)];
period = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8.cpu_number])), tscales[ourTCR & 3]);
period = attotime_mul(ATTOTIME_IN_HZ(cpu_get_clock(Machine->cpu[h8->cpu_number])), tscales[ourTCR & 3]);
if (ourTCR & 4)
{
logerror("H8/3007: Timer %d is using an external clock. Unsupported!\n", tnum);
}
timer_adjust_oneshot(h8.timer[tnum], period, 0);
timer_adjust_oneshot(h8->timer[tnum], period, 0);
}
static TIMER_CALLBACK( h8itu_3007_timer_cb )
static void h8itu_3007_timer_expire(h83xx_state *h8, int tnum)
{
int tnum = (int)(FPTR)ptr;
int base = 0x68 + (tnum*8);
UINT16 count = (h8.per_regs[base + 0x2]<<8) | h8.per_regs[base + 0x3];
UINT16 count;
count = (h8->per_regs[base + 0x2]<<8) | h8->per_regs[base + 0x3];
count++;
//logerror("h8/3007 timer %d count = %04x\n",tnum,count);
// GRA match
if ((h8.per_regs[base + 0x1] & 0x03) && (count == ((h8.per_regs[base + 0x4]<<8) | h8.per_regs[base + 0x5])))
if ((h8->per_regs[base + 0x1] & 0x03) && (count == ((h8->per_regs[base + 0x4]<<8) | h8->per_regs[base + 0x5])))
{
if ((h8.per_regs[base + 0x0] & 0x60) == 0x20)
if ((h8->per_regs[base + 0x0] & 0x60) == 0x20)
{
//logerror("h8/3007 timer %d GRA match, restarting\n",tnum);
count = 0;
h8_3007_itu_refresh_timer(tnum);
h8_3007_itu_refresh_timer(h8, tnum);
}
else
{
//logerror("h8/3007 timer %d GRA match, stopping\n",tnum);
timer_adjust_oneshot(h8.timer[tnum], attotime_never, 0);
timer_adjust_oneshot(h8->timer[tnum], attotime_never, 0);
}
h8.per_regs[0x64] |= 1<<tnum;
if(h8.per_regs[0x64] & (4<<tnum)) // interrupt enable
h8->per_regs[0x64] |= 1<<tnum;
if(h8->per_regs[0x64] & (4<<tnum)) // interrupt enable
{
//logerror("h8/3007 timer %d GRA INTERRUPT\n",tnum);
h8_3002_InterruptRequest(24+tnum*4);
h8_3002_InterruptRequest(h8, 24+tnum*4);
}
}
// GRB match
if ((h8.per_regs[base + 0x1] & 0x30) && (count == ((h8.per_regs[base + 0x6]<<8) | h8.per_regs[base + 0x7])))
if ((h8->per_regs[base + 0x1] & 0x30) && (count == ((h8->per_regs[base + 0x6]<<8) | h8->per_regs[base + 0x7])))
{
if ((h8.per_regs[base + 0x0] & 0x60) == 0x40)
if ((h8->per_regs[base + 0x0] & 0x60) == 0x40)
{
//logerror("h8/3007 timer %d GRB match, restarting\n",tnum);
count = 0;
h8_3007_itu_refresh_timer(tnum);
h8_3007_itu_refresh_timer(h8, tnum);
}
else
{
//logerror("h8/3007 timer %d GRB match, stopping\n",tnum);
timer_adjust_oneshot(h8.timer[tnum], attotime_never, 0);
timer_adjust_oneshot(h8->timer[tnum], attotime_never, 0);
}
h8.per_regs[0x65] |= 1<<tnum;
if(h8.per_regs[0x65] & (4<<tnum)) // interrupt enable
h8->per_regs[0x65] |= 1<<tnum;
if(h8->per_regs[0x65] & (4<<tnum)) // interrupt enable
{
//logerror("h8/3007 timer %d GRB INTERRUPT\n",tnum);
h8_3002_InterruptRequest(25+tnum*4);
h8_3002_InterruptRequest(h8, 25+tnum*4);
}
}
// Overflow
if (((h8.per_regs[base + 0x1] & 0x33) == 0) && (count == 0))
if (((h8->per_regs[base + 0x1] & 0x33) == 0) && (count == 0))
{
//logerror("h8/3007 timer %d OVF match, restarting\n",tnum);
h8.per_regs[0x66] |= 1<<tnum;
if(h8.per_regs[0x66] & (4<<tnum)) // interrupt enable
h8->per_regs[0x66] |= 1<<tnum;
if(h8->per_regs[0x66] & (4<<tnum)) // interrupt enable
{
//logerror("h8/3007 timer %d OVF INTERRUPT\n",tnum);
h8_3002_InterruptRequest(26+tnum*4);
h8_3002_InterruptRequest(h8, 26+tnum*4);
}
}
h8.per_regs[base + 0x2] = count >> 8;
h8.per_regs[base + 0x3] = count & 0xff;
h8->per_regs[base + 0x2] = count >> 8;
h8->per_regs[base + 0x3] = count & 0xff;
}
UINT8 h8_3007_itu_read8(UINT8 reg)
static TIMER_CALLBACK( h8itu_3007_timer_0_cb )
{
h83xx_state *h8 = (h83xx_state *)ptr;
h8itu_3007_timer_expire(h8, 0);
}
static TIMER_CALLBACK( h8itu_3007_timer_1_cb )
{
h83xx_state *h8 = (h83xx_state *)ptr;
h8itu_3007_timer_expire(h8, 1);
}
static TIMER_CALLBACK( h8itu_3007_timer_2_cb )
{
h83xx_state *h8 = (h83xx_state *)ptr;
h8itu_3007_timer_expire(h8, 2);
}
UINT8 h8_3007_itu_read8(h83xx_state *h8, UINT8 reg)
{
UINT8 val;
switch(reg)
{
case 0x60:
val = h8.h8TSTR | 0xf8;
val = h8->h8TSTR | 0xf8;
break;
default:
val = h8.per_regs[reg];
val = h8->per_regs[reg];
break;
}
return val;
}
void h8_3007_itu_write8(UINT8 reg, UINT8 val)
void h8_3007_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val)
{
//logerror("%06x: h8/3007 reg %02x = %02x\n",cpu_get_pc(machine->activecpu),reg,val);
h8.per_regs[reg] = val;
h8->per_regs[reg] = val;
switch(reg)
{
case 0x60:
if ((val & 1) && !(h8.h8TSTR & 1))
if ((val & 1) && !(h8->h8TSTR & 1))
{
h8_3007_itu_refresh_timer(0);
h8_3007_itu_refresh_timer(h8, 0);
}
if ((val & 2) && !(h8.h8TSTR & 2))
if ((val & 2) && !(h8->h8TSTR & 2))
{
h8_3007_itu_refresh_timer(1);
h8_3007_itu_refresh_timer(h8, 1);
}
if ((val & 4) && !(h8.h8TSTR & 4))
if ((val & 4) && !(h8->h8TSTR & 4))
{
h8_3007_itu_refresh_timer(2);
h8_3007_itu_refresh_timer(h8, 2);
}
h8.h8TSTR = val;
h8->h8TSTR = val;
break;
default:
val = 0;
@ -542,7 +600,7 @@ void h8_3007_itu_write8(UINT8 reg, UINT8 val)
}
}
UINT8 h8_3007_register_read8(UINT32 address)
UINT8 h8_3007_register_read8(h83xx_state *h8, UINT32 address)
{
UINT8 val;
UINT8 reg;
@ -553,25 +611,25 @@ UINT8 h8_3007_register_read8(UINT32 address)
if(reg >= 0x60 && reg <= 0x7f)
{
return h8_3007_itu_read8(reg);
return h8_3007_itu_read8(h8, reg);
}
else
{
switch(reg)
{
case 0xb4: // serial port A status
val = h8.per_regs[reg];
val = h8->per_regs[reg];
val |= 0xc4; // transmit finished, receive ready, no errors
break;
case 0xb5: // serial port A receive
val = io_read_byte(H8_SERIAL_A);
val = io_read_byte(H8_SERIAL_0);
break;
case 0xbc: // serial port B status
val = h8.per_regs[reg];
val = h8->per_regs[reg];
val |= 0xc4; // transmit finished, receive ready, no errors
break;
case 0xbd: // serial port B receive
val = io_read_byte(H8_SERIAL_B);
val = io_read_byte(H8_SERIAL_1);
break;
case 0xe0:
val = io_read_byte(H8_ADC_0_H);
@ -602,28 +660,28 @@ UINT8 h8_3007_register_read8(UINT32 address)
break;
case 0xd3: // port 4 data
val = io_read_byte(H8_PORT4);
val = io_read_byte(H8_PORT_4);
break;
case 0xd5: // port 6 data
val = io_read_byte(H8_PORT6);
val = io_read_byte(H8_PORT_6);
break;
case 0xd6: // port 7 data
val = io_read_byte(H8_PORT7);
val = io_read_byte(H8_PORT_7);
break;
case 0xd7: // port 8 data
val = io_read_byte(H8_PORT8);
val = io_read_byte(H8_PORT_8);
break;
case 0xd8: // port 9 data
val = io_read_byte(H8_PORT9);
val = io_read_byte(H8_PORT_9);
break;
case 0xd9: // port a data
val = io_read_byte(H8_PORTA);
val = io_read_byte(H8_PORT_A);
break;
case 0xda: // port b data
val = io_read_byte(H8_PORTB);
val = io_read_byte(H8_PORT_B);
break;
default:
val = h8.per_regs[reg];
val = h8->per_regs[reg];
break;
}
}
@ -631,7 +689,7 @@ UINT8 h8_3007_register_read8(UINT32 address)
return val;
}
void h8_3007_register_write8(UINT32 address, UINT8 val)
void h8_3007_register_write8(h83xx_state *h8, UINT32 address, UINT8 val)
{
UINT8 reg;
@ -639,98 +697,98 @@ void h8_3007_register_write8(UINT32 address, UINT8 val)
reg = address & 0xff;
h8.per_regs[reg] = val;
h8->per_regs[reg] = val;
if(reg >= 0x60 && reg <= 0x7f)
{
h8_3007_itu_write8(reg, val);
h8_3007_itu_write8(h8, reg, val);
}
else
{
switch (reg)
{
case 0xb3:
io_write_byte(H8_SERIAL_A, val);
io_write_byte(H8_SERIAL_0, val);
break;
case 0xbb:
io_write_byte(H8_SERIAL_B, val);
io_write_byte(H8_SERIAL_1, val);
break;
case 0xd3:
io_write_byte(H8_PORT4, val);
io_write_byte(H8_PORT_4, val);
break;
case 0xd5: // port 6 data
io_write_byte(H8_PORT6, val);
io_write_byte(H8_PORT_6, val);
break;
case 0xd6: // port 7 data
io_write_byte(H8_PORT7, val);
io_write_byte(H8_PORT_7, val);
break;
case 0xd7: // port 8 data
io_write_byte(H8_PORT8, val);
io_write_byte(H8_PORT_8, val);
break;
case 0xd8: // port 9 data
io_write_byte(H8_PORT9, val);
io_write_byte(H8_PORT_9, val);
break;
case 0xd9: // port a data
io_write_byte(H8_PORTA, val);
io_write_byte(H8_PORT_A, val);
break;
case 0xda: // port b data
io_write_byte(H8_PORTB, val);
io_write_byte(H8_PORT_B, val);
break;
}
}
}
UINT8 h8_3007_register1_read8(UINT32 address)
UINT8 h8_3007_register1_read8(h83xx_state *h8, UINT32 address)
{
switch (address)
{
case 0xfee012: return h8.per_regs[0xF2]; // SYSCR
case 0xfee016: return h8_ISR_r(); // ISR
case 0xfee018: return h8.per_regs[0xF8]; // IPRA
case 0xfee012: return h8->per_regs[0xF2]; // SYSCR
case 0xfee016: return h8_ISR_r(h8); // ISR
case 0xfee018: return h8->per_regs[0xF8]; // IPRA
}
logerror("cpu #%d (PC=%08X): unmapped I/O(1) byte read from %08X\n",cpunum_get_active(),cpu_get_pc(Machine->activecpu),address);
return 0;
}
void h8_3007_register1_write8(UINT32 address, UINT8 val)
void h8_3007_register1_write8(h83xx_state *h8, UINT32 address, UINT8 val)
{
switch (address)
{
case 0xfee012: h8.per_regs[0xF2] = val; return; // SYSCR
case 0xfee016: h8_ISR_w(val); return; // ISR
case 0xfee018: h8.per_regs[0xF8] = val; return; // IPRA
case 0xfee012: h8->per_regs[0xF2] = val; return; // SYSCR
case 0xfee016: h8_ISR_w(h8, val); return; // ISR
case 0xfee018: h8->per_regs[0xF8] = val; return; // IPRA
}
logerror("cpu #%d (PC=%08X): unmapped I/O(1) byte write to %08X = %02X\n",cpunum_get_active(),cpu_get_pc(Machine->activecpu),address,val);
}
void h8_3007_itu_init(void)
void h8_3007_itu_init(h83xx_state *h8)
{
int i;
h8->timer[0] = timer_alloc(h8itu_3007_timer_0_cb, h8);
h8->timer[1] = timer_alloc(h8itu_3007_timer_1_cb, h8);
h8->timer[2] = timer_alloc(h8itu_3007_timer_2_cb, h8);
for (i=0; i<3; i++)
h8.timer[i] = timer_alloc(h8itu_3007_timer_cb, (void*)(FPTR)i);
h8_itu_reset();
h8_itu_reset(h8);
}
void h8_itu_init(void)
void h8_itu_init(h83xx_state *h8)
{
int i;
h8->timer[0] = timer_alloc(h8itu_timer_0_cb, h8);
h8->timer[1] = timer_alloc(h8itu_timer_1_cb, h8);
h8->timer[2] = timer_alloc(h8itu_timer_2_cb, h8);
h8->timer[3] = timer_alloc(h8itu_timer_3_cb, h8);
h8->timer[4] = timer_alloc(h8itu_timer_4_cb, h8);
for (i=0; i<5; i++)
h8.timer[i] = timer_alloc(h8itu_timer_cb, (void*)(FPTR)i);
h8_itu_reset(h8);
h8_itu_reset();
h8.cpu_number = cpunum_get_active();
h8->cpu_number = cpunum_get_active();
}
void h8_itu_reset(void)
void h8_itu_reset(h83xx_state *h8)
{
int i;
// stop all the timers
for (i=0; i<5; i++)
timer_adjust_oneshot(h8.timer[i], attotime_never, 0);
timer_adjust_oneshot(h8->timer[i], attotime_never, 0);
}

View File

@ -9,14 +9,16 @@
#ifndef __H8PRIV_H__
#define __H8PRIV_H__
typedef struct _h83002_state h83002_state;
struct _h83002_state
typedef struct _h83xx_state h83xx_state;
struct _h83xx_state
{
// main CPU stuff
UINT32 h8err;
UINT32 regs[8];
UINT32 pc, ppc;
UINT32 h8_IRQrequestH, h8_IRQrequestL;
INT32 cyccnt;
UINT8 ccr;
UINT8 h8nflag, h8vflag, h8cflag, h8zflag, h8iflag, h8hflag;
@ -35,24 +37,24 @@ struct _h83002_state
emu_timer *timer[5];
int cpu_number;
int h8300_mode;
};
extern h83xx_state h8;
extern h83002_state h8;
UINT8 h8_register_read8(UINT32 address);
UINT8 h8_3007_register_read8(UINT32 address);
UINT8 h8_3007_register1_read8(UINT32 address);
void h8_register_write8(UINT32 address, UINT8 val);
void h8_3007_register_write8(UINT32 address, UINT8 val);
void h8_3007_register1_write8(UINT32 address, UINT8 val);
UINT8 h8_register_read8(h83xx_state *h8, UINT32 address);
UINT8 h8_3007_register_read8(h83xx_state *h8, UINT32 address);
UINT8 h8_3007_register1_read8(h83xx_state *h8, UINT32 address);
void h8_register_write8(h83xx_state *h8, UINT32 address, UINT8 val);
void h8_3007_register_write8(h83xx_state *h8, UINT32 address, UINT8 val);
void h8_3007_register1_write8(h83xx_state *h8, UINT32 address, UINT8 val);
void h8_itu_init(void);
void h8_3007_itu_init(void);
void h8_itu_reset(void);
UINT8 h8_itu_read8(UINT8 reg);
UINT8 h8_3007_itu_read8(UINT8 reg);
void h8_itu_write8(UINT8 reg, UINT8 val);
void h8_3007_itu_write8(UINT8 reg, UINT8 val);
void h8_itu_init(h83xx_state *h8);
void h8_3007_itu_init(h83xx_state *h8);
void h8_itu_reset(h83xx_state *h8);
UINT8 h8_itu_read8(h83xx_state *h8, UINT8 reg);
UINT8 h8_3007_itu_read8(h83xx_state *h8, UINT8 reg);
void h8_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val);
void h8_3007_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val);
#endif /* __H8PRIV_H__ */

View File

@ -209,6 +209,7 @@ CPU_GET_INFO( i960 );
CPU_GET_INFO( h8_3002 );
CPU_GET_INFO( h8_3007 );
CPU_GET_INFO( h8_3044 );
CPU_GET_INFO( h8_3344 );
CPU_GET_INFO( v810 );
CPU_GET_INFO( m37702 );
CPU_GET_INFO( m37710 );
@ -745,6 +746,9 @@ static const struct
#if (HAS_I960)
{ CPU_I960, CPU_GET_INFO_NAME(i960) },
#endif
#if (HAS_H83344)
{ CPU_H83344, CPU_GET_INFO_NAME(h8_3344) },
#endif
#if (HAS_H83002)
{ CPU_H83002, CPU_GET_INFO_NAME(h8_3002) },
{ CPU_H83007, CPU_GET_INFO_NAME(h8_3007) },

View File

@ -375,6 +375,7 @@ enum _cpu_type
CPU_H83002,
CPU_H83007,
CPU_H83044,
CPU_H83344,
CPU_V810,
CPU_M37702,
CPU_M37710,

View File

@ -47,7 +47,7 @@ Notes:
#include "driver.h"
#include "deprecat.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
#define BISHJAN_DEBUG 0
@ -435,7 +435,7 @@ static INTERRUPT_GEN( bishjan_interrupt )
cpu_set_input_line(device, 0, PULSE_LINE);
break;
default:
h8_3002_InterruptRequest(24);
cpu_set_input_line(device->machine->cpu[0], H8_METRO_TIMER_HACK, HOLD_LINE);
break;
}
}

View File

@ -52,7 +52,7 @@
#define SND_CLOCK XTAL_14_31818MHz
#include "driver.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
#include "sound/upd7759.h"

View File

@ -41,7 +41,7 @@
#define MAIN_CLOCK XTAL_16MHz
#include "driver.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
#include "sound/okim6295.h"

View File

@ -54,7 +54,7 @@
#define EJOLLYX5_MAIN_CLOCK XTAL_16MHz
#include "driver.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
#include "sound/okim6295.h"

View File

@ -64,7 +64,7 @@ Notes:
#include "driver.h"
#include "deprecat.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
/***************************************************************************
Video Hardware
@ -455,7 +455,7 @@ static INTERRUPT_GEN( unknown_interrupt )
cpu_set_input_line(device, 0, PULSE_LINE);
break;
default:
h8_3002_InterruptRequest(24);
cpu_set_input_line(device->machine->cpu[0], H8_METRO_TIMER_HACK, HOLD_LINE);
break;
}
}

View File

@ -82,7 +82,7 @@ driver modified by Eisuke Watanabe
#include "driver.h"
#include "deprecat.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
#include "cpu/upd7810/upd7810.h"
#include "machine/eeprom.h"
#include "video/konamiic.h"
@ -2188,9 +2188,9 @@ static WRITE8_HANDLER( puzzlet_portb_w )
}
static ADDRESS_MAP_START( puzzlet_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE( H8_PORT7, H8_PORT7 ) AM_READ_PORT("IN2")
AM_RANGE( H8_SERIAL_B, H8_SERIAL_B ) AM_READ_PORT("IN0") // coin
AM_RANGE( H8_PORTB, H8_PORTB ) AM_READ_PORT("DSW0") AM_WRITE( puzzlet_portb_w )
AM_RANGE( H8_PORT_7, H8_PORT_7 ) AM_READ_PORT("IN2")
AM_RANGE( H8_SERIAL_1, H8_SERIAL_1 ) AM_READ_PORT("IN0") // coin
AM_RANGE( H8_PORT_B, H8_PORT_B ) AM_READ_PORT("DSW0") AM_WRITE( puzzlet_portb_w )
ADDRESS_MAP_END
@ -4693,7 +4693,7 @@ static INTERRUPT_GEN( puzzlet_interrupt )
default:
// timer
h8_3002_InterruptRequest(24);
cpu_set_input_line(device->machine->cpu[0], H8_METRO_TIMER_HACK, HOLD_LINE);
break;
}
}

View File

@ -67,7 +67,7 @@ Notes:
#include "driver.h"
#include "video/ygv608.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
#include "namcond1.h"
#include "sound/c352.h"
#include "machine/at28c16.h"
@ -259,8 +259,8 @@ static ADDRESS_MAP_START( nd1h8rwmap, ADDRESS_SPACE_PROGRAM, 16 )
ADDRESS_MAP_END
static ADDRESS_MAP_START( nd1h8iomap, ADDRESS_SPACE_IO, 8 )
AM_RANGE(H8_PORT7, H8_PORT7) AM_READ( mcu_p7_read )
AM_RANGE(H8_PORTA, H8_PORTA) AM_READWRITE( mcu_pa_read, mcu_pa_write )
AM_RANGE(H8_PORT_7, H8_PORT_7) AM_READ( mcu_p7_read )
AM_RANGE(H8_PORT_A, H8_PORT_A) AM_READWRITE( mcu_pa_read, mcu_pa_write )
AM_RANGE(H8_ADC_0_L, H8_ADC_3_H) AM_NOP // MCU reads these, but the games have no analog controls
ADDRESS_MAP_END

View File

@ -924,7 +924,7 @@ Notes:
#include "driver.h"
#include "deprecat.h"
#include "cpu/mips/psx.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
#include "includes/psx.h"
#include "machine/at28c16.h"
#include "sound/c352.h"
@ -1421,11 +1421,11 @@ static READ8_HANDLER( s12_mcu_gun_v_r )
}
static ADDRESS_MAP_START( s12h8iomap, ADDRESS_SPACE_IO, 8 )
AM_RANGE(H8_PORT7, H8_PORT7) AM_READ_PORT("DSW")
AM_RANGE(H8_PORT8, H8_PORT8) AM_READ( s12_mcu_p8_r ) AM_WRITENOP
AM_RANGE(H8_PORTA, H8_PORTA) AM_READWRITE( s12_mcu_pa_r, s12_mcu_pa_w )
AM_RANGE(H8_PORTB, H8_PORTB) AM_READWRITE( s12_mcu_portB_r, s12_mcu_portB_w )
AM_RANGE(H8_SERIAL_B, H8_SERIAL_B) AM_READ( s12_mcu_rtc_r ) AM_WRITE( s12_mcu_settings_w )
AM_RANGE(H8_PORT_7, H8_PORT_7) AM_READ_PORT("DSW")
AM_RANGE(H8_PORT_8, H8_PORT_8) AM_READ( s12_mcu_p8_r ) AM_WRITENOP
AM_RANGE(H8_PORT_A, H8_PORT_A) AM_READWRITE( s12_mcu_pa_r, s12_mcu_pa_w )
AM_RANGE(H8_PORT_B, H8_PORT_B) AM_READWRITE( s12_mcu_portB_r, s12_mcu_portB_w )
AM_RANGE(H8_SERIAL_1, H8_SERIAL_1) AM_READ( s12_mcu_rtc_r ) AM_WRITE( s12_mcu_settings_w )
AM_RANGE(H8_ADC_0_H, H8_ADC_0_L) AM_NOP
AM_RANGE(H8_ADC_1_H, H8_ADC_1_L) AM_READ( s12_mcu_gun_h_r ) // golgo 13 gun X-axis
AM_RANGE(H8_ADC_2_H, H8_ADC_2_L) AM_READ( s12_mcu_gun_v_r ) // golgo 13 gun Y-axis

View File

@ -2,27 +2,32 @@
Namco System 22.5 and (Super) System 23
Extremely preliminary driver by R. Belmont, thanks to Phil Stroffolino & Olivier Galibert
Hardware: R4650 (MIPS III with IDT special instructions) main CPU @ 166 MHz
H8/3002 MCU for sound/inputs
Custom polygon hardware
1 text tilemap
Sprites?
Hardware: * R4650 (MIPS III with IDT special instructions) main CPU.
133 MHz for Gorgon, 166 MHz for System 23 and Super System 23, and
200 MHz for Super System 23 Evolution 2.
* H8/3002 MCU for sound/inputs
* Custom polygon hardware
* 1 text tilemap
Gorgon and System 23 use an I/O board based on the Namco C78, which is a Renesas H8/3334 MCU
(8-bit version of the H8/3002).
Super System 23 uses a PIC16Cxx-based I/O board. In both cases the I/O boards' MCUs apparently are connected
to the H8/3002's serial port, similar to System 22 where one 37702 reads the I/O and communicates serially
with the second 37702 which is the traditional "subcpu".
NOTES:
- First 128k of main program ROM is the BIOS, and after that is a 64-bit MIPS ELF image.
- Text layer is (almost?) identical to System 22 & Super System 22.
TODO:
- Palette is not right.
- H8/3002 does not handshake. Protocol should be the same as System 12 where the MIPS
writes 0x3163 to offset 0x3002 in the shared RAM and the H8/3002 notices and sets it to 0x7106.
The H8 currently never reads that location (core bug?).
- H8/3002 does not handshake. Looks like it needs to speak serially with the I/O board.
- Hook up actual inputs via the 2 serial latches at d00004 and d00006.
- Hook up actual inputs (?) via the 2 serial latches at d00004 and d00006.
Works like this: write to d00004, then read d00004 12 times. Ditto at
d00006. This gives 24 bits of inputs from the I/O board (?).
d00006. This gives 24 bits of inputs (?) from the I/O board (?).
- The entire 3D subsystem. Is there a DSP living down there? If not, why the 300k
download on initial startup?
@ -45,15 +50,15 @@ Note! This document is a Work-In-Progress and will be updated from time to time
This document covers all the known Namco System 23 / Super System 23 games, including....
*Angler King Namco, 1999 System 23
*Final Furlong Namco, 1997 System 23
*Gunmen Wars Namco, 1998 System 23
*Motocross Go! Namco, 1997 System 23
Gunmen Wars Namco, 1998 System 23 [not dumped, but have]
Motocross Go! Namco, 1997 System 23
*Panic Park Namco, 1998 System 23
Rapid River Namco, 1997 System 22.5/Gorgon
Time Crisis II Namco, 1997 System 23
*Underground King Namco, 1998 System 23
*Downhill Bikers Namco, 199? System 23
GP 500 Namco, 1999 Super System 23
Crisis Zone Namco, 2000 Super System 23 [not dumped, but have]
500 GP Namco, 1999 Super System 23
Crisis Zone Namco, 2000 Super System 23 Evolution 2 [not dumped, but have]
Final Furlong 2 Namco, 1999 Super System 23
*Guitar Jam Namco, 1999 Super System 23
*Race On! Namco, 1998 Super System 23
@ -732,7 +737,7 @@ Notes:
#include "driver.h"
#include "cpu/mips/mips3.h"
#include "cpu/h83002/h83002.h"
#include "cpu/h83002/h8.h"
#include "sound/c352.h"
static int ss23_vstat = 0, hstat = 0, vstate = 0;
@ -1055,7 +1060,7 @@ static ADDRESS_MAP_START( ss23_map, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x06a30000, 0x06a3ffff) AM_RAM
AM_RANGE(0x06820008, 0x0682000f) AM_READ( ss23_vstat_r ) // vblank status?
AM_RANGE(0x08000000, 0x08017fff) AM_RAM
AM_RANGE(0x0d000000, 0x0d000007) AM_READ(sysctl_stat_r)
AM_RANGE(0x0d000000, 0x0d000007) AM_READ(sysctl_stat_r) AM_WRITENOP
AM_RANGE(0x0fc00000, 0x0fffffff) AM_WRITENOP AM_ROM AM_REGION("user1", 0)
AM_RANGE(0x1fc00000, 0x1fffffff) AM_WRITENOP AM_ROM AM_REGION("user1", 0)
ADDRESS_MAP_END
@ -1074,6 +1079,15 @@ static READ16_HANDLER( sharedram_sub_r )
return shared16[BYTE_XOR_BE(offset)];
}
#if 1
static WRITE16_HANDLER(cause_sync_w)
{
UINT16 *shared16 = (UINT16 *)namcos23_shared_ram;
shared16[BYTE_XOR_BE(0x4052/2)] = 0;
}
#endif
/* H8/3002 MCU stuff */
static ADDRESS_MAP_START( s23h8rwmap, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM)
@ -1082,7 +1096,7 @@ static ADDRESS_MAP_START( s23h8rwmap, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x300000, 0x300001) AM_READNOP //AM_READ_PORT("IN1")
AM_RANGE(0x300002, 0x300003) AM_READNOP //AM_READ_PORT("IN2")
AM_RANGE(0x300010, 0x300011) AM_NOP
AM_RANGE(0x300030, 0x300031) AM_NOP
AM_RANGE(0x300030, 0x300031) AM_WRITE(cause_sync_w) // cheats comms with I/O board and makes SUBCPU TEST pass
ADDRESS_MAP_END
static READ8_HANDLER( s23_mcu_p8_r )
@ -1200,11 +1214,11 @@ static WRITE8_HANDLER( s23_mcu_settings_w )
}
static ADDRESS_MAP_START( s23h8iomap, ADDRESS_SPACE_IO, 8 )
AM_RANGE(H8_PORT7, H8_PORT7) AM_READ( input_port_0_r )
AM_RANGE(H8_PORT8, H8_PORT8) AM_READ( s23_mcu_p8_r ) AM_WRITENOP
AM_RANGE(H8_PORTA, H8_PORTA) AM_READWRITE( s23_mcu_pa_r, s23_mcu_pa_w )
AM_RANGE(H8_PORTB, H8_PORTB) AM_READWRITE( s23_mcu_portB_r, s23_mcu_portB_w )
AM_RANGE(H8_SERIAL_B, H8_SERIAL_B) AM_READ( s23_mcu_rtc_r ) AM_WRITE( s23_mcu_settings_w )
AM_RANGE(H8_PORT_7, H8_PORT_7) AM_READ( input_port_0_r )
AM_RANGE(H8_PORT_8, H8_PORT_8) AM_READ( s23_mcu_p8_r ) AM_WRITENOP
AM_RANGE(H8_PORT_A, H8_PORT_A) AM_READWRITE( s23_mcu_pa_r, s23_mcu_pa_w )
AM_RANGE(H8_PORT_B, H8_PORT_B) AM_READWRITE( s23_mcu_portB_r, s23_mcu_portB_w )
AM_RANGE(H8_SERIAL_1, H8_SERIAL_1) AM_READ( s23_mcu_rtc_r ) AM_WRITE( s23_mcu_settings_w )
AM_RANGE(H8_ADC_0_H, H8_ADC_0_L) AM_NOP
AM_RANGE(H8_ADC_1_H, H8_ADC_1_L) AM_NOP
AM_RANGE(H8_ADC_2_H, H8_ADC_2_L) AM_NOP
@ -1212,10 +1226,18 @@ static ADDRESS_MAP_START( s23h8iomap, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_END
/* H8/3334 (Namco C78) I/O board MCU */
static ADDRESS_MAP_START( s23iobrdmap, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x0fff) AM_READ(SMH_ROM)
AM_RANGE(0xc000, 0xdfff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( s23iobrdiomap, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_END
static DRIVER_INIT(ss23)
{
}
}
static const gfx_layout namcos23_cg_layout =
{
@ -1279,6 +1301,8 @@ static MACHINE_DRIVER_START( gorgon )
MDRV_CPU_IO_MAP( s23h8iomap, 0 )
MDRV_CPU_VBLANK_INT("main", irq1_line_pulse)
MDRV_INTERLEAVE(1000)
MDRV_SCREEN_ADD("main", RASTER)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
@ -1315,6 +1339,13 @@ static MACHINE_DRIVER_START( s23 )
MDRV_CPU_IO_MAP( s23h8iomap, 0 )
MDRV_CPU_VBLANK_INT("main", irq1_line_pulse)
MDRV_CPU_ADD("ioboard", H83344, 14745600 )
MDRV_CPU_PROGRAM_MAP( s23iobrdmap, 0 )
MDRV_CPU_IO_MAP( s23iobrdiomap, 0 )
MDRV_CPU_VBLANK_INT("main", irq1_line_pulse)
MDRV_INTERLEAVE(1000)
MDRV_SCREEN_ADD("main", RASTER)
MDRV_SCREEN_REFRESH_RATE(60)
@ -1353,6 +1384,8 @@ static MACHINE_DRIVER_START( ss23 )
MDRV_CPU_IO_MAP( s23h8iomap, 0 )
MDRV_CPU_VBLANK_INT("main", irq1_line_pulse)
MDRV_INTERLEAVE(1000)
MDRV_SCREEN_ADD("main", RASTER)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
@ -1436,6 +1469,53 @@ ROM_START( rapidrvr )
ROM_LOAD( "rd1waveh.3s", 0x800000, 0x800000, CRC(ef0136b5) SHA1(a6d923ededca168fe555e0b86a72f53bec5424cc) )
ROM_END
ROM_START( motoxgo )
ROM_REGION32_BE( 0x400000, "user1", 0 ) /* 4 megs for main R4650 code */
ROM_LOAD16_BYTE( "mg3vera.ic2", 0x000000, 0x200000, CRC(1bf06f00) SHA1(e9d04e9f19bff7a58cb280dd1d5db12801b68ba0) )
ROM_LOAD16_BYTE( "mg3vera.ic1", 0x000001, 0x200000, CRC(f5e6e25b) SHA1(1de30e8e831be66987112645a9db3a3001b89fe6) )
ROM_REGION( 0x80000, "audio", 0 ) /* Hitachi H8/3002 MCU code */
ROM_LOAD16_WORD_SWAP( "mg3vera.ic3", 0x000000, 0x080000, CRC(9e3d46a8) SHA1(9ffa5b91ea51cc0fb97def25ce47efa3441f3c6f) )
ROM_REGION( 0x40000, "ioboard", 0 ) /* I/O board HD643334 H8/3344 MCU code */
ROM_LOAD( "asca-3a.ic14", 0x000000, 0x040000, CRC(8e9266e5) SHA1(ffa8782ca641d71d57df23ed1c5911db05d3df97) )
ROM_REGION( 0x20000, "exioboard", 0 ) /* "extra" I/O board (uses Fujitsu MB90611A MCU) */
ROM_LOAD( "mg1prog0a.3a", 0x000000, 0x020000, CRC(b2b5be8f) SHA1(803652b7b8fde2196b7fb742ba8b9843e4fcd2de) )
ROM_REGION( 0x2000000, "sprite", ROMREGION_ERASEFF ) /* sprite? tilemap? tiles */
ROM_LOAD16_BYTE( "mg1mtal.2h", 0x000000, 0x800000, CRC(fdad0f0a) SHA1(420d50f012af40f80b196d3aae320376e6c32367) )
ROM_LOAD16_BYTE( "mg1mtah.2j", 0x000001, 0x800000, CRC(845f4768) SHA1(9c03b1f6dcd9d1f43c2958d855221be7f9415c47) )
ROM_REGION( 0x2000000, "textile", ROMREGION_ERASEFF ) /* texture tiles */
ROM_LOAD( "mg1cgum.4j", 0x000000, 0x800000, CRC(46a77d73) SHA1(132ce2452ee68ba374e98b59032ac0a1a277078d) )
ROM_LOAD( "mg1cgll.4m", 0x000000, 0x800000, CRC(175dfe34) SHA1(66ae35b0084159aea1afeb1a6486fffa635992b5) )
ROM_LOAD( "mg1cglm.4k", 0x000000, 0x800000, CRC(b3e648e7) SHA1(98018ae2276f905a7f74e1dab540a44247524436) )
ROM_REGION( 0x2000000, "textile2", ROMREGION_ERASEFF ) /* second copy of texture tiles */
ROM_LOAD( "mg1cgum.5j", 0x000000, 0x800000, CRC(46a77d73) SHA1(132ce2452ee68ba374e98b59032ac0a1a277078d) )
ROM_LOAD( "mg1cgll.5m", 0x000000, 0x800000, CRC(175dfe34) SHA1(66ae35b0084159aea1afeb1a6486fffa635992b5) )
ROM_LOAD( "mg1cglm.5k", 0x000000, 0x800000, CRC(b3e648e7) SHA1(98018ae2276f905a7f74e1dab540a44247524436) )
ROM_REGION( 0x600000, "textilemap", ROMREGION_ERASEFF ) /* texture tilemap */
ROM_LOAD( "mg1ccrl.7f", 0x000000, 0x400000, CRC(5372e300) SHA1(63a49782289ed93a321ca7d193241fb83ca97e6b) )
ROM_LOAD( "mg1ccrh.7e", 0x400000, 0x200000, CRC(2e77597d) SHA1(58dd83c1b0c08115e728c5e7dea5e62135b821ba) )
ROM_REGION( 0x600000, "textilemap2", ROMREGION_ERASEFF) /* second copy of texture tilemap */
ROM_LOAD( "mg1ccrl.7m", 0x000000, 0x400000, CRC(5372e300) SHA1(63a49782289ed93a321ca7d193241fb83ca97e6b) )
ROM_LOAD( "mg1ccrh.7k", 0x400000, 0x200000, CRC(2e77597d) SHA1(58dd83c1b0c08115e728c5e7dea5e62135b821ba) )
ROM_REGION32_LE( 0x2000000, "pointrom", ROMREGION_ERASEFF ) /* 3D model data */
ROM_LOAD32_WORD( "mg1pt0l.7c", 0x000000, 0x400000, CRC(3b9e95d3) SHA1(d7823ed6c590669ccd4098ed439599a3eb814ed1) )
ROM_LOAD32_WORD( "mg1pt0h.7a", 0x000002, 0x400000, CRC(c9ba1b47) SHA1(42ec0638edb4c502ff0a340c4cf590bdd767cfe2) )
ROM_LOAD32_WORD( "mg1pt1h.5a", 0x800000, 0x400000, CRC(8d4f7097) SHA1(004e9ed0b5d6ce83ffadb9bd429fa7560abdb598) )
ROM_LOAD32_WORD( "mg1pt1l.5c", 0x800002, 0x400000, CRC(0dd2f358) SHA1(3537e6be3fec9fec8d5a8dd02d9cf67b3805f8f0) )
ROM_REGION( 0x1000000, "c352", ROMREGION_ERASEFF ) /* C352 PCM samples */
ROM_LOAD( "mg1wavel.2c", 0x000000, 0x800000, CRC(f78b1b4d) SHA1(47cd654ec0a69de0dc81b8d83692eebf5611228b) )
ROM_LOAD( "mg1waveh.2a", 0x800000, 0x800000, CRC(8cb73877) SHA1(2e2b170c7ff889770c13b4ab7ac316b386ada153) )
ROM_END
ROM_START( timecrs2 )
ROM_REGION32_BE( 0x400000, "user1", 0 ) /* 4 megs for main R4650 code */
ROM_LOAD16_BYTE( "tss3verb.2", 0x000000, 0x200000, CRC(c7be691f) SHA1(5e2e7a0db3d8ce6dfeb6c0d99e9fe6a9f9cab467) )
@ -1444,6 +1524,9 @@ ROM_START( timecrs2 )
ROM_REGION( 0x80000, "audio", 0 ) /* Hitachi H8/3002 MCU code */
ROM_LOAD16_WORD_SWAP( "tss3verb.3", 0x000000, 0x080000, CRC(41e41994) SHA1(eabc1a307c329070bfc6486cb68169c94ff8a162) )
ROM_REGION( 0x40000, "ioboard", 0 ) /* I/O board HD643334 H8/3344 MCU code */
ROM_LOAD( "tssioprog.ic3", 0x000000, 0x040000, CRC(edad4538) SHA1(1330189184a636328d956c0e435f8d9ad2e96a80) )
ROM_REGION( 0x2000000, "sprite", 0 ) /* sprite? tilemap? tiles */
ROM_LOAD16_BYTE( "tss1mtal.2h", 0x0000000, 0x800000, CRC(bfc79190) SHA1(04bda00c4cc5660d27af4f3b0ee3550dea8d3805) )
ROM_LOAD16_BYTE( "tss1mtah.2j", 0x0000001, 0x800000, CRC(697c26ed) SHA1(72f6f69e89496ba0c6183b35c3bde71f5a3c721f) )
@ -1481,7 +1564,7 @@ ROM_START( timcrs2b )
ROM_REGION( 0x80000, "audio", 0 ) /* Hitachi H8/3002 MCU code */
ROM_LOAD16_WORD_SWAP( "tss3verb.3", 0x000000, 0x080000, CRC(41e41994) SHA1(eabc1a307c329070bfc6486cb68169c94ff8a162) )
ROM_REGION( 0x40000, "ioboard", 0 ) /* I/O board HD643334 H8/300 MCU code */
ROM_REGION( 0x40000, "ioboard", 0 ) /* I/O board HD643334 H8/3344 MCU code */
ROM_LOAD( "tssioprog.ic3", 0x000000, 0x040000, CRC(edad4538) SHA1(1330189184a636328d956c0e435f8d9ad2e96a80) )
ROM_REGION( 0x2000000, "sprite", 0 ) /* sprite? tilemap? tiles */
@ -1637,6 +1720,7 @@ ROM_END
/* Games */
GAME( 1997, rapidrvr, 0, gorgon, 0, ss23, ROT0, "Namco", "Rapid River (RD3 Ver. C)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
GAME( 1997, motoxgo, 0, s23, 0, ss23, ROT0, "Namco", "Motocross Go! (MG3 Ver. A)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
GAME( 1997, timecrs2, 0, s23, 0, ss23, ROT0, "Namco", "Time Crisis 2 (TSS3 Ver. B)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
GAME( 1997, timcrs2b, timecrs2, s23, 0, ss23, ROT0, "Namco", "Time Crisis 2 (TSS2 Ver. B)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
GAME( 1999, 500gp, 0, ss23, 0, ss23, ROT0, "Namco", "500GP", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )

View File

@ -184,6 +184,7 @@ CPUS += GMS30C2216
CPUS += GMS30C2232
CPUS += I960
CPUS += H83002
CPUS += H83344
CPUS += V810
CPUS += M37702
CPUS += M37710

View File

@ -862,6 +862,7 @@ const game_driver * const drivers[] =
/* Namco System 23 */
DRIVER( rapidrvr ) /* (c) 1997 */
DRIVER( motoxgo ) /* (c) 1997 */
DRIVER( timecrs2 ) /* (c) 1997 */
DRIVER( timcrs2b ) /* (c) 1997 */
DRIVER( 500gp ) /* (c) 1999 */