diff options
| author | 2015-07-14 00:48:54 +0200 | |
|---|---|---|
| committer | 2015-07-14 00:48:54 +0200 | |
| commit | 0b08b24d1da6e079c3a7283ce0ac056ddbb28047 (patch) | |
| tree | 9e50f4c8446924215e57f15a6f36e7367e643923 | |
| parent | b1c8ebcdf306b2bd0fb6b8872b2d20d6b6d53530 (diff) | |
32-bit transfer (which probably is just a FIFO that reads two words at the same time) ...
| -rw-r--r-- | src/emu/machine/segacdblock.c | 122 | ||||
| -rw-r--r-- | src/emu/machine/segacdblock.h | 7 |
2 files changed, 113 insertions, 16 deletions
diff --git a/src/emu/machine/segacdblock.c b/src/emu/machine/segacdblock.c index 1f782cf68f8..e5ec551ed86 100644 --- a/src/emu/machine/segacdblock.c +++ b/src/emu/machine/segacdblock.c @@ -153,6 +153,89 @@ WRITE16_MEMBER(segacdblock_device::cr2_w){ m_cmd_issued |= 4; COMBINE_DATA(&m_cr READ16_MEMBER(segacdblock_device::cr3_r){ return m_dr[3]; } WRITE16_MEMBER(segacdblock_device::cr3_w){ m_cmd_issued |= 8; COMBINE_DATA(&m_cr[3]); SH2SendsCommand(); } +void segacdblock_device::cd_defragblocks(partitionT *part) +{ + UINT32 i, j; + blockT *temp; + UINT8 temp2; + + for (i = 0; i < (MAX_BLOCKS-1); i++) + { + for (j = i+1; j < MAX_BLOCKS; j++) + { + if ((part->blocks[i] == (blockT *)NULL) && (part->blocks[j] != (blockT *)NULL)) + { + temp = part->blocks[i]; + part->blocks[i] = part->blocks[j]; + part->blocks[j] = temp; + + temp2 = part->bnum[i]; + part->bnum[i] = part->bnum[j]; + part->bnum[j] = temp2; + } + } + } +} + +READ32_MEMBER(segacdblock_device::datatrns32_r) +{ + UINT32 res; + + res = -1; + if(xfertype == CDDMA_INPROGRESS) + { + if (xfersect < xfersectnum) + { + // get next longword + res = (transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 0]<<24) | + (transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 1]<<16) | + (transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 2]<<8) | + (transpart->blocks[xfersectpos+xfersect]->data[xferoffs + 3]<<0); + + m_dma_size += 4; + xferoffs += 4; + + // did we run out of sector? + if (xferoffs >= transpart->blocks[xfersect]->size) + { + //CDROM_LOG(("CD: finished xfer of block %d of %d\n", xfersect+1, xfersectnum)) + + xferoffs = 0; + xfersect++; + } + } + else // sectors are done, kill 'em all if we can + { + if (DeleteSectorMode == true) + { + INT32 i; + + //CDROM_LOG(("Killing sectors in done\n")) + + // deallocate the blocks + for (i = xfersectpos; i < xfersectpos+xfersectnum; i++) + { + cd_free_block(transpart->blocks[i]); + transpart->blocks[i] = (blockT *)NULL; + transpart->bnum[i] = 0xff; + } + + // defrag what's left + cd_defragblocks(transpart); + + // clean up our state + transpart->size -= m_dma_size; + transpart->numblks -= xfersectnum; + + /* @todo check this */ + //xfertype = CDDMA_STOPPED; + } + } + } + + return res; +} + READ16_MEMBER(segacdblock_device::datatrns_r) { UINT16 res; @@ -187,13 +270,14 @@ READ16_MEMBER(segacdblock_device::datatrns_r) 0x25890028 MPEGRGB MPEG RGB Data Transfer Register */ static ADDRESS_MAP_START( map, AS_0, 32, segacdblock_device ) - AM_RANGE(0x00, 0x03) AM_MIRROR(0xf000) AM_READ16(datatrns_r,0xffffffff) - AM_RANGE(0x08, 0x0b) AM_MIRROR(0xf000) AM_READWRITE16(hirq_r,hirq_w,0xffffffff) - AM_RANGE(0x0c, 0x0f) AM_MIRROR(0xf000) AM_READWRITE16(hirq_mask_r,hirq_mask_w,0xffffffff) - AM_RANGE(0x18, 0x1b) AM_MIRROR(0xf000) AM_READWRITE16(cr0_r,cr0_w,0xffffffff) - AM_RANGE(0x1c, 0x1f) AM_MIRROR(0xf000) AM_READWRITE16(cr1_r,cr1_w,0xffffffff) - AM_RANGE(0x20, 0x23) AM_MIRROR(0xf000) AM_READWRITE16(cr2_r,cr2_w,0xffffffff) - AM_RANGE(0x24, 0x27) AM_MIRROR(0xf000) AM_READWRITE16(cr3_r,cr3_w,0xffffffff) + AM_RANGE(0x18000, 0x18003) AM_READ(datatrns32_r) + AM_RANGE(0x90000, 0x90003) AM_MIRROR(0xf000) AM_READ16(datatrns_r,0xffffffff) + AM_RANGE(0x90008, 0x9000b) AM_MIRROR(0xf000) AM_READWRITE16(hirq_r,hirq_w,0xffffffff) + AM_RANGE(0x9000c, 0x9000f) AM_MIRROR(0xf000) AM_READWRITE16(hirq_mask_r,hirq_mask_w,0xffffffff) + AM_RANGE(0x90018, 0x9001b) AM_MIRROR(0xf000) AM_READWRITE16(cr0_r,cr0_w,0xffffffff) + AM_RANGE(0x9001c, 0x9001f) AM_MIRROR(0xf000) AM_READWRITE16(cr1_r,cr1_w,0xffffffff) + AM_RANGE(0x90020, 0x90023) AM_MIRROR(0xf000) AM_READWRITE16(cr2_r,cr2_w,0xffffffff) + AM_RANGE(0x90024, 0x90027) AM_MIRROR(0xf000) AM_READWRITE16(cr3_r,cr3_w,0xffffffff) ADDRESS_MAP_END static MACHINE_CONFIG_FRAGMENT( segacdblock_config ) @@ -217,7 +301,7 @@ MACHINE_CONFIG_END segacdblock_device::segacdblock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, SEGACDBLOCK, "Sega Saturn CD-Block (HLE)", tag, owner, clock, "segacdblock", __FILE__), device_memory_interface(mconfig, *this), - m_space_config("segacdblock", ENDIANNESS_BIG, 32,16, 0, NULL, *ADDRESS_MAP_NAME(map)) + m_space_config("segacdblock", ENDIANNESS_BIG, 32,20, 0, NULL, *ADDRESS_MAP_NAME(map)) { } @@ -798,17 +882,25 @@ void segacdblock_device::cd_cmd_get_then_delete_sector() // @todo reject states cd_getsectoroffsetnum(bufnum, §ofs, §num); - m_dma_src = 0; - m_dma_size = 0; +// m_dma_src = 0; +// m_dma_size = 0; transpart = &partitions[bufnum]; m_TransferActive = true; cd_standard_return(false); // cheap hack - m_dr[0] = CD_STAT_TRANS | m_cd_state; - sourcetype = SOURCE_DATA; + m_dr[0] = CD_STAT_TRANS | m_cd_state; + xferoffs = 0; + xfersect = 0; + m_dma_size = 0; + xfersectpos = sectofs; + xfersectnum = sectnum; + xfertype = CDDMA_INPROGRESS; +// sourcetype = SOURCE_DATA; set_flag(EHST); + set_flag(DRDY); set_flag(CMOK); + DeleteSectorMode = true; } void segacdblock_device::cd_cmd_get_copy_error() @@ -983,7 +1075,9 @@ void segacdblock_device::dma_setup() sourcetype = SOURCE_NONE; break; case SOURCE_DATA: + xfertype = CDDMA_INPROGRESS; set_flag(DRDY); + sourcetype = SOURCE_NONE; break; case SOURCE_AUDIO: break; @@ -1361,8 +1455,8 @@ READ32_MEMBER( segacdblock_device::read ) res|= m_space->read_word(offset*4)<<0; if(mem_mask == 0xffffffff) - debugger_break(machine()); - + res = m_space->read_dword(offset*4); + return res; } diff --git a/src/emu/machine/segacdblock.h b/src/emu/machine/segacdblock.h index 25abd674395..705736a23de 100644 --- a/src/emu/machine/segacdblock.h +++ b/src/emu/machine/segacdblock.h @@ -57,7 +57,8 @@ public: DECLARE_WRITE16_MEMBER( hirq_mask_w ); DECLARE_READ16_MEMBER( datatrns_r ); - + DECLARE_READ32_MEMBER( datatrns32_r ); + protected: // device-level overrides virtual void device_validity_check(validity_checker &valid) const; @@ -246,7 +247,9 @@ private: int numfiles; // # of entries in current directory int firstfile; // first non-directory file void cd_getsectoroffsetnum(UINT32 bufnum, UINT32 *sectoffs, UINT32 *sectnum); - + UINT32 xferoffs, xfersect, xfersectpos, xfersectnum, xferdnum; + bool DeleteSectorMode; + void cd_defragblocks(partitionT *part); }; |
