diff --git a/hash/pico.xml b/hash/pico.xml index 77e1808613f..00922ecae17 100644 --- a/hash/pico.xml +++ b/hash/pico.xml @@ -651,6 +651,19 @@ Published by Others (T-yyy*** serial codes, for yyy depending on the publisher) + + Cooking Pico (Jpn) + 1999 + Sega Toys + + + + + + + + + Crayola - Create a World (USA) 19?? diff --git a/hash/sawatte.xml b/hash/sawatte.xml index c72719da411..2d6478edba7 100644 --- a/hash/sawatte.xml +++ b/hash/sawatte.xml @@ -17,6 +17,19 @@ + + Doraemon Nobita no Dou Butsu Land + 1996 + Sega + + + + + + + + + Mickey no Kudamonoya-san 1996 @@ -77,7 +90,20 @@ - + + Soreike! Anpanman Onamae Na~ni + 1996 + Sega + + + + + + + + + + Tokyo Disneyland - Mickey no Nakayoshi Tankentai 1998 Sega? @@ -122,4 +148,17 @@ + + Ultra Hero Touch + 1997 + Bandai + + + + + + + + + diff --git a/src/devices/cpu/sh4/sh4.cpp b/src/devices/cpu/sh4/sh4.cpp index 1d5c69ad483..637929121ec 100644 --- a/src/devices/cpu/sh4/sh4.cpp +++ b/src/devices/cpu/sh4/sh4.cpp @@ -75,7 +75,11 @@ static ADDRESS_MAP_START( sh4_internal_map, AS_PROGRAM, 64, sh4_base_device ) AM_RANGE(0x1C000000, 0x1C000FFF) AM_RAM AM_MIRROR(0x01FFF000) AM_RANGE(0x1E000000, 0x1E000FFF) AM_RAM AM_MIRROR(0x01FFF000) AM_RANGE(0xE0000000, 0xE000003F) AM_RAM AM_MIRROR(0x03FFFFC0) // todo: store queues should be write only on DC's SH4, executing PREFM shouldn't cause an actual memory read access! - AM_RANGE(0xF6000000, 0xF7FFFFFF) AM_READWRITE(sh4_tlb_r,sh4_tlb_w) + + AM_RANGE(0xF6000000, 0xF6FFFFFF) AM_READWRITE(sh4_utlb_address_array_r,sh4_utlb_address_array_w) + AM_RANGE(0xF7000000, 0xF77FFFFF) AM_READWRITE(sh4_utlb_data_array1_r,sh4_utlb_data_array1_w) + AM_RANGE(0xF7800000, 0xF7FFFFFF) AM_READWRITE(sh4_utlb_data_array2_r,sh4_utlb_data_array2_w) + AM_RANGE(0xFE000000, 0xFFFFFFFF) AM_READWRITE32(sh4_internal_r, sh4_internal_w, 0xffffffffffffffffU) ADDRESS_MAP_END @@ -180,6 +184,37 @@ void sh34_base_device::TODO(const uint16_t opcode) { } +void sh34_base_device::LDTLB(const uint16_t opcode) +{ + logerror("unhandled LDTLB for this CPU type\n"); +} + +void sh4_base_device::LDTLB(const uint16_t opcode) +{ + int replace = (m_m[MMUCR] & 0x0000fc00) >> 10; + + logerror("using LDTLB to replace UTLB entry %02x\n", replace); + + // these come from PTEH + m_utlb[replace].VPN = (m_m[PTEH] & 0xfffffc00) >> 10; +// m_utlb[replace].D = (m_m[PTEH] & 0x00000200) >> 9; // from PTEL +// m_utlb[replace].V = (m_m[PTEH] & 0x00000100) >> 8; // from PTEL + m_utlb[replace].ASID = (m_m[PTEH] & 0x000000ff) >> 0; + // these come from PTEL + m_utlb[replace].PPN = (m_m[PTEL] & 0x1ffffc00) >> 10; + m_utlb[replace].V = (m_m[PTEL] & 0x00000100) >> 8; + m_utlb[replace].PSZ = (m_m[PTEL] & 0x00000080) >> 6; + m_utlb[replace].PSZ |=(m_m[PTEL] & 0x00000010) >> 4; + m_utlb[replace].PPR= (m_m[PTEL] & 0x00000060) >> 5; + m_utlb[replace].C = (m_m[PTEL] & 0x00000008) >> 3; + m_utlb[replace].D = (m_m[PTEL] & 0x00000004) >> 2; + m_utlb[replace].SH = (m_m[PTEL] & 0x00000002) >> 1; + m_utlb[replace].WT = (m_m[PTEL] & 0x00000001) >> 0; + // these come from PTEA + m_utlb[replace].TC = (m_m[PTEA] & 0x00000008) >> 3; + m_utlb[replace].SA = (m_m[PTEA] & 0x00000007) >> 0; +} + #if 0 int sign_of(int n) { @@ -3331,7 +3366,7 @@ inline void sh34_base_device::execute_one_0000(const uint16_t opcode) case 0x08: CLRT(opcode); break; case 0x18: SETT(opcode); break; case 0x28: CLRMAC(opcode); break; - case 0x38: TODO(opcode); break; + case 0x38: LDTLB(opcode); break; case 0x48: CLRS(opcode); break; case 0x58: SETS(opcode); break; case 0x68: NOP(opcode); break; @@ -3339,7 +3374,7 @@ inline void sh34_base_device::execute_one_0000(const uint16_t opcode) case 0x88: CLRT(opcode); break; case 0x98: SETT(opcode); break; case 0xa8: CLRMAC(opcode); break; - case 0xb8: TODO(opcode); break; + case 0xb8: LDTLB(opcode); break; case 0xc8: CLRS(opcode); break; case 0xd8: SETS(opcode); break; case 0xe8: NOP(opcode); break; @@ -4028,6 +4063,47 @@ void sh4be_device::execute_run() } while( m_sh4_icount > 0 ); } +void sh4_base_device::device_start() +{ + sh34_base_device::device_start(); + + int i; + for (i=0;i<64;i++) + { + m_utlb[i].ASID = 0; + m_utlb[i].VPN = 0; + m_utlb[i].V = 0; + m_utlb[i].PPN = 0; + m_utlb[i].PSZ = 0; + m_utlb[i].SH = 0; + m_utlb[i].C = 0; + m_utlb[i].PPR = 0; + m_utlb[i].D = 0; + m_utlb[i].WT = 0; + m_utlb[i].SA = 0; + m_utlb[i].TC = 0; + } + + for (i=0;i<64;i++) + { + save_item(NAME(m_utlb[i].ASID), i); + save_item(NAME(m_utlb[i].VPN), i); + save_item(NAME(m_utlb[i].V), i); + save_item(NAME(m_utlb[i].PPN), i); + save_item(NAME(m_utlb[i].PSZ), i); + save_item(NAME(m_utlb[i].SH), i); + save_item(NAME(m_utlb[i].C), i); + save_item(NAME(m_utlb[i].PPR), i); + save_item(NAME(m_utlb[i].D), i); + save_item(NAME(m_utlb[i].WT), i); + save_item(NAME(m_utlb[i].SA), i); + save_item(NAME(m_utlb[i].TC), i); + } + +} + + + void sh34_base_device::device_start() { for (int i=0; i<3; i++) @@ -4134,8 +4210,6 @@ void sh34_base_device::device_start() save_item(NAME( m_ioport16_direction)); save_item(NAME(m_ioport4_pullup)); save_item(NAME(m_ioport4_direction)); - save_item(NAME(m_sh4_tlb_address)); - save_item(NAME(m_sh4_tlb_data)); save_item(NAME(m_sh4_mmu_enabled)); save_item(NAME(m_sh3internal_upper)); save_item(NAME(m_sh3internal_lower)); diff --git a/src/devices/cpu/sh4/sh4.h b/src/devices/cpu/sh4/sh4.h index 7531363c2da..2b9d10bfed4 100644 --- a/src/devices/cpu/sh4/sh4.h +++ b/src/devices/cpu/sh4/sh4.h @@ -136,6 +136,26 @@ struct sh4_ddt_dma int mode; }; + +// ASID [7:0] | VPN [31:10] | V | | PPN [28:10] | SZ[1:0] | SH | C | PR[1:0] | D | WT | SA[2:0] | TC + +struct sh4_utlb +{ + uint8_t ASID; + uint32_t VPN; + uint8_t V; + uint32_t PPN; + uint8_t PSZ; + uint8_t SH; + uint8_t C; + uint8_t PPR; + uint8_t D; + uint8_t WT; + uint8_t SA; + uint8_t TC; +}; + + typedef void (*sh4_ftcsr_callback)(uint32_t); @@ -358,8 +378,6 @@ protected: void (*m_ftcsr_read_callback)(uint32_t data); /* This MMU simulation is good for the simple remap used on Naomi GD-ROM SQ access *ONLY* */ - uint32_t m_sh4_tlb_address[64]; - uint32_t m_sh4_tlb_data[64]; uint8_t m_sh4_mmu_enabled; int m_cpu_type; @@ -451,6 +469,7 @@ protected: void LDSMMACH(const uint16_t opcode); void LDSMMACL(const uint16_t opcode); void LDSMPR(const uint16_t opcode); + virtual void LDTLB(const uint16_t opcode); void MAC_L(const uint16_t opcode); void MAC_W(const uint16_t opcode); void MOV(const uint16_t opcode); @@ -627,7 +646,7 @@ protected: void increment_rtc_time(int mode); void sh4_dmac_nmi(); void sh4_handler_ipra_w(uint32_t data, uint32_t mem_mask); - uint32_t sh4_getsqremap(uint32_t address); + virtual uint32_t sh4_getsqremap(uint32_t address); void sh4_parse_configuration(); void sh4_timer_recompute(int which); uint32_t sh4_handle_tcnt0_addr_r(uint32_t mem_mask); @@ -736,10 +755,20 @@ public: DECLARE_WRITE32_MEMBER( sh4_internal_w ); DECLARE_READ32_MEMBER( sh4_internal_r ); - DECLARE_READ64_MEMBER( sh4_tlb_r ); - DECLARE_WRITE64_MEMBER( sh4_tlb_w ); + DECLARE_READ64_MEMBER( sh4_utlb_address_array_r ); + DECLARE_WRITE64_MEMBER( sh4_utlb_address_array_w ); + DECLARE_READ64_MEMBER( sh4_utlb_data_array1_r ); + DECLARE_WRITE64_MEMBER( sh4_utlb_data_array1_w ); + DECLARE_READ64_MEMBER( sh4_utlb_data_array2_r ); + DECLARE_WRITE64_MEMBER( sh4_utlb_data_array2_w ); + + virtual void LDTLB(const uint16_t opcode) override; + + virtual uint32_t sh4_getsqremap(uint32_t address) override; + sh4_utlb m_utlb[64]; protected: + virtual void device_start() override; virtual void device_reset() override; }; diff --git a/src/devices/cpu/sh4/sh4comn.cpp b/src/devices/cpu/sh4/sh4comn.cpp index 985413e4a73..f02c9f50242 100644 --- a/src/devices/cpu/sh4/sh4comn.cpp +++ b/src/devices/cpu/sh4/sh4comn.cpp @@ -676,9 +676,57 @@ WRITE32_MEMBER( sh4_base_device::sh4_internal_w ) // printf("sh4_internal_w: Write %08x (%x), %08x @ %08x\n", 0xfe000000+((offset & 0x3fc0) << 11)+((offset & 0x3f) << 2), offset, data, mem_mask); - switch( offset ) + switch( offset ) { + case PTEH: // for use with LDTLB opcode + m_m[PTEH] &= 0xffffffff; + /* + NNNN NNNN NNNN NNNN NNNN NN-- AAAA AAAA + + N = VPM = Virtual Page Number + A = ASID = Address Space Identifier + + same as the address table part of the utlb but with 2 unused bits (these are sourced from PTEL instead when LDTLB is called) + */ + + + break; + + case PTEL: + m_m[PTEL] &= 0xffffffff; + /* + ---P PPPP PPPP PPPP PPPP PP-V zRRz CDHW + + same format as data array 1 of the utlb + */ + break; + + case PTEA: + m_m[PTEA] &= 0xffffffff; + /* + ---- ---- ---- ---- ---- ---- ---- TSSS + + same format as data array 2 of the utlb + */ + break; + case MMUCR: // MMU Control + logerror("MMUCR %08x\n", data); + m_m[MMUCR] &= 0xffffffff; + /* + LLLL LL-- BBBB BB-- CCCC CCQV ---- -T-A + + L = LRUI = Least recently used ITLB + B = URB = UTLB replace boundary + C = URC = UTLB replace counter + Q = SQMD = Store Queue Mode Bit + V = SV = Single Virtual Mode Bit + T = TI = TLB invaldiate + A = AT = Address translation bit (enable) + */ + + + if (data & MMUCR_AT) { printf("SH4 MMU Enabled\n"); @@ -686,16 +734,7 @@ WRITE32_MEMBER( sh4_base_device::sh4_internal_w ) printf("The MMU emulation is a hack specific to that system\n"); m_sh4_mmu_enabled = 1; - // should be a different bit! - { - int i; - for (i=0;i<64;i++) - { - m_sh4_tlb_address[i] = 0; - m_sh4_tlb_data[i] = 0; - } - } } else { @@ -1185,6 +1224,11 @@ void sh34_base_device::sh4_parse_configuration() } uint32_t sh34_base_device::sh4_getsqremap(uint32_t address) +{ + return address; +} + +uint32_t sh4_base_device::sh4_getsqremap(uint32_t address) { if (!m_sh4_mmu_enabled) return address; @@ -1195,9 +1239,9 @@ uint32_t sh34_base_device::sh4_getsqremap(uint32_t address) for (i=0;i<64;i++) { - uint32_t topcmp = m_sh4_tlb_address[i]&0xfff00000; + uint32_t topcmp = (m_utlb[i].VPN<<10)&0xfff00000; if (topcmp==topaddr) - return (address&0x000fffff) | ((m_sh4_tlb_data[i])&0xfff00000); + return (address&0x000fffff) | ((m_utlb[i].PPN<<10)&0xfff00000); } } @@ -1205,34 +1249,147 @@ uint32_t sh34_base_device::sh4_getsqremap(uint32_t address) return address; } -READ64_MEMBER( sh4_base_device::sh4_tlb_r ) -{ - int offs = offset*8; - if (offs >= 0x01000000) +WRITE64_MEMBER( sh4_base_device::sh4_utlb_address_array_w ) +{ +/* uses bits 13:8 of address to select which UTLB entry we're addressing + bit 7 of the address enables 'associative' mode, causing a search + operation rather than a direct write. + + NNNN NNNN NNNN NNNN NNNN NNDV AAAA AAAA + + N = VPM = Virtual Page Number + D = Dirty Bit + V = Validity Bit + A = ASID = Address Space Identifier +*/ + + logerror("sh4_utlb_address_array_w %08x %08x\n", offset, data); + int offs = offset << 3; + + uint8_t associative = (offs >> 7) & 1; + + if (!associative) { - uint8_t i = (offs>>8)&63; - return m_sh4_tlb_data[i]; + // non-associative mode + uint8_t i = (offs >> 8) & 63; + + m_utlb[i].VPN = (data & 0xfffffc00) >> 10; + m_utlb[i].D = (data & 0x00000200) >> 9; + m_utlb[i].V = (data & 0x00000100) >> 8; + m_utlb[i].ASID = (data & 0x000000ff) >> 0; } else { - uint8_t i = (offs>>8)&63; - return m_sh4_tlb_address[i]; + // associative mode + fatalerror("SH4MMU: associative mode writes unsupported\n"); } } -WRITE64_MEMBER( sh4_base_device::sh4_tlb_w ) +READ64_MEMBER( sh4_base_device::sh4_utlb_address_array_r ) { + // associative bit is ignored for reads int offs = offset*8; - if (offs >= 0x01000000) - { - uint8_t i = (offs>>8)&63; - m_sh4_tlb_data[i] = data&0xffffffff; - } - else - { - uint8_t i = (offs>>8)&63; - m_sh4_tlb_address[i] = data&0xffffffff; - } + uint32_t ret = 0; + + uint8_t i = (offs >> 8) & 63; + + ret |= m_utlb[i].VPN << 10; + ret |= m_utlb[i].D << 9; + ret |= m_utlb[i].V << 8; + ret |= m_utlb[i].ASID << 0; + + return ret; } + + +WRITE64_MEMBER( sh4_base_device::sh4_utlb_data_array1_w ) +{ +/* uses bits 13:8 of address to select which UTLB entry we're addressing + + ---P PPPP PPPP PPPP PPPP PP-V zRRz CDHW + + P = PPN = Physical page number + V = Validity bit + z = SZ = Page Size (2 bits, split) + D = Dirty Bit + R = PR = Protection Key Data + C = Cacheable bit + H = Share status + W = Write through + - = unused (should be 0) +*/ + logerror("sh4_utlb_data_array1_w %08x %08x\n", offset, data); + int offs = offset*8; + + uint8_t i = (offs>>8)&63; + + m_utlb[i].PPN = (data & 0x1ffffc00) >> 10; + m_utlb[i].V = (data & 0x00000100) >> 8; + m_utlb[i].PSZ = (data & 0x00000080) >> 6; + m_utlb[i].PSZ |=(data & 0x00000010) >> 4; + m_utlb[i].PPR= (data & 0x00000060) >> 5; + m_utlb[i].C = (data & 0x00000008) >> 3; + m_utlb[i].D = (data & 0x00000004) >> 2; + m_utlb[i].SH = (data & 0x00000002) >> 1; + m_utlb[i].WT = (data & 0x00000001) >> 0; +} + + +READ64_MEMBER(sh4_base_device::sh4_utlb_data_array1_r) +{ + uint32_t ret = 0; + int offs = offset*8; + + uint8_t i = (offs>>8)&63; + + ret |= m_utlb[i].PPN << 10; + ret |= m_utlb[i].V << 8; + ret |= (m_utlb[i].PSZ & 2) << 6; + ret |= (m_utlb[i].PSZ & 1) << 4; + ret |= m_utlb[i].PPR << 5; + ret |= m_utlb[i].C << 3; + ret |= m_utlb[i].D << 2; + ret |= m_utlb[i].SH << 1; + ret |= m_utlb[i].WT << 0; + + return ret; +} + + + +WRITE64_MEMBER( sh4_base_device::sh4_utlb_data_array2_w ) +{ +/* uses bits 13:8 of address to select which UTLB entry we're addressing + + ---- ---- ---- ---- ---- ---- ---- TSSS + + T = TC = Timing Control + S = SA = Space attributes + - = unused (should be 0) + +*/ + + logerror("sh4_utlb_data_array2_w %08x %08x\n", offset, data); + int offs = offset*8; + + uint8_t i = (offs>>8)&63; + + m_utlb[i].TC = (data & 0x00000008) >> 3; + m_utlb[i].SA = (data & 0x00000007) >> 0; +} + + +READ64_MEMBER(sh4_base_device::sh4_utlb_data_array2_r) +{ + uint32_t ret = 0; + int offs = offset*8; + + uint8_t i = (offs>>8)&63; + + ret |= m_utlb[i].TC << 3; + ret |= m_utlb[i].SA << 0; + + return ret; +} \ No newline at end of file diff --git a/src/mame/drivers/sega_sawatte.cpp b/src/mame/drivers/sega_sawatte.cpp index 04dd9fa432e..1caec4a2748 100644 --- a/src/mame/drivers/sega_sawatte.cpp +++ b/src/mame/drivers/sega_sawatte.cpp @@ -5,7 +5,7 @@ a sound-only Pico type system (one of the boards even says S-PICO) -CPU is unknown (I can't see one?!) cartridge dumps should be good, but not confirmed, might be data only for an MCU? +CPU is unknown (I can't see one?! MCU with internal ROM?) cartridge dumps have been tested as working using a flash cart. driver does nothing except allow the softlist to be connected to the -romident commands etc.