mirror of
https://github.com/ARMSX2/ARMSX1.git
synced 2026-08-24 16:53:35 -07:00
checkpoint portable cached CPU SDL acceleration and media support
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bus.h"
|
||||
#include "bus_init.h"
|
||||
@@ -7,17 +8,30 @@
|
||||
|
||||
#define RANGE(v, s, e) ((v >= s) && (v < e))
|
||||
|
||||
const uint32_t g_psx_bus_region_mask_table[] = {
|
||||
const uint32_t g_psx_bus_region_mask_table[] = {
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0x7fffffff, 0x1fffffff, 0xffffffff, 0xffffffff
|
||||
};
|
||||
|
||||
psx_bus_t* psx_bus_create(void) {
|
||||
return (psx_bus_t*)malloc(sizeof(psx_bus_t));
|
||||
}
|
||||
|
||||
// Does nothing for now
|
||||
void psx_bus_init(psx_bus_t* bus) {}
|
||||
};
|
||||
|
||||
uint32_t psx_bus_physical_address(uint32_t addr) {
|
||||
return addr & g_psx_bus_region_mask_table[addr >> 29];
|
||||
}
|
||||
psx_bus_t* psx_bus_create(void) {
|
||||
return (psx_bus_t*)calloc(1, sizeof(psx_bus_t));
|
||||
}
|
||||
|
||||
void psx_bus_init(psx_bus_t* bus) {
|
||||
if (bus)
|
||||
memset(bus, 0, sizeof(*bus));
|
||||
}
|
||||
|
||||
void psx_bus_set_write_observer(psx_bus_t* bus, psx_bus_write_observer_t observer, void* udata) {
|
||||
if (!bus)
|
||||
return;
|
||||
|
||||
bus->write_observer = observer;
|
||||
bus->write_observer_udata = udata;
|
||||
}
|
||||
|
||||
void psx_bus_destroy(psx_bus_t* bus) {
|
||||
free(bus);
|
||||
@@ -28,17 +42,19 @@ void psx_bus_destroy(psx_bus_t* bus) {
|
||||
bus->access_cycles = bus->dev->bus_delay; \
|
||||
return psx_ ## dev ## _read ## bits (bus->dev, addr - bus->dev->io_base); \
|
||||
}
|
||||
#define HANDLE_WRITE(dev, bits) \
|
||||
if (RANGE(addr, bus->dev->io_base, (bus->dev->io_base + bus->dev->io_size))) { \
|
||||
bus->access_cycles = bus->dev->bus_delay; \
|
||||
psx_ ## dev ## _write ## bits (bus->dev, addr - bus->dev->io_base, value); \
|
||||
return; \
|
||||
}
|
||||
#define HANDLE_WRITE(dev, bits) \
|
||||
if (RANGE(addr, bus->dev->io_base, (bus->dev->io_base + bus->dev->io_size))) { \
|
||||
bus->access_cycles = bus->dev->bus_delay; \
|
||||
psx_ ## dev ## _write ## bits (bus->dev, addr - bus->dev->io_base, value); \
|
||||
if (bus->write_observer) \
|
||||
bus->write_observer(bus->write_observer_udata, addr, (bits) / 8); \
|
||||
return; \
|
||||
}
|
||||
|
||||
uint32_t psx_bus_read32(psx_bus_t* bus, uint32_t addr) {
|
||||
uint32_t vaddr = addr;
|
||||
|
||||
addr &= g_psx_bus_region_mask_table[addr >> 29];
|
||||
addr = psx_bus_physical_address(addr);
|
||||
|
||||
if (addr & 0x3) {
|
||||
log_fatal("Unaligned 32-bit read from %08x:%08x", vaddr, addr);
|
||||
@@ -75,7 +91,7 @@ uint16_t psx_bus_read16(psx_bus_t* bus, uint32_t addr) {
|
||||
|
||||
uint32_t vaddr = addr;
|
||||
|
||||
addr &= g_psx_bus_region_mask_table[addr >> 29];
|
||||
addr = psx_bus_physical_address(addr);
|
||||
|
||||
if (addr & 0x1) {
|
||||
log_fatal("Unaligned 16-bit read from %08x:%08x", vaddr, addr);
|
||||
@@ -122,7 +138,7 @@ uint8_t psx_bus_read8(psx_bus_t* bus, uint32_t addr) {
|
||||
|
||||
// uint32_t vaddr = addr;
|
||||
|
||||
addr &= g_psx_bus_region_mask_table[addr >> 29];
|
||||
addr = psx_bus_physical_address(addr);
|
||||
|
||||
HANDLE_READ(bios, 8);
|
||||
HANDLE_READ(ram, 8);
|
||||
@@ -153,7 +169,7 @@ void psx_bus_write32(psx_bus_t* bus, uint32_t addr, uint32_t value) {
|
||||
|
||||
uint32_t vaddr = addr;
|
||||
|
||||
addr &= g_psx_bus_region_mask_table[addr >> 29];
|
||||
addr = psx_bus_physical_address(addr);
|
||||
|
||||
if (addr & 0x3) {
|
||||
log_fatal("Unaligned 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);
|
||||
@@ -187,7 +203,7 @@ void psx_bus_write16(psx_bus_t* bus, uint32_t addr, uint32_t value) {
|
||||
|
||||
uint32_t vaddr = addr;
|
||||
|
||||
addr &= g_psx_bus_region_mask_table[addr >> 29];
|
||||
addr = psx_bus_physical_address(addr);
|
||||
|
||||
if (addr & 0x1) {
|
||||
log_fatal("Unaligned 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);
|
||||
@@ -222,7 +238,7 @@ void psx_bus_write8(psx_bus_t* bus, uint32_t addr, uint32_t value) {
|
||||
|
||||
uint32_t vaddr = addr;
|
||||
|
||||
addr &= g_psx_bus_region_mask_table[addr >> 29];
|
||||
addr = psx_bus_physical_address(addr);
|
||||
|
||||
HANDLE_WRITE(bios, 8);
|
||||
HANDLE_WRITE(ram, 8);
|
||||
@@ -319,4 +335,4 @@ uint32_t psx_bus_get_access_cycles(psx_bus_t* bus) {
|
||||
}
|
||||
|
||||
#undef HANDLE_READ
|
||||
#undef HANDLE_WRITE
|
||||
#undef HANDLE_WRITE
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct psx_bus_t;
|
||||
|
||||
typedef struct psx_bus_t psx_bus_t;
|
||||
struct psx_bus_t;
|
||||
|
||||
typedef struct psx_bus_t psx_bus_t;
|
||||
typedef void (*psx_bus_write_observer_t)(void*, uint32_t, uint32_t);
|
||||
|
||||
psx_bus_t* psx_bus_create(void);
|
||||
void psx_bus_init(psx_bus_t*);
|
||||
@@ -13,9 +14,11 @@ uint32_t psx_bus_read32(psx_bus_t*, uint32_t);
|
||||
uint16_t psx_bus_read16(psx_bus_t*, uint32_t);
|
||||
uint8_t psx_bus_read8(psx_bus_t*, uint32_t);
|
||||
void psx_bus_write32(psx_bus_t*, uint32_t, uint32_t);
|
||||
void psx_bus_write16(psx_bus_t*, uint32_t, uint32_t);
|
||||
void psx_bus_write8(psx_bus_t*, uint32_t, uint32_t);
|
||||
uint32_t psx_bus_get_access_cycles(psx_bus_t*);
|
||||
void psx_bus_destroy(psx_bus_t*);
|
||||
void psx_bus_write16(psx_bus_t*, uint32_t, uint32_t);
|
||||
void psx_bus_write8(psx_bus_t*, uint32_t, uint32_t);
|
||||
uint32_t psx_bus_get_access_cycles(psx_bus_t*);
|
||||
uint32_t psx_bus_physical_address(uint32_t);
|
||||
void psx_bus_set_write_observer(psx_bus_t*, psx_bus_write_observer_t, void*);
|
||||
void psx_bus_destroy(psx_bus_t*);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+7
-5
@@ -34,10 +34,12 @@ struct psx_bus_t {
|
||||
psx_timer_t* timer;
|
||||
psx_cdrom_t* cdrom;
|
||||
psx_pad_t* pad;
|
||||
psx_mdec_t* mdec;
|
||||
|
||||
uint32_t access_cycles;
|
||||
};
|
||||
psx_mdec_t* mdec;
|
||||
|
||||
uint32_t access_cycles;
|
||||
psx_bus_write_observer_t write_observer;
|
||||
void* write_observer_udata;
|
||||
};
|
||||
|
||||
void psx_bus_init_bios(psx_bus_t*, psx_bios_t*);
|
||||
void psx_bus_init_ram(psx_bus_t*, psx_ram_t*);
|
||||
@@ -56,4 +58,4 @@ void psx_bus_init_cdrom(psx_bus_t*, psx_cdrom_t*);
|
||||
void psx_bus_init_pad(psx_bus_t*, psx_pad_t*);
|
||||
void psx_bus_init_mdec(psx_bus_t*, psx_mdec_t*);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -9,9 +9,21 @@
|
||||
#define PSX_CPU_CPS 33868800 // 33868800 Clocks/s
|
||||
#define PSX_CPU_FREQ 33.868800f // 33.868800 MHz
|
||||
|
||||
struct psx_cpu_t;
|
||||
|
||||
typedef struct psx_cpu_t psx_cpu_t;
|
||||
struct psx_cpu_t;
|
||||
struct psx_cpu_cache_t;
|
||||
|
||||
typedef struct psx_cpu_t psx_cpu_t;
|
||||
|
||||
typedef enum {
|
||||
PSX_CPU_INTERPRETER = 0,
|
||||
PSX_CPU_CACHED_INTERPRETER = 1
|
||||
} psx_cpu_execution_mode_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t hits;
|
||||
uint64_t misses;
|
||||
uint64_t invalidations;
|
||||
} psx_cpu_cache_stats_t;
|
||||
|
||||
typedef void (*psx_cpu_kcall_hook_t)(psx_cpu_t*);
|
||||
|
||||
@@ -151,9 +163,11 @@ struct __attribute__((__packed__)) psx_cpu_t {
|
||||
|
||||
psx_bus_t* bus;
|
||||
|
||||
psx_cpu_kcall_hook_t a_function_hook;
|
||||
psx_cpu_kcall_hook_t b_function_hook;
|
||||
};
|
||||
psx_cpu_kcall_hook_t a_function_hook;
|
||||
psx_cpu_kcall_hook_t b_function_hook;
|
||||
psx_cpu_execution_mode_t execution_mode;
|
||||
struct psx_cpu_cache_t* cache;
|
||||
};
|
||||
|
||||
/*
|
||||
0 IEc Current Interrupt Enable (0=Disable, 1=Enable) ;rfe pops IUp here
|
||||
@@ -231,9 +245,14 @@ void psx_cpu_set_irq_pending(psx_cpu_t*);
|
||||
void psx_cpu_load_state(psx_cpu_t*, FILE*);
|
||||
void psx_cpu_save_state(psx_cpu_t*, FILE*);
|
||||
void psx_cpu_fetch(psx_cpu_t*);
|
||||
void psx_cpu_set_a_kcall_hook(psx_cpu_t*, psx_cpu_kcall_hook_t);
|
||||
void psx_cpu_set_b_kcall_hook(psx_cpu_t*, psx_cpu_kcall_hook_t);
|
||||
int psx_cpu_execute(psx_cpu_t*);
|
||||
void psx_cpu_set_a_kcall_hook(psx_cpu_t*, psx_cpu_kcall_hook_t);
|
||||
void psx_cpu_set_b_kcall_hook(psx_cpu_t*, psx_cpu_kcall_hook_t);
|
||||
void psx_cpu_set_execution_mode(psx_cpu_t*, psx_cpu_execution_mode_t);
|
||||
psx_cpu_execution_mode_t psx_cpu_get_execution_mode(const psx_cpu_t*);
|
||||
void psx_cpu_invalidate_cache(psx_cpu_t*);
|
||||
void psx_cpu_invalidate_range(psx_cpu_t*, uint32_t, uint32_t);
|
||||
psx_cpu_cache_stats_t psx_cpu_get_cache_stats(const psx_cpu_t*);
|
||||
int psx_cpu_execute(psx_cpu_t*);
|
||||
|
||||
/*
|
||||
00h INT Interrupt
|
||||
@@ -310,4 +329,4 @@ int psx_cpu_execute(psx_cpu_t*);
|
||||
#define GTEF_M1POVF 0x40000000
|
||||
#define GTEF_ERRORF 0x80000000
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+90
-3
@@ -13,20 +13,28 @@
|
||||
|
||||
#define CHD_CD_FRAME_SIZE CD_FRAME_SIZE
|
||||
#define CHD_CD_TRACK_ALIGN 4u
|
||||
#define CHD_DEFAULT_PREGAP_FRAMES (2u * 75u)
|
||||
#define CHD_TRACK1_PREGAP_FRAMES (2u * 75u)
|
||||
|
||||
typedef enum {
|
||||
CHD_TRACK_MODE_AUDIO = 0,
|
||||
CHD_TRACK_MODE_DATA = 1
|
||||
} chd_track_mode_t;
|
||||
|
||||
typedef enum {
|
||||
CHD_SUBCHANNEL_NONE = 0,
|
||||
CHD_SUBCHANNEL_COOKED,
|
||||
CHD_SUBCHANNEL_RAW
|
||||
} chd_subchannel_mode_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t track_number;
|
||||
uint32_t start_lba;
|
||||
uint64_t file_lba;
|
||||
uint32_t pregap_frames;
|
||||
uint32_t data_frames;
|
||||
uint32_t postgap_frames;
|
||||
chd_track_mode_t mode;
|
||||
chd_subchannel_mode_t subchannel_mode;
|
||||
} chd_track_t;
|
||||
|
||||
struct chd_s {
|
||||
@@ -119,6 +127,25 @@ static int chd_parse_track_mode(const char* type_str, chd_track_mode_t* mode_out
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chd_parse_subchannel_mode(const char* subtype, chd_subchannel_mode_t* mode_out) {
|
||||
if (!subtype || !mode_out)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(subtype, "NONE")) {
|
||||
*mode_out = CHD_SUBCHANNEL_NONE;
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(subtype, "RW")) {
|
||||
*mode_out = CHD_SUBCHANNEL_COOKED;
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(subtype, "RW_RAW")) {
|
||||
*mode_out = CHD_SUBCHANNEL_RAW;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chd_read_hunk(chd_t* chd, uint32_t hunk_index) {
|
||||
if (!chd || !chd->handle || !chd->hunk_buffer) {
|
||||
return 0;
|
||||
@@ -157,6 +184,7 @@ static int chd_find_track(const chd_t* chd, uint32_t lba, int* is_pregap_out) {
|
||||
? (track->start_lba - track->pregap_frames)
|
||||
: 0u;
|
||||
const uint32_t track_end = track->start_lba + track->data_frames;
|
||||
const uint32_t postgap_end = track_end + track->postgap_frames;
|
||||
|
||||
if (lba >= pregap_start && lba < track->start_lba) {
|
||||
if (is_pregap_out) {
|
||||
@@ -171,6 +199,13 @@ static int chd_find_track(const chd_t* chd, uint32_t lba, int* is_pregap_out) {
|
||||
}
|
||||
return (int)index;
|
||||
}
|
||||
|
||||
if (lba >= track_end && lba < postgap_end) {
|
||||
if (is_pregap_out) {
|
||||
*is_pregap_out = 1;
|
||||
}
|
||||
return (int)index;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_pregap_out) {
|
||||
@@ -252,6 +287,7 @@ int chd_load(chd_t* chd, const char* path) {
|
||||
int postgap_frames = 0;
|
||||
uint32_t metadata_length = 0;
|
||||
chd_track_mode_t track_mode = CHD_TRACK_MODE_DATA;
|
||||
chd_subchannel_mode_t subchannel_mode = CHD_SUBCHANNEL_NONE;
|
||||
int have_metadata = 0;
|
||||
|
||||
memset(metadata, 0, sizeof(metadata));
|
||||
@@ -303,8 +339,14 @@ int chd_load(chd_t* chd, const char* path) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pregap_frames <= 0 && track_mode != CHD_TRACK_MODE_AUDIO) {
|
||||
pregap_frames = CHD_DEFAULT_PREGAP_FRAMES;
|
||||
if (!chd_parse_subchannel_mode(subtype_str, &subchannel_mode)) {
|
||||
log_error("Unsupported CHD subchannel mode '%s' in %s", subtype_str, path);
|
||||
chd_reset(chd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pregap_frames <= 0 && track_num == 1) {
|
||||
pregap_frames = CHD_TRACK1_PREGAP_FRAMES;
|
||||
}
|
||||
|
||||
const int pregap_in_file = (pregap_frames > 0 && toupper((unsigned char)pgtype_str[0]) == 'V');
|
||||
@@ -339,7 +381,9 @@ int chd_load(chd_t* chd, const char* path) {
|
||||
.file_lba = track_file_lba,
|
||||
.pregap_frames = (uint32_t)pregap_frames,
|
||||
.data_frames = data_frames,
|
||||
.postgap_frames = (uint32_t)(postgap_frames > 0 ? postgap_frames : 0),
|
||||
.mode = track_mode,
|
||||
.subchannel_mode = subchannel_mode,
|
||||
};
|
||||
|
||||
if (!chd_append_track(chd, &track)) {
|
||||
@@ -349,6 +393,9 @@ int chd_load(chd_t* chd, const char* path) {
|
||||
}
|
||||
|
||||
disc_lba += data_frames;
|
||||
if (postgap_frames > 0) {
|
||||
disc_lba += (uint32_t)postgap_frames;
|
||||
}
|
||||
file_lba += data_frames;
|
||||
file_lba = align_up_u64(file_lba, CHD_CD_TRACK_ALIGN);
|
||||
}
|
||||
@@ -466,6 +513,46 @@ int chd_get_track_lba(chd_t* chd, int track) {
|
||||
return (int)chd->tracks[(size_t)track - 1u].start_lba;
|
||||
}
|
||||
|
||||
static void chd_deinterleave_subchannel(const uint8_t raw[96], uint8_t cooked[96]) {
|
||||
memset(cooked, 0, 96);
|
||||
for (unsigned symbol = 0; symbol < 96; ++symbol) {
|
||||
for (unsigned channel = 0; channel < 8; ++channel) {
|
||||
const uint8_t bit = (uint8_t)((raw[symbol] >> (7u - channel)) & 1u);
|
||||
cooked[channel * 12u + symbol / 8u] |= (uint8_t)(bit << (7u - (symbol & 7u)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int chd_read_subchannel_q(chd_t* chd, uint32_t lba, uint8_t q[12]) {
|
||||
if (!chd || !q || !chd->handle || !chd->hunk_buffer)
|
||||
return 0;
|
||||
|
||||
int is_gap = 0;
|
||||
const int track_index = chd_find_track(chd, lba, &is_gap);
|
||||
if (track_index < 0 || is_gap)
|
||||
return 0;
|
||||
|
||||
const chd_track_t* track = &chd->tracks[track_index];
|
||||
if (track->subchannel_mode == CHD_SUBCHANNEL_NONE)
|
||||
return 0;
|
||||
|
||||
const uint64_t file_frame = track->file_lba + (uint64_t)(lba - track->start_lba);
|
||||
const uint32_t hunk_index = (uint32_t)(file_frame / chd->sectors_per_hunk);
|
||||
const uint32_t hunk_offset = (uint32_t)((file_frame % chd->sectors_per_hunk) * CHD_CD_FRAME_SIZE);
|
||||
if ((hunk_offset + CHD_CD_FRAME_SIZE) > chd->hunk_size || !chd_read_hunk(chd, hunk_index))
|
||||
return 0;
|
||||
|
||||
const uint8_t* subchannel = &chd->hunk_buffer[hunk_offset + CD_SECTOR_SIZE];
|
||||
if (track->subchannel_mode == CHD_SUBCHANNEL_COOKED) {
|
||||
memcpy(q, subchannel + 12, 12);
|
||||
} else {
|
||||
uint8_t cooked[96];
|
||||
chd_deinterleave_subchannel(subchannel, cooked);
|
||||
memcpy(q, cooked + 12, 12);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void chd_destroy(chd_t* chd) {
|
||||
if (!chd) {
|
||||
return;
|
||||
|
||||
@@ -17,6 +17,7 @@ int chd_query(chd_t* cue, uint32_t lba);
|
||||
int chd_get_track_number(chd_t* cue, uint32_t lba);
|
||||
int chd_get_track_count(chd_t* cue);
|
||||
int chd_get_track_lba(chd_t* cue, int track);
|
||||
int chd_read_subchannel_q(chd_t* cue, uint32_t lba, uint8_t q[12]);
|
||||
void chd_destroy(chd_t* cue);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -203,6 +203,7 @@ int psx_disc_open_as(psx_disc_t* disc, const char* path, int type) {
|
||||
disc->get_track_number = (get_track_number_func)chd_get_track_number;
|
||||
disc->get_track_count = (get_track_count_func)chd_get_track_count;
|
||||
disc->get_track_lba = (get_track_lba_func)chd_get_track_lba;
|
||||
disc->read_subchannel_q = (read_subchannel_q_func)chd_read_subchannel_q;
|
||||
disc->destroy = (destroy_func)chd_destroy;
|
||||
} break;
|
||||
#endif
|
||||
@@ -242,6 +243,13 @@ int psx_disc_get_track_lba(psx_disc_t* disc, int track) {
|
||||
return disc->get_track_lba(disc->udata, track);
|
||||
}
|
||||
|
||||
int psx_disc_read_subchannel_q(psx_disc_t* disc, uint32_t lba, uint8_t q[12]) {
|
||||
if (!disc || !disc->read_subchannel_q || !q)
|
||||
return 0;
|
||||
|
||||
return disc->read_subchannel_q(disc->udata, lba, q);
|
||||
}
|
||||
|
||||
void psx_disc_destroy(psx_disc_t* disc) {
|
||||
disc->destroy(disc->udata);
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef int (*query_sector_func)(void*, uint32_t);
|
||||
typedef int (*get_track_number_func)(void*, uint32_t);
|
||||
typedef int (*get_track_count_func)(void*);
|
||||
typedef uint32_t (*get_track_lba_func)(void*, int);
|
||||
typedef int (*read_subchannel_q_func)(void*, uint32_t, uint8_t*);
|
||||
typedef void (*destroy_func)(void*);
|
||||
|
||||
typedef struct {
|
||||
@@ -58,6 +59,7 @@ typedef struct {
|
||||
get_track_number_func get_track_number;
|
||||
get_track_count_func get_track_count;
|
||||
get_track_lba_func get_track_lba;
|
||||
read_subchannel_q_func read_subchannel_q;
|
||||
destroy_func destroy;
|
||||
} psx_disc_t;
|
||||
|
||||
@@ -69,6 +71,7 @@ int psx_disc_query(psx_disc_t* disc, uint32_t lba);
|
||||
int psx_disc_get_track_number(psx_disc_t* disc, uint32_t lba);
|
||||
int psx_disc_get_track_count(psx_disc_t* disc);
|
||||
int psx_disc_get_track_lba(psx_disc_t* disc, int track);
|
||||
int psx_disc_read_subchannel_q(psx_disc_t* disc, uint32_t lba, uint8_t q[12]);
|
||||
void psx_disc_close(psx_disc_t* disc);
|
||||
void psx_disc_destroy(psx_disc_t* disc);
|
||||
|
||||
|
||||
+16
-2
@@ -417,13 +417,27 @@ void cdrom_cmd_getlocl(psx_cdrom_t* cdrom) {
|
||||
|
||||
void cdrom_cmd_getlocp(psx_cdrom_t* cdrom) {
|
||||
int lba = cdrom->lba;
|
||||
|
||||
int track = psx_disc_get_track_number(cdrom->disc, lba);
|
||||
int track_lba = psx_disc_get_track_lba(cdrom->disc, track);
|
||||
|
||||
if (!cdrom->seek_precision)
|
||||
lba -= 25;
|
||||
|
||||
uint8_t subq[12];
|
||||
if (lba >= 0 && psx_disc_read_subchannel_q(cdrom->disc, (uint32_t)lba, subq)) {
|
||||
cdrom_set_int(cdrom, 3);
|
||||
queue_push(cdrom->response, subq[1]);
|
||||
queue_push(cdrom->response, subq[2]);
|
||||
queue_push(cdrom->response, subq[3]);
|
||||
queue_push(cdrom->response, subq[4]);
|
||||
queue_push(cdrom->response, subq[5]);
|
||||
queue_push(cdrom->response, subq[7]);
|
||||
queue_push(cdrom->response, subq[8]);
|
||||
queue_push(cdrom->response, subq[9]);
|
||||
cdrom_restore_state(cdrom);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t diff = lba - track_lba;
|
||||
|
||||
if (diff < 0)
|
||||
@@ -732,4 +746,4 @@ void cdrom_cmd_readtoc(psx_cdrom_t* cdrom) {
|
||||
|
||||
void cdrom_cmd_videocd(psx_cdrom_t* cdrom) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,11 @@ int psx_exe_load(psx_cpu_t* cpu, const char* path) {
|
||||
// Read to RAM directly
|
||||
uint32_t offset = hdr.ramdest & 0x7fffffff;
|
||||
|
||||
if (!fread(cpu->bus->ram->buf + offset, 1, hdr.filesz, file))
|
||||
return 3;
|
||||
|
||||
if (!fread(cpu->bus->ram->buf + offset, 1, hdr.filesz, file))
|
||||
return 3;
|
||||
|
||||
psx_cpu_invalidate_range(cpu, offset, hdr.filesz);
|
||||
|
||||
// Load initial register values
|
||||
cpu->pc = hdr.ipc;
|
||||
cpu->next_pc = cpu->pc + 4;
|
||||
@@ -43,4 +45,4 @@ int psx_exe_load(psx_cpu_t* cpu, const char* path) {
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user