gdrom: reduce dma buffer size. reios: schedule dma reads by chunks

Reduce gdrom dma buffer size to 16 sectors from 32.
Limit serialization of dma and pio buffers to actual content.
reios: schedule transfer of dma data in chunks.
Fixes Soul Calibuf audio drop outs at boot with HLE BIOS (RA).
Issue #1755
This commit is contained in:
Flyinghead 2024-11-30 16:37:55 +01:00
parent a085fd2f6d
commit c860807fef
9 changed files with 355 additions and 224 deletions

View File

@ -25,9 +25,9 @@ int sns_key;
static u32 set_mode_offset;
static read_params_t read_params;
static packet_cmd_t packet_cmd;
static read_buff_t read_buff;
static pio_buff_t pio_buff;
static ata_cmd_t ata_cmd;
static DmaBuffer dma_buff;
static PioBuffer pio_buff;
static u8 ata_command;
cdda_t cdda;
static gd_states gd_state;
@ -35,7 +35,7 @@ static DiscType gd_disk_type;
/*
GD rom reset -> GDS_WAITCMD
GDS_WAITCMD -> ATA/SPI command [Command code is on ata_cmd]
GDS_WAITCMD -> ATA/SPI command [Command code is on ata_command]
SPI Command -> GDS_WAITPACKET -> GDS_SPI_* , depending on input
GDS_SPI_READSECTOR -> Depending on features , it can do quite a few things
@ -98,21 +98,69 @@ static void gd_spi_pio_end(const u8* buffer, u32 len, gd_states next_state = gds
static void gd_process_spi_cmd();
static void gd_process_ata_cmd();
static void FillReadBuffer()
void DmaBuffer::fill(read_params_t& params)
{
read_buff.cache_index=0;
u32 count = read_params.remaining_sectors;
if (!isEmpty())
return;
index = 0;
verify(params.remaining_sectors > 0);
u32 count = std::min(params.remaining_sectors, NSECT);
size = count * params.sector_type;
if (count > 32)
count = 32;
read_buff.cache_size=count*read_params.sector_type;
libGDR_ReadSector(read_buff.cache,read_params.start_sector,count,read_params.sector_type);
read_params.start_sector+=count;
read_params.remaining_sectors-=count;
libGDR_ReadSector(cache, params.start_sector, count, params.sector_type);
params.start_sector += count;
params.remaining_sectors -= count;
}
const u8 *DmaBuffer::read(u32 len)
{
verify(len <= size);
const u8 *p = &cache[index];
index += len;
size -= len;
return p;
}
void DmaBuffer::serialize(Serializer& ser) const
{
ser << size;
ser.serialize(&cache[index], size);
}
void DmaBuffer::deserialize(Deserializer& deser)
{
if (deser.version() < Deserializer::V54)
{
deser >> index;
deser >> size;
deser >> cache;
}
else
{
index = 0;
deser >> size;
deser.deserialize(&cache[0], size);
}
}
void PioBuffer::serialize(Serializer& ser) const
{
ser << next_state;
ser << index;
ser << size;
ser.serialize(&_data[0], size);
}
void PioBuffer::deserialize(Deserializer& deser)
{
deser >> next_state;
deser >> index;
deser >> size;
if (deser.version() < Deserializer::V54)
deser >> _data;
else
deser.deserialize(&_data[0], size);
}
static void gd_set_state(gd_states state)
{
@ -163,7 +211,7 @@ static void gd_set_state(gd_states state)
case gds_pio_send_data:
// When preparations are complete, the following steps are carried out at the device.
//(1) Number of bytes to be read is set in "Byte Count" register.
ByteCount.full =(u16)(pio_buff.size<<1);
ByteCount.full = (u16)pio_buff.getSize();
//(2) IO bit is set and CoD bit is cleared.
IntReason.IO=1;
IntReason.CoD=0;
@ -189,22 +237,24 @@ static void gd_set_state(gd_states state)
u32 sector_count = read_params.remaining_sectors;
gd_states next_state=gds_pio_end;
if (sector_count > 27)
{
sector_count = 27;
const u32 maxSectors = (PioBuffer::Capacity - 1) / read_params.sector_type;
if (sector_count > maxSectors) {
sector_count = maxSectors;
next_state = gds_readsector_pio;
}
libGDR_ReadSector((u8*)&pio_buff.data[0],read_params.start_sector,sector_count, read_params.sector_type);
read_params.start_sector+=sector_count;
read_params.remaining_sectors-=sector_count;
u16 *buffer = pio_buff.fill(sector_count * read_params.sector_type);
libGDR_ReadSector((u8*)buffer, read_params.start_sector, sector_count, read_params.sector_type);
read_params.start_sector += sector_count;
read_params.remaining_sectors -= sector_count;
gd_spi_pio_end(0,sector_count*read_params.sector_type,next_state);
gd_spi_pio_end(nullptr, 0, next_state);
}
break;
case gds_readsector_dma:
FillReadBuffer();
dma_buff.clear();
dma_buff.fill(read_params);
break;
case gds_pio_end:
@ -236,7 +286,7 @@ static void gd_set_state(gd_states state)
break;
case gds_process_set_mode:
memcpy((u8 *)&GD_HardwareInfo + set_mode_offset, pio_buff.data, pio_buff.size << 1);
memcpy((u8 *)&GD_HardwareInfo + set_mode_offset, pio_buff.data(), pio_buff.getSize());
//end pio transfer ;)
gd_set_state(gds_pio_end);
break;
@ -304,36 +354,32 @@ static void gd_disc_change()
read_params = { 0 };
set_mode_offset = 0;
packet_cmd = { 0 };
memset(&read_buff, 0, sizeof(read_buff));
pio_buff = { gds_waitcmd, 0 };
ata_cmd = { 0 };
dma_buff.clear();
pio_buff.clear();
ata_command = 0;
cdda = { cdda_t::NoInfo, 0 };
}
//This handles the work of setting up the pio regs/state :)
static void gd_spi_pio_end(const u8* buffer, u32 len, gd_states next_state)
{
verify(len<0xFFFF);
pio_buff.index=0;
pio_buff.size=len>>1;
pio_buff.next_state=next_state;
if (buffer!=0)
memcpy(pio_buff.data,buffer,len);
if (len==0)
if (buffer != nullptr) {
verify(len < 0xFFFF); // TODO shouldn't this be <= 0xFFFF ?
memcpy(pio_buff.fill(len), buffer, len);
}
pio_buff.next_state = next_state;
if (pio_buff.isEmpty())
gd_set_state(next_state);
else
gd_set_state(gds_pio_send_data);
}
static void gd_spi_pio_read_end(u32 len, gd_states next_state)
{
verify(len<0xFFFF);
pio_buff.index=0;
pio_buff.size=len>>1;
pio_buff.next_state=next_state;
verify(len < 0xFFFF); // TODO see above
pio_buff.resetSize(len);
pio_buff.next_state = next_state;
if (len==0)
if (len == 0)
gd_set_state(next_state);
else
gd_set_state(gds_pio_get_data);
@ -350,7 +396,7 @@ static void gd_process_ata_cmd()
else
GDStatus.CHECK=1;
switch(ata_cmd.command)
switch (ata_command)
{
case ATA_NOP:
printf_ata("ATA_NOP");
@ -447,7 +493,7 @@ static void gd_process_ata_cmd()
break;
default:
WARN_LOG(GDROM, "Unknown ATA command %x", ata_cmd.command);
WARN_LOG(GDROM, "Unknown ATA command %x", ata_command);
Error.ABRT = 1;
Error.Sense = 5; // illegal request
GDStatus.BSY = 0;
@ -706,12 +752,12 @@ static void gd_process_spi_cmd()
read_params.sector_type = sector_type;//yeah i know , not really many types supported...
printf_spicmd("SPI_CD_READ - Sector=%d Size=%d/%d DMA=%d",read_params.start_sector,read_params.remaining_sectors,read_params.sector_type,Features.CDRead.DMA);
if (Features.CDRead.DMA == 1)
{
if (Features.CDRead.DMA == 1) {
pio_buff.clear();
gd_set_state(gds_readsector_dma);
}
else
{
else {
dma_buff.clear();
gd_set_state(gds_readsector_pio);
}
}
@ -1008,16 +1054,15 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
//if (gd_state == gds_pio_send_data)
//{
if (pio_buff.index == pio_buff.size)
if (pio_buff.atEnd())
{
INFO_LOG(GDROM, "GDROM: Illegal Read From DATA (underflow)");
}
else
{
u32 rv= pio_buff.data[pio_buff.index];
pio_buff.index+=1;
ByteCount.full-=2;
if (pio_buff.index==pio_buff.size)
u32 rv = pio_buff.read();
ByteCount.full -= sizeof(u16);
if (pio_buff.atEnd())
{
verify(pio_buff.next_state != gds_pio_send_data);
//end of pio transfer !
@ -1085,11 +1130,10 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz)
}
else if (gd_state == gds_pio_get_data)
{
pio_buff.data[pio_buff.index]=(u16)data;
pio_buff.index+=1;
if (pio_buff.size==pio_buff.index)
pio_buff.write((u16)data);
if (pio_buff.atEnd())
{
verify(pio_buff.next_state!=gds_pio_get_data);
verify(pio_buff.next_state != gds_pio_get_data);
gd_set_state(pio_buff.next_state);
}
}
@ -1136,7 +1180,7 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz)
{
if (data != ATA_NOP && data != ATA_SOFT_RESET)
verify(gd_state == gds_waitcmd);
ata_cmd.command = (u8)data;
ata_command = (u8)data;
gd_set_state(gds_procata);
}
else
@ -1178,7 +1222,7 @@ static int GDRomschd(int tag, int cycles, int jitter, void *arg)
SecNumber.Status = GD_STANDBY;
GDStatus.DSC = 1;
}
if(!(SB_GDST&1) || !(SB_GDEN &1) || (read_buff.cache_size==0 && read_params.remaining_sectors==0))
if (!(SB_GDST & 1) || !(SB_GDEN & 1) || (dma_buff.isEmpty() && read_params.remaining_sectors == 0))
return 0;
u32 src = SB_GDSTARD;
@ -1193,7 +1237,7 @@ static int GDRomschd(int tag, int cycles, int jitter, void *arg)
//if we don't have any more sectors to read
if (read_params.remaining_sectors == 0)
//make sure we don't underrun the cache :)
len = std::min(len, read_buff.cache_size);
len = std::min(len, dma_buff.getSize());
len = std::min(len, (u32)10240);
// do we need to do this for GDROM DMA?
@ -1211,25 +1255,15 @@ static int GDRomschd(int tag, int cycles, int jitter, void *arg)
u32 len_backup = len;
if(1 == SB_GDDIR)
{
while(len)
while (len)
{
u32 buff_size =read_buff.cache_size;
if (buff_size==0)
{
verify(read_params.remaining_sectors>0);
//buffer is empty , fill it :)
FillReadBuffer();
continue;
}
dma_buff.fill(read_params);
// transfer up to len bytes
const u32 buff_size = std::min(dma_buff.getSize(), len);
//transfer up to len bytes
if (buff_size>len)
buff_size=len;
WriteMemBlock_nommu_ptr(src,(u32*)&read_buff.cache[read_buff.cache_index], buff_size);
read_buff.cache_index+=buff_size;
read_buff.cache_size-=buff_size;
src+=buff_size;
len-=buff_size;
WriteMemBlock_nommu_ptr(src, (const u32 *)dma_buff.read(buff_size), buff_size);
src += buff_size;
len -= buff_size;
}
}
else
@ -1245,16 +1279,10 @@ static int GDRomschd(int tag, int cycles, int jitter, void *arg)
SB_GDST = 0;
asic_RaiseInterrupt(holly_GDROM_DMA);
}
//Read ALL sectors
if (read_params.remaining_sectors==0)
{
//And all buffer :p
if (read_buff.cache_size==0)
{
//verify(!SB_GDST&1) -> dc can do multi read dma
gd_set_state(gds_procpacketdone);
}
}
// Read ALL sectors and all buffer
if (read_params.remaining_sectors == 0 && dma_buff.isEmpty())
//verify(!SB_GDST&1) -> dc can do multi read dma
gd_set_state(gds_procpacketdone);
return getGDROMTicks();
}
@ -1338,9 +1366,9 @@ void gdrom_reg_Reset(bool hard)
set_mode_offset = 0;
read_params = {};
packet_cmd = {};
read_buff = {};
pio_buff = {};
ata_cmd = {};
dma_buff.clear();
pio_buff.clear();
ata_command = 0;
cdda = {};
gd_disk_type = NoDisk;
@ -1371,9 +1399,9 @@ void serialize(Serializer& ser)
ser << packet_cmd;
ser << set_mode_offset;
ser << read_params;
ser << read_buff;
ser << pio_buff;
ser << ata_cmd;
dma_buff.serialize(ser);
pio_buff.serialize(ser);
ser << ata_command;
ser << cdda;
ser << gd_state;
ser << gd_disk_type;
@ -1400,16 +1428,16 @@ void deserialize(Deserializer& deser)
deser >> packet_cmd;
deser >> set_mode_offset;
deser >> read_params;
if (deser.version() >= Deserializer::V17)
deser >> read_buff;
else
{
deser >> packet_cmd;
read_buff.cache_size = 0;
if (deser.version() >= Deserializer::V17) {
dma_buff.deserialize(deser);
}
deser >> pio_buff;
else {
deser >> packet_cmd;
dma_buff.clear();
}
pio_buff.deserialize(deser);
deser.skip<u32>(Deserializer::V44); // set_mode_offset (repeat)
deser >> ata_cmd;
deser >> ata_command;
deser >> cdda;
deser >> gd_state;
deser >> gd_disk_type;

View File

@ -164,26 +164,89 @@ struct packet_cmd_t
};
};
//Buffer for sector reads [dma]
struct read_buff_t
class DmaBuffer
{
u32 cache_index;
u32 cache_size;
u8 cache[2352 * 32];
};
public:
DmaBuffer() {
clear();
}
bool isEmpty() const {
return size == 0;
}
u32 getSize() const {
return size;
}
void clear() {
size = 0;
index = 0;
}
//pio buffer
struct pio_buff_t
{
gd_states next_state;
// Fill the cache with up to NSECT sectors if empty, using the passed read parameters
void fill(read_params_t& params);
// Return a pointer to the cache and advance the index by len bytes. len *must* be <= getSize()
const u8 *read(u32 len);
void serialize(Serializer& ser) const;
void deserialize(Deserializer& deser);
private:
static constexpr u32 NSECT = 16;
u32 index;
u32 size;
u16 data[0x10000>>1]; //64 kb
u8 cache[2352 * NSECT] {};
};
struct ata_cmd_t
class PioBuffer
{
u8 command;
public:
PioBuffer() {
clear();
}
bool isEmpty() const {
return size == 0;
}
// Returns true if the buffer has reached its capacity and can't be read from or written to
bool atEnd() const {
return index == size;
}
// in bytes
u32 getSize() const {
return size * sizeof(u16);
}
void clear()
{
next_state = gds_waitcmd;
size = 0;
index = 0;
}
u16 read() {
return _data[index++];
}
const u16 *data() const {
return _data;
}
void write(u16 v) {
_data[index++] = v;
}
// Returns a pointer to fill the buffer and sets its size. Index is reset.
u16 *fill(u32 size) {
resetSize(size);
return &_data[0];
}
// Sets the buffer capacity and resets the index.
void resetSize(u32 size) {
this->index = 0;
this->size = size / sizeof(u16);
}
void serialize(Serializer& ser) const;
void deserialize(Deserializer& deser);
gd_states next_state;
static constexpr u32 Capacity = 64_KB;
private:
u32 index;
u32 size;
u16 _data[Capacity / 2] {};
};
struct cdda_t

View File

@ -22,8 +22,126 @@
#define SWAP32(a) ((((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))
#define debugf(...) DEBUG_LOG(REIOS, __VA_ARGS__)
static void readSectors(u32 addr, u32 sector, u32 count, bool virtualAddr);
gdrom_hle_state_t gd_hle_state;
struct gdrom_hle_state_t
{
gdrom_hle_state_t() : params{}, result{} {}
u32 last_request_id = 0xFFFFFFFF;
u32 next_request_id = 2;
gd_return_value status = GDC_OK;
gd_command command = GDCC_NONE;
u32 params[4];
u32 result[4];
u32 cur_sector = 0;
u32 multi_read_sector = 0;
u32 multi_read_offset = 0;
u32 multi_read_count = 0;
u32 multi_read_total = 0;
u32 multi_callback = 0;
u32 multi_callback_arg = 0;
bool dma_trans_ended = false;
u64 xfer_end_time = 0;
void Serialize(Serializer& ser)
{
ser << last_request_id;
ser << next_request_id;
ser << status;
ser << command;
ser << params;
ser << result;
ser << cur_sector;
ser << multi_read_sector;
ser << multi_read_offset;
ser << multi_read_count;
ser << multi_read_total;
ser << multi_callback;
ser << multi_callback_arg;
ser << dma_trans_ended;
ser << xfer_end_time;
}
void Deserialize(Deserializer& deser)
{
deser >> last_request_id;
deser >> next_request_id;
deser >> status;
deser >> command;
deser >> params;
deser >> result;
deser >> cur_sector;
deser >> multi_read_sector;
deser >> multi_read_offset;
deser >> multi_read_count;
deser >> multi_read_total;
deser >> multi_callback;
deser >> multi_callback_arg;
deser >> dma_trans_ended;
deser >> xfer_end_time;
}
};
static gdrom_hle_state_t gd_hle_state;
static int schedId = -1;
static int getGdromTicks()
{
u32 len = gd_hle_state.multi_read_count * 2048;
if (len > 10240)
return 1000000; // Large transfers: GD-ROM transfer rate 1.8 MB/s
else
return len * 2; // Small transfers: Max G1 bus rate: 50 MHz x 16 bits
}
static int schedCallback(int tag, int cycles, int jitter, void *arg)
{
const u32 sect = std::min(gd_hle_state.multi_read_count, 5u);
readSectors(gd_hle_state.multi_read_offset, gd_hle_state.multi_read_sector, sect, false);
gd_hle_state.multi_read_count -= sect;
gd_hle_state.multi_read_sector += sect;
gd_hle_state.cur_sector = gd_hle_state.multi_read_sector;
gd_hle_state.multi_read_offset += sect * 2048;
if (gd_hle_state.multi_read_count == 0)
{
gd_hle_state.result[3] = GDC_WAIT_INTERNAL;
SecNumber.Status = GD_STANDBY;
gd_hle_state.status = GDC_COMPLETE;
}
gd_hle_state.result[2] = (gd_hle_state.multi_read_total - gd_hle_state.multi_read_count) * 2048;
return getGdromTicks();
}
void reios_init() {
if (schedId == -1)
schedId = sh4_sched_register(0, schedCallback);
}
void reios_serialize(Serializer& ser) {
gd_hle_state.Serialize(ser);
sh4_sched_serialize(ser, schedId);
}
void reios_deserialize(Deserializer& deser)
{
gd_hle_state.Deserialize(deser);
if (deser.version() >= Deserializer::V54)
sh4_sched_deserialize(deser, schedId);
}
void gdrom_hle_reset() {
gd_hle_state = {};
}
void reios_term()
{
if (schedId != -1)
sh4_sched_unregister(schedId);
schedId = -1;
}
static void GDROM_HLE_ReadSES()
{
@ -64,19 +182,10 @@ static void GDROM_HLE_ReadTOC()
WriteMem32(dest, toc[i]);
}
template<bool virtual_addr>
static void read_sectors_to(u32 addr, u32 sector, u32 count)
static void readSectors(u32 addr, u32 sector, u32 count, bool virtualAddr)
{
gd_hle_state.cur_sector = sector + count - 1;
if (virtual_addr)
gd_hle_state.xfer_end_time = 0;
else if (count > 5 && !config::FastGDRomLoad)
// Large Transfers: GD-ROM rate (approx. 1.8 MB/s)
gd_hle_state.xfer_end_time = sh4_sched_now64() + (u64)count * 2048 * 1000000L / 10240;
else
// Small transfers: Max G1 bus rate: 50 MHz x 16 bits
gd_hle_state.xfer_end_time = sh4_sched_now64() + 5 * 2048 * 2;
if (!virtual_addr || !mmu_enabled())
if (!virtualAddr || !mmu_enabled())
{
u8 * pDst = GetMemPtr(addr, 0);
@ -94,7 +203,7 @@ static void read_sectors_to(u32 addr, u32 sector, u32 count)
for (std::size_t i = 0; i < std::size(temp); i++)
{
if (virtual_addr)
if (virtualAddr)
WriteMem32(addr, temp[i]);
else
WriteMem32_nommu(addr, temp[i]);
@ -106,6 +215,12 @@ static void read_sectors_to(u32 addr, u32 sector, u32 count)
}
}
static void read_pio_sectors(u32 addr, u32 sector, u32 count)
{
gd_hle_state.xfer_end_time = 0;
readSectors(addr, sector, count, true);
}
static void GDROM_HLE_ReadDMA()
{
u32 fad = gd_hle_state.params[0] & 0xffffff;
@ -115,7 +230,13 @@ static void GDROM_HLE_ReadDMA()
debugf("GDROM: DMA READ Sector=%d, Num=%d, Buffer=%08x, zero=%x", fad, nsect, buffer, gd_hle_state.params[3]);
read_sectors_to<false>(buffer, fad, nsect);
gd_hle_state.cur_sector = fad;
gd_hle_state.multi_read_sector = fad;
gd_hle_state.multi_read_offset = buffer;
gd_hle_state.multi_read_count = nsect;
gd_hle_state.multi_read_total = nsect;
sh4_sched_request(schedId, getGdromTicks());
gd_hle_state.result[2] = 0;
gd_hle_state.result[3] = 0;
}
@ -129,7 +250,7 @@ static void GDROM_HLE_ReadPIO()
debugf("GDROM: PIO READ Sector=%d, Num=%d, Buffer=%08x, SeekAhead=%x", fad, nsect, buffer, gd_hle_state.params[3]);
read_sectors_to<true>(buffer, fad, nsect);
read_pio_sectors(buffer, fad, nsect);
gd_hle_state.result[2] = nsect * 2048;
gd_hle_state.result[3] = 0;
}
@ -292,19 +413,9 @@ static void GD_HLE_Command(gd_command cc)
case GDCC_DMAREAD:
cdda.status = cdda_t::NoInfo;
if (gd_hle_state.xfer_end_time == 0)
if (gd_hle_state.multi_read_count == 0)
GDROM_HLE_ReadDMA();
if (gd_hle_state.xfer_end_time > 0)
{
if (gd_hle_state.xfer_end_time > sh4_sched_now64())
return;
gd_hle_state.xfer_end_time = 0;
}
gd_hle_state.result[2] = gd_hle_state.params[1] * 2048;
gd_hle_state.result[3] = 0;
SecNumber.Status = GD_PAUSE;
break;
return;
case GDCC_PLAY2:
{

View File

@ -70,9 +70,8 @@ enum misc_command {
MISC_SETVECTOR
};
void gdrom_hle_init();
void gdrom_hle_term();
void gdrom_hle_op();
void gdrom_hle_reset();
typedef enum : int32_t {
GDC_ERR = -1,
@ -85,66 +84,6 @@ typedef enum : int32_t {
GDC_RET2
} gd_return_value;
struct gdrom_hle_state_t
{
gdrom_hle_state_t() : params{}, result{} {}
u32 last_request_id = 0xFFFFFFFF;
u32 next_request_id = 2;
gd_return_value status = GDC_OK;
gd_command command = GDCC_NONE;
u32 params[4];
u32 result[4];
u32 cur_sector = 0;
u32 multi_read_sector = 0;
u32 multi_read_offset = 0;
u32 multi_read_count = 0;
u32 multi_read_total = 0;
u32 multi_callback = 0;
u32 multi_callback_arg = 0;
bool dma_trans_ended = false;
u64 xfer_end_time = 0;
void Serialize(Serializer& ser)
{
ser << last_request_id;
ser << next_request_id;
ser << status;
ser << command;
ser << params;
ser << result;
ser << cur_sector;
ser << multi_read_sector;
ser << multi_read_offset;
ser << multi_read_count;
ser << multi_read_total;
ser << multi_callback;
ser << multi_callback_arg;
ser << dma_trans_ended;
ser << xfer_end_time;
}
void Deserialize(Deserializer& deser)
{
deser >> last_request_id;
deser >> next_request_id;
deser >> status;
deser >> command;
deser >> params;
deser >> result;
deser >> cur_sector;
deser >> multi_read_sector;
deser >> multi_read_offset;
deser >> multi_read_count;
deser >> multi_read_total;
deser >> multi_callback;
deser >> multi_callback_arg;
deser >> dma_trans_ended;
deser >> xfer_end_time;
}
};
extern gdrom_hle_state_t gd_hle_state;
// status for GDROM_GET_DRV_STAT
enum gd_drv_stat {
GD_STAT_BUSY,

View File

@ -727,13 +727,7 @@ void DYNACALL reios_trap(Sh4Context *ctx, u32 op)
ctx->pc = ctx->pr;
}
bool reios_init()
{
return true;
}
void reios_set_flash(MemChip* flash)
{
void reios_set_flash(MemChip* flash) {
flashrom = flash;
}
@ -763,8 +757,5 @@ void reios_reset(u8* rom)
std::unique_ptr<u8[]> fontData = resource::load("fonts/biosfont.bin", size);
memcpy(pFont, fontData.get(), size);
gd_hle_state = {};
}
void reios_term() {
gdrom_hle_reset();
}

View File

@ -3,10 +3,11 @@
#include "types.h"
#include "hw/flashrom/flashrom.h"
bool reios_init();
void reios_init();
void reios_set_flash(MemChip* flash);
void reios_reset(u8* rom);
void reios_serialize(Serializer& ser);
void reios_deserialize(Deserializer& deser);
void reios_term();
struct Sh4Context;

View File

@ -10,7 +10,7 @@
#include "hw/pvr/pvr.h"
#include "hw/sh4/sh4_sched.h"
#include "hw/sh4/sh4_mmr.h"
#include "reios/gdrom_hle.h"
#include "reios/reios.h"
#include "hw/naomi/naomi.h"
#include "hw/naomi/naomi_cart.h"
#include "hw/bba/bba.h"
@ -50,7 +50,7 @@ void dc_serialize(Serializer& ser)
ser << config::Region.get();
naomi_cart_serialize(ser);
gd_hle_state.Serialize(ser);
reios_serialize(ser);
achievements::serialize(ser);
DEBUG_LOG(SAVESTATE, "Saved %d bytes", (u32)ser.size());
@ -93,7 +93,7 @@ void dc_deserialize(Deserializer& deser)
verify(config::Region >= 0 && config::Region <= 3);
naomi_cart_deserialize(deser);
gd_hle_state.Deserialize(deser);
reios_deserialize(deser);
achievements::deserialize(deser);
sh4_sched_ffts();

View File

@ -64,7 +64,8 @@ public:
V51,
V52,
V53,
Current = V53,
V54,
Current = V54,
Next = Current + 1,
};

View File

@ -32,8 +32,5 @@ TEST_F(SerializeTest, SizeTest)
std::vector<char> data(30000000);
Serializer ser(data.data(), data.size());
dc_serialize(ser);
ASSERT_EQ(28191434u, ser.size());
ASSERT_EQ(28050642u, ser.size());
}