ref: ce32c2fd274db2a5d5302a3744758f62c6d8fd6c
parent: 8a5aaf02459fea9f1cc287dc6406e3557547407f
author: allkern <lisandroaalarcon@gmail.com>
date: Tue Mar 19 18:30:01 EDT 2024
Fix stuff
--- a/.gitignore
+++ b/.gitignore
@@ -20,4 +20,5 @@
*.zip
*.cue
*.iso
-*.mcd
\ No newline at end of file
+*.mcd
+*.rom
--- a/frontend/config.c
+++ b/frontend/config.c
@@ -77,7 +77,7 @@
}
void psxe_cfg_load_defaults(psxe_config_t* cfg) {- cfg->bios = NULL;
+ cfg->bios = "bios.bin";
cfg->bios_search = "bios";
cfg->exe = NULL;
cfg->help_model = 0;
@@ -91,6 +91,7 @@
cfg->log_level = LOG_FATAL;
cfg->quiet = 0;
cfg->cd_path = NULL;
+ cfg->exp_path = NULL;
}
void psxe_cfg_load(psxe_config_t* cfg, int argc, const char* argv[]) {@@ -111,6 +112,7 @@
const char* region = NULL;
const char* psxe_version = NULL;
const char* cd_path = NULL;
+ const char* exp_path = NULL;
static const char *const usages[] = {"psxe [options] path-to-cdrom",
@@ -124,15 +126,16 @@
OPT_BOOLEAN ('v', "version" , &version , "Display version and build information", NULL, 0, 0), OPT_GROUP("Basic options"), OPT_BOOLEAN ('a', "use-args" , &use_args , "Ignore settings file, use CLI args instead", NULL, 0, 0),- OPT_STRING ('b', "bios" , &bios , "Use this BIOS file (ignores -B, -M)", NULL, 0, 0),+ OPT_STRING ('b', "bios" , &bios , "Specify a BIOS file (ignores -B, -M)", NULL, 0, 0), OPT_BOOLEAN ('B', "bios-folder" , &bios_search , "Specify a BIOS search folder", NULL, 0, 0), OPT_STRING ('c', "console-source", &console_source, "Select console source (auto, null, kernel, atcons)"),+ OPT_STRING ('e', "exp-rom" , &exp_path , "Specify an expansion ROM file"), OPT_INTEGER ('L', "log-level" , &log_level , "Set log level"), OPT_STRING ('M', "model" , &model , "Specify console model (SPCH-XXXX)", NULL, 0, 0), OPT_STRING ('r', "region" , ®ion , "Specify console region"), OPT_STRING ('S', "settings-file" , &settings_path , "Specify settings file path", NULL, 0, 0), OPT_BOOLEAN ('q', "quiet" , &quiet , "Silence all logs (ignores -L)"),- OPT_STRING ('x', "exe" , &exe , "Boot this PS-X EXE file"),+ OPT_STRING ('x', "exe" , &exe , "Launch a PS-X EXE file"),OPT_STRING (0 , "cdrom" , &cd_path , "Specify a CDROM image"),
OPT_END()
};
@@ -274,6 +277,9 @@
if (psxe_version)
cfg->psxe_version = psxe_version;
+
+ if (exp_path)
+ cfg->exp_path = exp_path;
}
// To-do: Implement BIOS searching
--- a/frontend/config.h
+++ b/frontend/config.h
@@ -24,6 +24,7 @@
const char* region;
const char* psxe_version;
const char* cd_path;
+ const char* exp_path;
} psxe_config_t;
psxe_config_t* psxe_cfg_create();
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -34,7 +34,7 @@
log_set_level(cfg->log_level);
psx_t* psx = psx_create();
- psx_init(psx, cfg->bios);
+ psx_init(psx, cfg->bios, cfg->exp_path);
psx_cdrom_t* cdrom = psx_get_cdrom(psx);
--- a/frontend/screen.c
+++ b/frontend/screen.c
@@ -52,13 +52,10 @@
screen->texture_height = PSX_GPU_FB_HEIGHT;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
- SDL_SetHint("SDL_HINT_RENDER_SCALE_QUALITY", "0");SDL_SetRenderDrawColor(screen->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
}
void psxe_screen_reload(psxe_screen_t* screen) {- SDL_SetHint("SDL_HINT_RENDER_SCALE_QUALITY", "0");-
if (screen->texture) SDL_DestroyTexture(screen->texture);
if (screen->renderer) SDL_DestroyRenderer(screen->renderer);
if (screen->window) SDL_DestroyWindow(screen->window);
@@ -81,7 +78,7 @@
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
screen->width * screen->scale,
screen->height * screen->scale,
- SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI
+ 0
);
screen->renderer = SDL_CreateRenderer(
@@ -90,6 +87,8 @@
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
);
+ SDL_SetHint("SDL_HINT_RENDER_SCALE_QUALITY", "linear"),+
screen->texture = SDL_CreateTexture(
screen->renderer,
screen->format,
@@ -97,6 +96,8 @@
screen->texture_width, screen->texture_height
);
+ SDL_SetTextureScaleMode(screen->texture, screen->bilinear);
+
// Check for retina displays
int width = 0, height = 0;
@@ -130,20 +131,24 @@
}
void psxe_screen_update(psxe_screen_t* screen) {- void* display_buf = screen->debug_mode ?
- psx_get_vram(screen->psx) : psx_get_display_buffer(screen->psx);
+ // void* vram = psx_get_vram(screen->psx);
- // // Update texture with Lock/UnlockTexture
- // int pitch;
- // uint8_t* ptr = NULL;
+ // if (screen->field & 2) {+ // for (int y = screen->field & 1; y < 512; y += 2) {+ // memcpy(
+ // ((uint8_t*)screen->buf) + (y * PSX_GPU_FB_STRIDE),
+ // ((uint8_t*)vram) + (y * PSX_GPU_FB_STRIDE),
+ // PSX_GPU_FB_STRIDE
+ // );
+ // }
+ // }
- // SDL_LockTexture(screen->texture, NULL, &ptr, &pitch);
+ // screen->field += 1;
+ // screen->field &= 3;
- // for (int y = 0; y < screen->texture_height; y++)
- // memcpy(ptr + (y * pitch), display_buf + (y * PSX_GPU_FB_STRIDE), pitch);
+ void* display_buf = screen->debug_mode ?
+ psx_get_vram(screen->psx) : psx_get_display_buffer(screen->psx);
- // SDL_UnlockTexture(screen->texture);
-
SDL_UpdateTexture(screen->texture, NULL, display_buf, PSX_GPU_FB_STRIDE);
SDL_RenderClear(screen->renderer);
@@ -212,6 +217,12 @@
} break;
case SDLK_F4: {+ screen->bilinear = !screen->bilinear;
+
+ psxe_gpu_dmode_event_cb(screen->psx->gpu);
+ } break;
+
+ case SDLK_F11: {screen->fullscreen = !screen->fullscreen;
SDL_SetWindowFullscreen(
@@ -237,8 +248,16 @@
uint16_t mask = screen_get_button(event.key.keysym.sym);
psx_pad_button_press(screen->pad, 0, mask);
+
+ if (event.key.keysym.sym == SDLK_RETURN) {+ psx_exp2_atcons_put(screen->psx->exp2, 13);
+ }
} break;
+ case SDL_TEXTINPUT: {+ psx_exp2_atcons_put(screen->psx->exp2, event.text.text[0]);
+ } break;
+
case SDL_KEYUP: {uint16_t mask = screen_get_button(event.key.keysym.sym);
@@ -280,9 +299,12 @@
screen->texture_height = PSX_GPU_FB_HEIGHT;
} else { if (screen->fullscreen) {- screen->width = 1920;
- screen->height = 1080;
+ SDL_DisplayMode dm;
+ SDL_GetCurrentDisplayMode(0, &dm);
+ screen->width = dm.w;
+ screen->height = dm.h;
+
if (screen->vertical_mode) {screen->image_width = screen->height;
screen->image_height = (double)screen->height / psx_get_display_aspect(screen->psx);
@@ -330,6 +352,8 @@
SDL_TEXTUREACCESS_STREAMING,
screen->texture_width, screen->texture_height
);
+
+ SDL_SetTextureScaleMode(screen->texture, screen->bilinear);
SDL_SetWindowSize(screen->window, screen->width, screen->height);
}
--- a/frontend/screen.h
+++ b/frontend/screen.h
@@ -23,6 +23,7 @@
unsigned int format;
unsigned int texture_width, texture_height;
+ int bilinear;
int fullscreen;
int vertical_mode;
int debug_mode;
--- a/psx/bus.c
+++ b/psx/bus.c
@@ -48,6 +48,7 @@
HANDLE_READ(ram, 32);
HANDLE_READ(dma, 32);
HANDLE_READ(exp1, 32);
+ HANDLE_READ(exp2, 32);
HANDLE_READ(mc1, 32);
HANDLE_READ(mc2, 32);
HANDLE_READ(mc3, 32);
@@ -82,6 +83,7 @@
HANDLE_READ(ram, 16);
HANDLE_READ(dma, 16);
HANDLE_READ(exp1, 16);
+ HANDLE_READ(exp2, 16);
HANDLE_READ(mc1, 16);
HANDLE_READ(mc2, 16);
HANDLE_READ(mc3, 16);
@@ -112,6 +114,7 @@
HANDLE_READ(ram, 8);
HANDLE_READ(dma, 8);
HANDLE_READ(exp1, 8);
+ HANDLE_READ(exp2, 8);
HANDLE_READ(mc1, 8);
HANDLE_READ(mc2, 8);
HANDLE_READ(mc3, 8);
@@ -146,6 +149,7 @@
HANDLE_WRITE(ram, 32);
HANDLE_WRITE(dma, 32);
HANDLE_WRITE(exp1, 32);
+ HANDLE_WRITE(exp2, 32);
HANDLE_WRITE(mc1, 32);
HANDLE_WRITE(mc2, 32);
HANDLE_WRITE(mc3, 32);
@@ -178,6 +182,7 @@
HANDLE_WRITE(ram, 16);
HANDLE_WRITE(dma, 16);
HANDLE_WRITE(exp1, 16);
+ HANDLE_WRITE(exp2, 16);
HANDLE_WRITE(mc1, 16);
HANDLE_WRITE(mc2, 16);
HANDLE_WRITE(mc3, 16);
@@ -206,6 +211,7 @@
HANDLE_WRITE(ram, 8);
HANDLE_WRITE(dma, 8);
HANDLE_WRITE(exp1, 8);
+ HANDLE_WRITE(exp2, 8);
HANDLE_WRITE(mc1, 8);
HANDLE_WRITE(mc2, 8);
HANDLE_WRITE(mc3, 8);
@@ -237,6 +243,10 @@
void psx_bus_init_exp1(psx_bus_t* bus, psx_exp1_t* exp1) {bus->exp1 = exp1;
+}
+
+void psx_bus_init_exp2(psx_bus_t* bus, psx_exp2_t* exp2) {+ bus->exp2 = exp2;
}
void psx_bus_init_mc1(psx_bus_t* bus, psx_mc1_t* mc1) {--- a/psx/bus_init.h
+++ b/psx/bus_init.h
@@ -5,6 +5,7 @@
#include "dev/ram.h"
#include "dev/dma.h"
#include "dev/exp1.h"
+#include "dev/exp2.h"
#include "dev/mc1.h"
#include "dev/mc2.h"
#include "dev/mc3.h"
@@ -22,6 +23,7 @@
psx_ram_t* ram;
psx_dma_t* dma;
psx_exp1_t* exp1;
+ psx_exp2_t* exp2;
psx_mc1_t* mc1;
psx_mc2_t* mc2;
psx_mc3_t* mc3;
@@ -41,6 +43,7 @@
void psx_bus_init_ram(psx_bus_t*, psx_ram_t*);
void psx_bus_init_dma(psx_bus_t*, psx_dma_t*);
void psx_bus_init_exp1(psx_bus_t*, psx_exp1_t*);
+void psx_bus_init_exp2(psx_bus_t*, psx_exp2_t*);
void psx_bus_init_mc1(psx_bus_t*, psx_mc1_t*);
void psx_bus_init_mc2(psx_bus_t*, psx_mc2_t*);
void psx_bus_init_mc3(psx_bus_t*, psx_mc3_t*);
--- a/psx/dev/bios.c
+++ b/psx/dev/bios.c
@@ -15,8 +15,6 @@
bios->io_base = PSX_BIOS_BEGIN;
bios->io_size = PSX_BIOS_SIZE;
bios->bus_delay = 18;
-
- bios->buf = (uint8_t*)malloc(PSX_BIOS_SIZE);
}
void psx_bios_load(psx_bios_t* bios, const char* path) {@@ -28,7 +26,21 @@
exit(1);
}
- if (!fread(bios->buf, 1, PSX_BIOS_SIZE, file)) {+ // Almost all PS1 BIOS ROMs are 512 KiB in size.
+ // There's (at least) one exception, and that is SCPH-5903.
+ // This is a special asian model PS1 that had built-in support
+ // for Video CD (VCD) playback. Its BIOS is double the normal
+ // size
+ fseek(file, 0, SEEK_END);
+
+ size_t size = ftell(file);
+
+ fseek(file, 0, SEEK_SET);
+
+ bios->buf = malloc(size);
+ bios->io_size = size;
+
+ if (!fread(bios->buf, 1, size, file)) { perror("Error reading BIOS file");exit(1);
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -1,6 +1,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include "cdrom.h"
#include "../log.h"
@@ -21,6 +22,106 @@
Modchip:Audio/Mode1 INT3(stat) INT2(02h,00h, 00h,00h, 53h,43h,45h,4xh)
*/
+msf_t cdrom_get_track_addr(psx_cdrom_t* cdrom, msf_t msf) {+ uint32_t lba = msf_to_address(msf);
+
+ int num_tracks, track;
+
+ psx_disc_get_track_count(cdrom->disc, &num_tracks);
+
+ for (track = 1; track < num_tracks - 1; track++) {+ msf_t curr, next;
+
+ psx_disc_get_track_addr(cdrom->disc, &curr, track);
+ psx_disc_get_track_addr(cdrom->disc, &next, track + 1);
+
+ uint32_t curr_lba = msf_to_address(curr);
+ uint32_t next_lba = msf_to_address(next);
+
+ printf("lba=%02u:%02u:%02u (%08x) curr=%02u:%02u:%02u (%08x) next=%02u:%02u:%02u (%08x)\n",+ msf.m,
+ msf.s,
+ msf.f,
+ lba,
+ curr.m,
+ curr.s,
+ curr.f,
+ curr_lba,
+ next.m,
+ next.s,
+ next.f,
+ next_lba
+ );
+
+ if ((lba >= curr_lba) && (lba < next_lba))
+ break;
+ }
+
+ msf_t track_msf;
+
+ psx_disc_get_track_addr(cdrom->disc, &track_msf, track);
+
+ return track_msf;
+}
+
+void cdrom_fetch_video_sector(psx_cdrom_t* cdrom) {+ while (true) {+ if (psx_disc_seek(cdrom->disc, cdrom->seek_msf))
+ return;
+
+ psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
+
+ // printf("%02u:%02u:%02u - file=%02x channel=%02x sm=%02x (%u%u%u%u%u%u%u%u) ci=%02x... ",+ // cdrom->seek_msf.m,
+ // cdrom->seek_msf.s,
+ // cdrom->seek_msf.f,
+ // cdrom->dfifo[0x10],
+ // cdrom->dfifo[0x11],
+ // cdrom->dfifo[0x12],
+ // (cdrom->dfifo[0x12] & 0x80) != 0,
+ // (cdrom->dfifo[0x12] & 0x40) != 0,
+ // (cdrom->dfifo[0x12] & 0x20) != 0,
+ // (cdrom->dfifo[0x12] & 0x10) != 0,
+ // (cdrom->dfifo[0x12] & 0x08) != 0,
+ // (cdrom->dfifo[0x12] & 0x04) != 0,
+ // (cdrom->dfifo[0x12] & 0x02) != 0,
+ // (cdrom->dfifo[0x12] & 0x01) != 0,
+ // cdrom->dfifo[0x13]
+ // );
+
+ msf_add_f(&cdrom->seek_msf, 1);
+
+ // Check RT and Video/Data bit
+ uint8_t sm = cdrom->dfifo[0x12] & 4;
+
+ if (sm) {+ // printf("Not sent (Unfiltered)\n");+
+ continue;
+ }
+
+ // If we get here it means this is a real-time video sector.
+ // If the XA filter is disabled, we're done
+ if (!(cdrom->mode & MODE_XA_FILTER)) {+ // printf("Sent (Unfiltered)\n");+ return;
+ }
+
+ // Else check XA file/channel
+ int file_eq = cdrom->dfifo[0x10] == cdrom->xa_file;
+ int channel_eq = cdrom->dfifo[0x11] == cdrom->xa_channel;
+
+ // If they are equal to our filter values, we're done
+ // else keep searching
+ if (file_eq && channel_eq) {+ // printf("Sent (Filtered)\n");+ return;
+ }
+
+ // printf("Not sent (Filtered)\n");+ }
+}
+
#define GETID_RESPONSE_SIZE 8
#define GETID_RESPONSE_END (GETID_RESPONSE_SIZE - 1)
@@ -157,10 +258,18 @@
exit(1);
}
void cdrom_cmd_getstat(psx_cdrom_t* cdrom) {- cdrom->delayed_command = CDL_NONE;
-
switch (cdrom->state) { case CD_STATE_RECV_CMD: {+ if (cdrom->ongoing_read_command) {+ cdrom->status |= STAT_BUSYSTS_MASK;
+ // printf("command=%02x\n", cdrom->ongoing_read_command);+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
+ cdrom->irq_delay = DELAY_1MS;
+
+ return;
+ }
+
if (cdrom->pfifo_index) { log_fatal("CdlGetStat: Expected exactly 0 parameters");@@ -183,12 +292,15 @@
RESP_PUSH(
GETSTAT_MOTOR |
(cdrom->cdda_playing ? GETSTAT_PLAY : 0) |
+ // (cdrom->ongoing_read_command ? GETSTAT_READ : 0) |
(cdrom->disc ? 0 : GETSTAT_TRAYOPEN)
);
- if (cdrom->read_ongoing) {+ if (cdrom->ongoing_read_command) {+ cdrom->status |= STAT_BUSYSTS_MASK;
+ // printf("command=%02x\n", cdrom->ongoing_read_command);cdrom->state = CD_STATE_SEND_RESP2;
- cdrom->delayed_command = CDL_READN;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
cdrom->irq_delay = DELAY_1MS;
} else {cdrom->delayed_command = CDL_NONE;
@@ -216,16 +328,6 @@
return;
}
- //if (!cdrom->read_ongoing) {- cdrom->irq_delay = DELAY_1MS;
- cdrom->delayed_command = CDL_SETLOC;
- cdrom->state = CD_STATE_SEND_RESP1;
- // } else {- // cdrom->irq_delay = DELAY_1MS;
- // cdrom->delayed_command = CDL_READN;
- // cdrom->state = CD_STATE_SEND_RESP2;
- // }
-
int f = PFIFO_POP;
int s = PFIFO_POP;
int m = PFIFO_POP;
@@ -240,26 +342,40 @@
return;
}
- cdrom->seek_ff = f;
- cdrom->seek_ss = s;
- cdrom->seek_mm = m;
+ cdrom->seek_msf.m = m;
+ cdrom->seek_msf.s = s;
+ cdrom->seek_msf.f = f;
+ msf_from_bcd(&cdrom->seek_msf);
+
+ cdrom->cdda_msf = cdrom->seek_msf;
+
cdrom->seek_pending = 1;
log_fatal("setloc: %02x:%02x:%02x",- cdrom->seek_mm,
- cdrom->seek_ss,
- cdrom->seek_ff
+ cdrom->seek_msf.m,
+ cdrom->seek_msf.s,
+ cdrom->seek_msf.f
);
+
+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->delayed_command = CDL_SETLOC;
+ cdrom->state = CD_STATE_SEND_RESP1;
} break;
case CD_STATE_SEND_RESP1: {- cdrom->delayed_command = CDL_NONE;
-
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(GETSTAT_MOTOR);
- cdrom->state = CD_STATE_RECV_CMD;
+ if (cdrom->ongoing_read_command) {+ // printf("command=%02x\n", cdrom->ongoing_read_command);+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
+ cdrom->irq_delay = DELAY_1MS;
+ } else {+ cdrom->delayed_command = CDL_NONE;
+ cdrom->state = CD_STATE_RECV_CMD;
+ }
} break;
// Read ongoing
@@ -269,7 +385,7 @@
int m = PFIFO_POP;
if (!(VALID_BCD(m) && VALID_BCD(s) && VALID_BCD(f) && (f < 0x75))) {- cdrom->read_ongoing = false;
+ cdrom->ongoing_read_command = false;
cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_ERROR;
cdrom->state = CD_STATE_ERROR;
@@ -279,9 +395,9 @@
return;
}
- cdrom->seek_ff = f;
- cdrom->seek_ss = s;
- cdrom->seek_mm = m;
+ cdrom->seek_msf.m = m;
+ cdrom->seek_msf.s = s;
+ cdrom->seek_msf.f = f;
} break;
}
}
@@ -316,9 +432,9 @@
msf_to_bcd(&cdrom->cdda_msf);
cdrom->cdda_track = track;
- cdrom->seek_mm = cdrom->cdda_msf.m;
- cdrom->seek_ss = cdrom->cdda_msf.s;
- cdrom->seek_ff = cdrom->cdda_msf.f;
+ cdrom->seek_msf.m = cdrom->cdda_msf.m;
+ cdrom->seek_msf.s = cdrom->cdda_msf.s;
+ cdrom->seek_msf.f = cdrom->cdda_msf.f;
cdrom->seek_pending = 1;
}
@@ -326,24 +442,17 @@
if (cdrom->seek_pending) {cdrom->seek_pending = 0;
- cdrom->cdda_msf.m = cdrom->seek_mm;
- cdrom->cdda_msf.s = cdrom->seek_ss;
- cdrom->cdda_msf.f = cdrom->seek_ff;
+ printf("Seeked to location\n");- // Convert seek to I
- msf_t msf = cdrom->cdda_msf;
-
- msf_from_bcd(&msf);
-
+ cdrom->cdda_msf = cdrom->seek_msf;
+
// Seek to that address and read sector
- psx_disc_seek(cdrom->disc, msf);
+ psx_disc_seek(cdrom->disc, cdrom->cdda_msf);
psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
// Increment sector
- msf_add_f(&msf, 1);
- msf_to_bcd(&msf);
+ msf_add_f(&cdrom->cdda_msf, 1);
- cdrom->cdda_msf = msf;
cdrom->cdda_sector_offset = 0;
}
@@ -361,7 +470,7 @@
}
void cdrom_cmd_readn(psx_cdrom_t* cdrom) {cdrom->delayed_command = CDL_NONE;
- cdrom->read_ongoing = 1;
+ cdrom->ongoing_read_command = CDL_READN;
switch (cdrom->state) { case CD_STATE_RECV_CMD: {@@ -377,17 +486,8 @@
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(GETSTAT_MOTOR);
- msf_t msf;
-
- msf.m = cdrom->seek_mm;
- msf.s = cdrom->seek_ss;
- msf.f = cdrom->seek_ff;
-
- msf_from_bcd(&msf);
-
- cdrom->xa_msf = msf;
-
if (cdrom->mode & MODE_XA_ADPCM) {+ cdrom->xa_msf = cdrom->seek_msf;
cdrom->xa_playing = 1;
SET_BITS(status, STAT_ADPBUSY_MASK, STAT_ADPBUSY_MASK);
@@ -402,7 +502,7 @@
);
}
- int err = psx_disc_seek(cdrom->disc, msf);
+ int err = psx_disc_seek(cdrom->disc, cdrom->seek_msf);
if (err) {log_set_quiet(0);
@@ -420,34 +520,6 @@
psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
- msf_t sector_msf;
-
- sector_msf.m = cdrom->dfifo[0x0c];
- sector_msf.s = cdrom->dfifo[0x0d];
- sector_msf.f = cdrom->dfifo[0x0e];
-
- int correct_msf = (cdrom->seek_mm == sector_msf.m) &&
- (cdrom->seek_ss == sector_msf.s) &&
- (cdrom->seek_ff == sector_msf.f);
-
- // Most probably audio sector:
- // Purposefully constructed audio data could
- // circumvent this detection code, but it will work
- // for most intents and purposes
- if (!correct_msf) {- log_set_quiet(0);
- log_fatal("CdlReadN: Audio read");- log_set_quiet(1);
-
- cdrom->irq_delay = DELAY_1MS * 600;
- cdrom->delayed_command = CDL_ERROR;
- cdrom->state = CD_STATE_ERROR;
- cdrom->error = ERR_SEEK;
- cdrom->error_flags = GETSTAT_SEEKERROR;
-
- return;
- }
-
int double_speed = cdrom->mode & MODE_SPEED;
cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
@@ -461,44 +533,31 @@
} break;
case CD_STATE_SEND_RESP2: {- log_fatal("CdlReadN: CD_STATE_SEND_RESP2");+ log_fatal("CdlReadS: CD_STATE_SEND_RESP2");- msf_t msf;
+ // Returning only non-ADPCM sectors causes desync for some
+ // reason. I'll keep returning all sectors for now
- msf.m = cdrom->seek_mm;
- msf.s = cdrom->seek_ss;
- msf.f = cdrom->seek_ff;
+ if (cdrom->mode & MODE_XA_ADPCM) {+ // printf("ReadS fetching non ADPCM sector...\n");+ cdrom_fetch_video_sector(cdrom);
- msf_from_bcd(&msf);
+ printf("%02u:%02u:%02u - file=%02x channel=%02x sm=%02x ci=%02x\n",+ cdrom->seek_msf.m,
+ cdrom->seek_msf.s,
+ cdrom->seek_msf.f,
+ cdrom->dfifo[0x10],
+ cdrom->dfifo[0x11],
+ cdrom->dfifo[0x12],
+ cdrom->dfifo[0x13]
+ );
+ } else {+ psx_disc_seek(cdrom->disc, cdrom->seek_msf);
+ psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
- psx_disc_seek(cdrom->disc, msf);
- psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
-
- // printf("Sector header: msf=%02x:%02x:%02x, mode=%02x, subheader=%02x,%02x,%02x,%02x\n",- // cdrom->dfifo[0x0c],
- // cdrom->dfifo[0x0d],
- // cdrom->dfifo[0x0e],
- // cdrom->dfifo[0x0f],
- // cdrom->dfifo[0x10],
- // cdrom->dfifo[0x11],
- // cdrom->dfifo[0x12],
- // cdrom->dfifo[0x13]
- // );
-
- if (cdrom->dfifo[0x12] & 0x20) {- log_fatal("Unimplemented XA Form2 Sector");-
- // exit(1);
+ msf_add_f(&cdrom->seek_msf, 1);
}
- cdrom->seek_ff++;
-
- if ((cdrom->seek_ff & 0xF) == 10) { cdrom->seek_ff += 0x10; cdrom->seek_ff &= 0xF0; }- if (cdrom->seek_ff == 0x75) { cdrom->seek_ss++; cdrom->seek_ff = 0; }- if ((cdrom->seek_ss & 0xF) == 10) { cdrom->seek_ss += 0x10; cdrom->seek_ss &= 0xF0; }- if (cdrom->seek_ss == 0x60) { cdrom->seek_mm++; cdrom->seek_ss = 0; }- if ((cdrom->seek_mm & 0xF) == 10) { cdrom->seek_mm += 0x10; cdrom->seek_mm &= 0xF0; }-
int double_speed = cdrom->mode & MODE_SPEED;
cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
@@ -516,7 +575,7 @@
switch (cdrom->state) { case CD_STATE_RECV_CMD: {- cdrom->read_ongoing = 0;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->cdda_playing = 0;
cdrom->irq_delay = DELAY_1MS;
@@ -549,18 +608,17 @@
switch (cdrom->state) { case CD_STATE_RECV_CMD: {- cdrom->read_ongoing = 0;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->cdda_playing = 0;
cdrom->irq_delay = DELAY_1MS;
cdrom->state = CD_STATE_SEND_RESP1;
cdrom->delayed_command = CDL_STOP;
- cdrom->seek_ff = 0;
- cdrom->seek_ss = 0;
- cdrom->seek_mm = 0;
- cdrom->cdda_msf.m = 0;
- cdrom->cdda_msf.s = 0;
- cdrom->cdda_msf.f = 0;
+ cdrom->seek_msf.m = 0;
+ cdrom->seek_msf.s = 0;
+ cdrom->seek_msf.f = 0;
+
+ cdrom->cdda_msf = cdrom->seek_msf;
} break;
case CD_STATE_SEND_RESP1: {@@ -588,7 +646,7 @@
switch (cdrom->state) { case CD_STATE_RECV_CMD: {- cdrom->read_ongoing = 0;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->cdda_playing = 0;
cdrom->xa_playing = 0;
@@ -627,20 +685,20 @@
cdrom->irq_delay = DELAY_1MS;
cdrom->state = CD_STATE_SEND_RESP1;
cdrom->delayed_command = CDL_INIT;
- cdrom->read_ongoing = 0;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->mode = 0;
cdrom->dfifo_index = 0;
cdrom->dfifo_full = 0;
cdrom->pfifo_index = 0;
cdrom->rfifo_index = 0;
- cdrom->seek_mm = 0;
- cdrom->seek_ss = 0;
- cdrom->seek_ff = 0;
+ cdrom->seek_msf.m = 0;
+ cdrom->seek_msf.s = 2;
+ cdrom->seek_msf.f = 0;
} break;
case CD_STATE_SEND_RESP1: {SET_BITS(ifr, IFR_INT, 3);
- RESP_PUSH(cdrom->stat);
+ RESP_PUSH(GETSTAT_MOTOR);
cdrom->irq_delay = DELAY_1MS;
cdrom->state = CD_STATE_SEND_RESP2;
@@ -649,7 +707,7 @@
case CD_STATE_SEND_RESP2: {SET_BITS(ifr, IFR_INT, 2);
- RESP_PUSH(cdrom->stat);
+ RESP_PUSH(GETSTAT_MOTOR);
cdrom->state = CD_STATE_RECV_CMD;
cdrom->delayed_command = CDL_NONE;
@@ -682,8 +740,15 @@
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(cdrom->stat);
- cdrom->delayed_command = CDL_NONE;
- cdrom->state = CD_STATE_RECV_CMD;
+ if (cdrom->ongoing_read_command) {+ // printf("command=%02x\n", cdrom->ongoing_read_command);+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
+ cdrom->irq_delay = DELAY_1MS;
+ } else {+ cdrom->delayed_command = CDL_NONE;
+ cdrom->state = CD_STATE_RECV_CMD;
+ }
} break;
}
}
@@ -718,6 +783,12 @@
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(cdrom->stat);
+ if (cdrom->ongoing_read_command) {+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
+ cdrom->state = CD_STATE_SEND_RESP2;
+ }
+
cdrom->state = CD_STATE_RECV_CMD;
} break;
}
@@ -755,8 +826,14 @@
cdrom->delayed_command = CDL_NONE;
SET_BITS(ifr, IFR_INT, IFR_INT3);
- RESP_PUSH(GETSTAT_MOTOR | GETSTAT_PLAY);
+ RESP_PUSH(GETSTAT_MOTOR);
+ if (cdrom->ongoing_read_command) {+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
+ cdrom->state = CD_STATE_SEND_RESP2;
+ }
+
cdrom->state = CD_STATE_RECV_CMD;
} break;
}
@@ -795,17 +872,24 @@
case CD_STATE_SEND_RESP1: {SET_BITS(ifr, IFR_INT, IFR_INT3);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x01);
- RESP_PUSH(0xff);
+ RESP_PUSH(cdrom->dfifo[0x13]);
+ RESP_PUSH(cdrom->dfifo[0x12]);
+ RESP_PUSH(cdrom->dfifo[0x11]);
+ RESP_PUSH(cdrom->dfifo[0x10]);
+ RESP_PUSH(cdrom->dfifo[0x0f]);
+ RESP_PUSH(cdrom->dfifo[0x0e]);
+ RESP_PUSH(cdrom->dfifo[0x0d]);
+ RESP_PUSH(cdrom->dfifo[0x0c]);
- cdrom->delayed_command = CDL_NONE;
- cdrom->state = CD_STATE_RECV_CMD;
+ // if (cdrom->ongoing_read_command) {+ // // printf("command=%02x\n", cdrom->ongoing_read_command);+ // cdrom->state = CD_STATE_SEND_RESP2;
+ // cdrom->delayed_command = cdrom->ongoing_read_command;
+ // cdrom->irq_delay = DELAY_1MS;
+ // } else {+ cdrom->delayed_command = CDL_NONE;
+ cdrom->state = CD_STATE_RECV_CMD;
+ // }
} break;
}
}
@@ -818,18 +902,59 @@
} break;
case CD_STATE_SEND_RESP1: {+ msf_t absolute = cdrom->xa_playing ? cdrom->xa_msf : cdrom->seek_msf;
+ msf_t relative = absolute;
+ msf_t track_msf = cdrom_get_track_addr(cdrom, absolute);
+
+ relative.m -= track_msf.m;
+ relative.s -= track_msf.s;
+ relative.f -= track_msf.f;
+
+ msf_adjust_sub(&relative);
+
+ // printf("abs=%02u:%02u:%02u tra=%02u:%02u:%02u rel=%02u:%02u:%02u\n",+ // absolute.m,
+ // absolute.s,
+ // absolute.f,
+ // track_msf.m,
+ // track_msf.s,
+ // track_msf.f,
+ // relative.m,
+ // relative.s,
+ // relative.f
+ // );
+
+ msf_to_bcd(&absolute);
+ msf_to_bcd(&relative);
+
+ // printf("getlocp 01 01 %02x:%02x:%02x %02x:%02x:%02x\n",+ // relative.m,
+ // relative.s,
+ // relative.f,
+ // absolute.m,
+ // absolute.s,
+ // absolute.f
+ // );
+
SET_BITS(ifr, IFR_INT, IFR_INT3);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
- RESP_PUSH(0x00);
+ RESP_PUSH(absolute.f);
+ RESP_PUSH(absolute.s);
+ RESP_PUSH(absolute.m);
+ RESP_PUSH(relative.f);
+ RESP_PUSH(relative.s);
+ RESP_PUSH(relative.m);
RESP_PUSH(0x01);
- RESP_PUSH(0xff);
+ RESP_PUSH(0x01);
- cdrom->delayed_command = CDL_NONE;
- cdrom->state = CD_STATE_RECV_CMD;
+ if (cdrom->ongoing_read_command) {+ //// printf("command=%02x\n", cdrom->ongoing_read_command);+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
+ cdrom->irq_delay = DELAY_1MS;
+ } else {+ cdrom->delayed_command = CDL_NONE;
+ cdrom->state = CD_STATE_RECV_CMD;
+ }
} break;
}
}
@@ -877,7 +1002,7 @@
return;
}
- cdrom->irq_delay = DELAY_1MS;
+ cdrom->irq_delay = DELAY_1MS * 2;
cdrom->delayed_command = CDL_GETTN;
cdrom->state = CD_STATE_SEND_RESP1;
} break;
@@ -903,7 +1028,7 @@
switch (cdrom->state) { case CD_STATE_RECV_CMD: { if (cdrom->pfifo_index != 1) {- log_fatal("CdlGetTD: Expected exactly 0 parameters");+ log_fatal("CdlGetTD: Expected exactly 1 parameter");cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_ERROR;
@@ -916,6 +1041,16 @@
cdrom->gettd_track = PFIFO_POP;
+ if (!VALID_BCD(cdrom->gettd_track)) {+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->delayed_command = CDL_ERROR;
+ cdrom->state = CD_STATE_ERROR;
+ cdrom->error = ERR_INVSUBF;
+ cdrom->error_flags = GETSTAT_ERROR;
+
+ return;
+ }
+
int err = psx_disc_get_track_addr(cdrom->disc, NULL, cdrom->gettd_track);
if (err) {@@ -922,7 +1057,7 @@
cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_ERROR;
cdrom->state = CD_STATE_ERROR;
- cdrom->error = ERR_PCOUNT;
+ cdrom->error = ERR_INVSUBF;
cdrom->error_flags = GETSTAT_ERROR;
return;
@@ -978,16 +1113,8 @@
cdrom->state = CD_STATE_SEND_RESP2;
cdrom->delayed_command = CDL_SEEKL;
- msf_t msf;
+ psx_disc_seek(cdrom->disc, cdrom->seek_msf);
- msf.m = cdrom->seek_mm;
- msf.s = cdrom->seek_ss;
- msf.f = cdrom->seek_ff;
-
- msf_from_bcd(&msf);
-
- psx_disc_seek(cdrom->disc, msf);
-
cdrom->seek_pending = 0;
} break;
@@ -1030,16 +1157,8 @@
cdrom->state = CD_STATE_SEND_RESP2;
cdrom->delayed_command = CDL_SEEKP;
- msf_t msf;
+ psx_disc_seek(cdrom->disc, cdrom->seek_msf);
- msf.m = cdrom->seek_mm;
- msf.s = cdrom->seek_ss;
- msf.f = cdrom->seek_ff;
-
- msf_from_bcd(&msf);
-
- psx_disc_seek(cdrom->disc, msf);
-
cdrom->seek_pending = 0;
} break;
@@ -1087,12 +1206,13 @@
case CD_STATE_SEND_RESP1: {cdrom->delayed_command = CDL_NONE;
-
+
+ // 95h,05h,16h,C1h
SET_BITS(ifr, IFR_INT, IFR_INT3);
- RESP_PUSH(0xc0);
- RESP_PUSH(0x19);
- RESP_PUSH(0x09);
- RESP_PUSH(0x94);
+ RESP_PUSH(0xc1);
+ RESP_PUSH(0x16);
+ RESP_PUSH(0x05);
+ RESP_PUSH(0x95);
cdrom->state = CD_STATE_RECV_CMD;
} break;
@@ -1163,7 +1283,7 @@
}
void cdrom_cmd_reads(psx_cdrom_t* cdrom) {cdrom->delayed_command = CDL_NONE;
- cdrom->read_ongoing = 1;
+ cdrom->ongoing_read_command = CDL_READS;
switch (cdrom->state) { case CD_STATE_RECV_CMD: {@@ -1174,27 +1294,19 @@
} break;
case CD_STATE_SEND_RESP1: {+ printf("CdlReadS: CD_STATE_SEND_RESP1\n"); log_fatal("CdlReadS: CD_STATE_SEND_RESP1");SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(GETSTAT_MOTOR);
- msf_t msf;
-
- msf.m = cdrom->seek_mm;
- msf.s = cdrom->seek_ss;
- msf.f = cdrom->seek_ff;
-
- msf_from_bcd(&msf);
-
- cdrom->xa_msf = msf;
-
if (cdrom->mode & MODE_XA_ADPCM) {+ cdrom->xa_msf = cdrom->seek_msf;
cdrom->xa_playing = 1;
SET_BITS(status, STAT_ADPBUSY_MASK, STAT_ADPBUSY_MASK);
- printf("Play XA-ADPCM encoded song at %02u:%02u:%02u, filter=%u, file=%02x, channel=%02x\n",+ printf("Play XA-ADPCM encoded song at %02u:%02u:%02u, filter=%u, file=%02x, channel=%02x (ReadS)\n",cdrom->xa_msf.m,
cdrom->xa_msf.s,
cdrom->xa_msf.f,
@@ -1205,17 +1317,19 @@
int double_speed = cdrom->mode & MODE_SPEED;
- cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
+ cdrom->irq_delay = DELAY_1MS * 2;
cdrom->state = CD_STATE_SEND_RESP2;
cdrom->delayed_command = CDL_READS;
- if (cdrom->spin_delay) {- cdrom->irq_delay += cdrom->spin_delay;
- cdrom->spin_delay = 0;
- }
+ // if (cdrom->spin_delay) {+ // cdrom->irq_delay += cdrom->spin_delay;
+ // cdrom->spin_delay = 0;
+ // }
+
+ return;
}
- int err = psx_disc_seek(cdrom->disc, msf);
+ int err = psx_disc_seek(cdrom->disc, cdrom->seek_msf);
if (err) { log_fatal("CdlReadS: Out of bounds seek");@@ -1244,52 +1358,117 @@
case CD_STATE_SEND_RESP2: { log_fatal("CdlReadS: CD_STATE_SEND_RESP2");- msf_t msf;
+ // Returning only non-ADPCM sectors causes desync for some
+ // reason. I'll keep returning all sectors for now
- msf.m = cdrom->seek_mm;
- msf.s = cdrom->seek_ss;
- msf.f = cdrom->seek_ff;
+ if (cdrom->mode & MODE_XA_ADPCM) {+ // printf("ReadS fetching non ADPCM sector...\n");+ cdrom_fetch_video_sector(cdrom);
- msf_from_bcd(&msf);
+ // printf("%02u:%02u:%02u - file=%02x channel=%02x sm=%02x ci=%02x\n",+ // cdrom->seek_msf.m,
+ // cdrom->seek_msf.s,
+ // cdrom->seek_msf.f,
+ // cdrom->dfifo[0x10],
+ // cdrom->dfifo[0x11],
+ // cdrom->dfifo[0x12],
+ // cdrom->dfifo[0x13]
+ // );
+ } else {+ psx_disc_seek(cdrom->disc, cdrom->seek_msf);
+ psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
- psx_disc_seek(cdrom->disc, msf);
- psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
+ msf_add_f(&cdrom->seek_msf, 1);
+ }
- cdrom->seek_ff++;
-
- if ((cdrom->seek_ff & 0xF) == 10) { cdrom->seek_ff += 0x10; cdrom->seek_ff &= 0xF0; }- if (cdrom->seek_ff == 0x75) { cdrom->seek_ss++; cdrom->seek_ff = 0; }- if ((cdrom->seek_ss & 0xF) == 10) { cdrom->seek_ss += 0x10; cdrom->seek_ss &= 0xF0; }- if (cdrom->seek_ss == 0x60) { cdrom->seek_mm++; cdrom->seek_ss = 0; }- if ((cdrom->seek_mm & 0xF) == 10) { cdrom->seek_mm += 0x10; cdrom->seek_mm &= 0xF0; }-
int double_speed = cdrom->mode & MODE_SPEED;
- cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
+ cdrom->irq_delay = DELAY_1MS * 2;
cdrom->state = CD_STATE_SEND_RESP2;
cdrom->delayed_command = CDL_READS;
cdrom->dfifo_index = 0;
- if (cdrom->mode & MODE_XA_ADPCM) {- int double_speed = cdrom->mode & MODE_SPEED;
+ SET_BITS(ifr, IFR_INT, IFR_INT1);
+ RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
+ } break;
+ }
+}
+void cdrom_cmd_readtoc(psx_cdrom_t* cdrom) {+ switch (cdrom->state) {+ case CD_STATE_RECV_CMD: {+ cdrom->status |= STAT_BUSYSTS_MASK;
+ cdrom->irq_delay = DELAY_1MS * 1000;
+ cdrom->state = CD_STATE_SEND_RESP1;
+ cdrom->delayed_command = CDL_READTOC;
+ } break;
- if (cdrom->dfifo[0x12] & 4) {- cdrom->irq_delay = 10;
- cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
- cdrom->state = CD_STATE_SEND_RESP2;
- cdrom->delayed_command = CDL_READS;
- // cdrom->irq_disable = 1;
+ case CD_STATE_SEND_RESP1: {+ cdrom->status &= ~STAT_BUSYSTS_MASK;
+ SET_BITS(ifr, IFR_INT, 3);
+ RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
- return;
- }
+ cdrom->irq_delay = DELAY_1MS * 1000;
+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = CDL_READTOC;
+ } break;
+
+ case CD_STATE_SEND_RESP2: {+ SET_BITS(ifr, IFR_INT, 2);
+ RESP_PUSH(GETSTAT_MOTOR);
+
+ cdrom->state = CD_STATE_RECV_CMD;
+ cdrom->delayed_command = CDL_NONE;
+ } break;
+ }
+}
+void cdrom_cmd_videocd(psx_cdrom_t* cdrom) {+ switch (cdrom->state) {+ case CD_STATE_RECV_CMD: {+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->state = CD_STATE_SEND_RESP1;
+ cdrom->delayed_command = CDL_VIDEOCD;
+ cdrom->pfifo_index = 0;
+ } break;
+
+ case CD_STATE_SEND_RESP1: {+ printf("VideoCD task %02x\n", cdrom->pfifo[4]);+ SET_BITS(ifr, IFR_INT, 3);
+
+ switch (cdrom->pfifo[4]) {+ case 0: {+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(GETSTAT_MOTOR);
+ } break;
+
+ case 1: {+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x81);
+ RESP_PUSH(GETSTAT_MOTOR);
+ } break;
+
+ case 2: {+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x00);
+ RESP_PUSH(0x05);
+ RESP_PUSH(GETSTAT_MOTOR);
+ } break;
}
- SET_BITS(ifr, IFR_INT, IFR_INT1);
- RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->state = CD_STATE_RECV_CMD;
+ cdrom->delayed_command = CDL_NONE;
} break;
}
}
-void cdrom_cmd_readtoc(psx_cdrom_t* cdrom) { log_fatal("readtoc: Unimplemented"); exit(1); }typedef void (*cdrom_cmd_t)(psx_cdrom_t*);
@@ -1325,7 +1504,7 @@
"CdlUnimplemented",
"CdlUnimplemented",
"CdlReadtoc",
- "CdlUnimplemented"
+ "CdlVideoCD"
};
cdrom_cmd_t g_psx_cdrom_command_table[] = {@@ -1360,6 +1539,7 @@
cdrom_cmd_unimplemented,
cdrom_cmd_unimplemented,
cdrom_cmd_readtoc,
+ cdrom_cmd_videocd,
// Actually an unimplemented command, we use this
// index for CD error handling
@@ -1418,8 +1598,7 @@
}
void cdrom_write_cmd(psx_cdrom_t* cdrom, uint8_t value) {- // log_set_quiet(0);
- // log_fatal("%s(%02x) %u params=[%02x, %02x, %02x, %02x, %02x, %02x]",+ // printf("%s(%02x) %u params=[%02x, %02x, %02x, %02x, %02x, %02x]\n",// g_psx_cdrom_command_names[value],
// value,
// cdrom->pfifo_index,
@@ -1430,7 +1609,6 @@
// cdrom->pfifo[4],
// cdrom->pfifo[5]
// );
- // log_set_quiet(1);
cdrom->command = value;
cdrom->state = CD_STATE_RECV_CMD;
@@ -1577,6 +1755,10 @@
memset(cdrom->xa_left_resample_buf, 0, (XA_STEREO_RESAMPLE_SIZE * 2) * sizeof(int16_t));
memset(cdrom->xa_right_resample_buf, 0, (XA_STEREO_RESAMPLE_SIZE * 2) * sizeof(int16_t));
memset(cdrom->xa_mono_resample_buf, 0, (XA_MONO_RESAMPLE_SIZE * 2) * sizeof(int16_t));
+
+ cdrom->seek_msf.m = 0;
+ cdrom->seek_msf.s = 2;
+ cdrom->seek_msf.f = 0;
}
uint32_t psx_cdrom_read32(psx_cdrom_t* cdrom, uint32_t offset) {@@ -1730,7 +1912,16 @@
void psx_cdrom_open(psx_cdrom_t* cdrom, const char* path) {cdrom->disc = psx_disc_create();
- int ext = cdrom_get_extension(path);
+ int len = strlen(path);
+
+ char* lower = malloc(len + 1);
+
+ for (int i = 0; i < len; i++)
+ lower[i] = tolower(path[i]);
+
+ lower[len] = '\0';
+
+ int ext = cdrom_get_extension(lower);
int error = 0;
switch (ext) {@@ -1739,6 +1930,7 @@
psxd_cue_init_disc(cue, cdrom->disc);
psxd_cue_init(cue);
+
error = psxd_cue_load(cue, path);
if (error)
@@ -1768,6 +1960,8 @@
} break;
}
+ free(lower);
+
if (error) { log_fatal("Error loading file \'%s\'", path);@@ -1963,13 +2157,8 @@
return;
}
- // Convert seek to I
- msf_t msf = cdrom->cdda_msf;
-
- msf_from_bcd(&msf);
-
// Seek to that address and read sector
- if (psx_disc_seek(cdrom->disc, msf))
+ if (psx_disc_seek(cdrom->disc, cdrom->cdda_msf))
cdrom->cdda_playing = 0;
psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
@@ -1977,11 +2166,7 @@
++cdrom->cdda_sectors_played;
// Increment sector
- msf_add_f(&msf, 1);
- msf_to_bcd(&msf);
-
- // Assign to CDDA MSF
- cdrom->cdda_msf = msf;
+ msf_add_f(&cdrom->cdda_msf, 1);
memcpy(buf, cdrom->cdda_buf, size);
--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -58,7 +58,8 @@
#define CDL_RESET 0x1c
#define CDL_GETQ 0x1d
#define CDL_READTOC 0x1e
-#define CDL_ERROR 0x1f
+#define CDL_VIDEOCD 0x1f
+#define CDL_ERROR 0x20
#define STAT_INDEX_MASK 0x3
#define STAT_ADPBUSY_MASK 0x4
@@ -178,7 +179,7 @@
int tray_open;
// Setloc
- uint8_t seek_ss, seek_mm, seek_ff;
+ msf_t seek_msf;
uint32_t seek_offset;
int seek_pending;
@@ -195,7 +196,7 @@
int spin_delay;
uint8_t error;
uint8_t error_flags;
- int read_ongoing;
+ int ongoing_read_command;
int gettd_track;
// CDDA
@@ -318,5 +319,6 @@
void cdrom_cmd_getid(psx_cdrom_t*);
void cdrom_cmd_reads(psx_cdrom_t*);
void cdrom_cmd_readtoc(psx_cdrom_t*);
+void cdrom_cmd_videocd(psx_cdrom_t*);
#endif
\ No newline at end of file
--- a/psx/dev/dma.c
+++ b/psx/dev/dma.c
@@ -165,19 +165,28 @@
if (!CHCR_BUSY(mdec_in))
return;
+ // printf("dma mdec in size=%04x bcnt=%04x step=%u madr=%08x\n",+ // BCR_SIZE(mdec_in),
+ // BCR_BCNT(mdec_in),
+ // CHCR_STEP(mdec_in),
+ // dma->mdec_in.madr
+ // );
+
size_t size = BCR_SIZE(mdec_in) * BCR_BCNT(mdec_in);
+ int step = CHCR_STEP(mdec_in) ? -4 : 4;
+
for (int i = 0; i < size; i++) {uint32_t data = psx_bus_read32(dma->bus, dma->mdec_in.madr);
psx_bus_write32(dma->bus, 0x1f801820, data);
- dma->mdec_in.madr += CHCR_STEP(mdec_in) ? -4 : 4;
+ dma->mdec_in.madr += step;
}
dma->mdec_in_irq_delay = size;
- dma->mdec_in.chcr &= ~(CHCR_BUSY_MASK | CHCR_TRIG_MASK);
+ dma->mdec_in.chcr = 0;
dma->mdec_in.bcr = 0;
}
@@ -185,6 +194,15 @@
if (!CHCR_BUSY(mdec_out))
return;
+ // printf("dma mdec out size=%04x bcnt=%04x step=%u madr=%08x\n",+ // BCR_SIZE(mdec_out),
+ // BCR_BCNT(mdec_out),
+ // CHCR_STEP(mdec_out),
+ // dma->mdec_out.madr
+ // );
+
+ // printf("mdec out transfer\n");+
size_t size = BCR_SIZE(mdec_out) * BCR_BCNT(mdec_out);
for (int i = 0; i < size; i++) {@@ -293,8 +311,7 @@
if (!CHCR_BUSY(cdrom))
return;
- // log_set_quiet(0);
- // log_fatal("CDROM DMA transfer: madr=%08x, dir=%s, sync=%s (%u), step=%s, size=%x",+ // printf("CDROM DMA transfer: madr=%08x, dir=%s, sync=%s (%u), step=%s, size=%x\n",// dma->cdrom.madr,
// CHCR_TDIR(cdrom) ? "to device" : "to RAM",
// g_psx_dma_sync_type_name_table[CHCR_SYNC(cdrom)], CHCR_SYNC(cdrom),
@@ -302,13 +319,12 @@
// BCR_SIZE(cdrom)
// );
- // log_fatal("DICR: force=%u, en=%02x, irqen=%u, flags=%02x",+ // printf("DICR: force=%u, en=%02x, irqen=%u, flags=%02x\n",// (dma->dicr >> 15) & 1,
// (dma->dicr >> 16) & 0x7f,
// (dma->dicr >> 23) & 1,
// (dma->dicr >> 24) & 0x7f
// );
- // log_set_quiet(1);
uint32_t size = BCR_SIZE(cdrom);
--- a/psx/dev/exp1.c
+++ b/psx/dev/exp1.c
@@ -9,7 +9,7 @@
return (psx_exp1_t*)malloc(sizeof(psx_exp1_t));
}
-void psx_exp1_init(psx_exp1_t* exp1, psx_mc1_t* mc1) {+void psx_exp1_init(psx_exp1_t* exp1, psx_mc1_t* mc1, const char* path) {memset(exp1, 0, sizeof(psx_exp1_t));
exp1->io_base = PSX_EXP1_BEGIN;
@@ -19,6 +19,23 @@
exp1->rom = (uint8_t*)malloc(PSX_EXP1_SIZE);
memset(exp1->rom, 0xff, PSX_EXP1_SIZE);
+
+ if (path)
+ psx_exp1_load(exp1, path);
+}
+
+void psx_exp1_load(psx_exp1_t* exp1, const char* path) {+ FILE* file = fopen(path, "rb");
+
+ if (!file) {+ perror("Error opening expansion ROM file \'%s\'");+
+ exit(1);
+ }
+
+ fread(exp1->rom, 1, PSX_EXP1_SIZE, file);
+
+ fclose(file);
}
uint32_t psx_exp1_read32(psx_exp1_t* exp1, uint32_t offset) {--- a/psx/dev/exp1.h
+++ b/psx/dev/exp1.h
@@ -18,7 +18,8 @@
} psx_exp1_t;
psx_exp1_t* psx_exp1_create();
-void psx_exp1_init(psx_exp1_t*, psx_mc1_t*);
+void psx_exp1_init(psx_exp1_t*, psx_mc1_t*, const char*);
+void psx_exp1_load(psx_exp1_t*, const char*);
uint32_t psx_exp1_read32(psx_exp1_t*, uint32_t);
uint16_t psx_exp1_read16(psx_exp1_t*, uint32_t);
uint8_t psx_exp1_read8(psx_exp1_t*, uint32_t);
--- /dev/null
+++ b/psx/dev/exp2.c
@@ -1,0 +1,80 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../log.h"
+#include "exp2.h"
+
+psx_exp2_t* psx_exp2_create() {+ return (psx_exp2_t*)malloc(sizeof(psx_exp2_t));
+}
+
+void psx_exp2_init(psx_exp2_t* exp2, exp2_tty_tx atcons_tx, exp2_tty_tx duart_tx) {+ memset(exp2, 0, sizeof(psx_exp2_t));
+
+ exp2->io_base = PSX_EXP2_BEGIN;
+ exp2->io_size = PSX_EXP2_SIZE;
+ exp2->atcons_tx = atcons_tx;
+ exp2->duart_tx = duart_tx;
+}
+
+void psx_exp2_atcons_put(psx_exp2_t* exp2, char c) {+ exp2->atc_stat |= 0x10;
+ exp2->atc_rx = c;
+}
+
+void psx_exp2_duart_put(psx_exp2_t* exp2, char c) {+ /* To-do */
+}
+
+uint32_t psx_exp2_read32(psx_exp2_t* exp2, uint32_t offset) {+ return 0;
+}
+
+uint16_t psx_exp2_read16(psx_exp2_t* exp2, uint32_t offset) {+ return 0;
+}
+
+uint8_t psx_exp2_read8(psx_exp2_t* exp2, uint32_t offset) {+ switch (offset) {+ case EXP2_DTL_ATC_STAT:
+ return exp2->atc_stat | 8;
+
+ case EXP2_DTL_ATC_DATA:
+ exp2->atc_stat &= 0xef;
+ return exp2->atc_rx;
+ }
+
+ return 0;
+}
+
+void psx_exp2_write32(psx_exp2_t* exp2, uint32_t offset, uint32_t value) {+ log_warn("Unhandled 32-bit EXP2 write at offset %08x (%08x)", offset, value);+}
+
+void psx_exp2_write16(psx_exp2_t* exp2, uint32_t offset, uint16_t value) {+ log_warn("Unhandled 16-bit EXP2 write at offset %08x (%04x)", offset, value);+}
+
+void psx_exp2_write8(psx_exp2_t* exp2, uint32_t offset, uint8_t value) {+ switch (offset) {+ case EXP2_DTL_ATC_DATA:
+ if (exp2->atcons_tx)
+ exp2->atcons_tx(exp2->atcons_udata, value);
+ return;
+ break;
+
+ case EXP2_LED:
+ case EXP2_POST:
+ case EXP2_POST2:
+ // To-do: Do something with this data
+ return;
+ break;
+ }
+
+ log_warn("Unhandled 8-bit EXP2 write at offset %08x (%02x)", offset, value);+}
+
+void psx_exp2_destroy(psx_exp2_t* exp2) {+ free(exp2);
+}
\ No newline at end of file
--- /dev/null
+++ b/psx/dev/exp2.h
@@ -1,0 +1,48 @@
+#ifndef EXP2_H
+#define EXP2_H
+
+#include <stdint.h>
+
+#define PSX_EXP2_BEGIN 0x1f802000
+#define PSX_EXP2_SIZE 0x1fe000
+#define PSX_EXP2_END 0x1f9fffff
+
+#define EXP2_DTL_ATC_STAT 0x00 // 1f802000
+#define EXP2_DTL_ATC_DATA 0x02 // 1f802002
+#define EXP2_DTL_HDATA 0x04 // 1f802004
+#define EXP2_DTL_SEC_IRQ10 0x30 // 1f802030
+#define EXP2_DTL_IRQ_CTRL 0x32 // 1f802032
+#define EXP2_DTL_BOOT_DIP 0x40 // 1f802040
+#define EXP2_POST 0x41 // 1f802041
+#define EXP2_LED 0x42 // 1f802042
+#define EXP2_POST2 0x70 // 1f802070
+
+typedef void (*exp2_tty_tx)(void*, uint8_t);
+
+typedef struct {+ uint32_t bus_delay;
+ uint32_t io_base, io_size;
+
+ void* duart_udata;
+ void* atcons_udata;
+
+ exp2_tty_tx duart_tx;
+ exp2_tty_tx atcons_tx;
+
+ uint8_t atc_stat;
+ uint8_t atc_rx;
+} psx_exp2_t;
+
+psx_exp2_t* psx_exp2_create();
+void psx_exp2_init(psx_exp2_t*, exp2_tty_tx atcons_tx, exp2_tty_tx duart_tx);
+void psx_exp2_atcons_put(psx_exp2_t*, char);
+void psx_exp2_duart_put(psx_exp2_t*, char);
+uint32_t psx_exp2_read32(psx_exp2_t*, uint32_t);
+uint16_t psx_exp2_read16(psx_exp2_t*, uint32_t);
+uint8_t psx_exp2_read8(psx_exp2_t*, uint32_t);
+void psx_exp2_write32(psx_exp2_t*, uint32_t, uint32_t);
+void psx_exp2_write16(psx_exp2_t*, uint32_t, uint16_t);
+void psx_exp2_write8(psx_exp2_t*, uint32_t, uint8_t);
+void psx_exp2_destroy(psx_exp2_t*);
+
+#endif
\ No newline at end of file
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -1683,6 +1683,8 @@
void gpu_hblank_event(psx_gpu_t* gpu) {gpu->line++;
+ psx_ic_irq(gpu->ic, IC_TIMER2);
+
if (gpu->line < GPU_SCANS_PER_VDRAW_NTSC) { if (gpu->line & 1) {gpu->gpustat |= 1 << 31;
@@ -1701,9 +1703,9 @@
} else if (gpu->line == GPU_SCANS_PER_FRAME_NTSC) {if (gpu->event_cb_table[GPU_EVENT_VBLANK_END])
gpu->event_cb_table[GPU_EVENT_VBLANK_END](gpu);
-
- // psx_ic_irq(gpu->ic, IC_SPU);
+ psx_ic_irq(gpu->ic, IC_SPU);
+
gpu->line = 0;
}
}
@@ -1726,6 +1728,9 @@
} else if (prev_hblank && !curr_hblank) {if (gpu->event_cb_table[GPU_EVENT_HBLANK_END])
gpu->event_cb_table[GPU_EVENT_HBLANK_END](gpu);
+
+ //psx_ic_irq(gpu->ic, IC_SPU);
+ // psx_ic_irq(gpu->ic, IC_SPU);
gpu->cycles -= (float)GPU_CYCLES_PER_SCANL_NTSC;
}
--- a/psx/dev/mdec.c
+++ b/psx/dev/mdec.c
@@ -282,6 +282,13 @@
uint32_t psx_mdec_read32(psx_mdec_t* mdec, uint32_t offset) { switch (offset) { case 0: {+ // printf("mdec data read\n");+ // mdec->output_empty = 1;
+ // mdec->output_index = 0;
+ // mdec->output_request = 0;
+
+ // return 0xaaaaaaaa;
+
if (mdec->output_words_remaining) {--mdec->output_words_remaining;
@@ -291,6 +298,7 @@
return ((uint32_t*)mdec->output)[mdec->output_index++];
} else {+ // printf("no read words remaining\n");mdec->output_empty = 0;
mdec->output_index = 0;
mdec->output_request = 0;
@@ -299,6 +307,7 @@
}
} break;
case 4: {+ //printf("mdec status read\n");uint32_t status = 0;
status |= mdec->words_remaining;
@@ -334,6 +343,7 @@
void psx_mdec_write32(psx_mdec_t* mdec, uint32_t offset, uint32_t value) { switch (offset) { case 0: {+ //printf("mdec data write\n"); if (mdec->words_remaining) {mdec->input[mdec->input_index++] = value;
@@ -340,6 +350,7 @@
--mdec->words_remaining;
if (!mdec->words_remaining) {+ //printf("no words remaining\n");mdec->output_empty = 0;
mdec->input_full = 1;
mdec->input_request = 0;
@@ -367,6 +378,7 @@
//log_set_quiet(0);
switch (mdec->cmd >> 29) { case MDEC_CMD_NOP: {+ //printf("mdec nop\n");mdec->busy = 0;
mdec->words_remaining = 0;
@@ -374,15 +386,17 @@
} break;
case MDEC_CMD_DECODE: {+ //printf("mdec decode\n");mdec->words_remaining = mdec->cmd & 0xffff;
- printf("MDEC %08x: decode macroblock %04x\n",- mdec->cmd,
- mdec->words_remaining
- );
+ // printf("MDEC %08x: decode macroblock %04x\n",+ // mdec->cmd,
+ // mdec->words_remaining
+ // );
} break;
case MDEC_CMD_SET_QT: {+ //printf("mdec setqt\n");mdec->recv_color = mdec->cmd & 1;
mdec->words_remaining = mdec->recv_color ? 32 : 16;
@@ -393,6 +407,7 @@
} break;
case MDEC_CMD_SET_ST: {+ //printf("mdec setst\n");mdec->words_remaining = 32;
log_fatal("MDEC %08x: set scale table %04x",@@ -404,7 +419,7 @@
// log_set_quiet(1);
if (mdec->words_remaining) {- mdec->input_request = mdec->enable_dma0;
+ mdec->input_request = 1;
mdec->input_size = mdec->words_remaining * sizeof(uint32_t);
mdec->input_full = 0;
mdec->input_index = 0;
@@ -413,6 +428,7 @@
} break;
case 4: {+ //printf("mdec status write\n");mdec->enable_dma0 = (value & 0x40000000) != 0;
mdec->enable_dma1 = (value & 0x20000000) != 0;
--- a/psx/dev/old/cdrom.c
+++ b/psx/dev/old/cdrom.c
@@ -93,9 +93,9 @@
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(GETSTAT_MOTOR | (cdrom->disc ? 0 : GETSTAT_TRAYOPEN));
- if (cdrom->read_ongoing) {+ if (cdrom->ongoing_read_command) {cdrom->state = CD_STATE_SEND_RESP2;
- cdrom->delayed_command = CDL_READN;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
cdrom->irq_delay = DELAY_1MS;
} else {cdrom->delayed_command = CDL_NONE;
@@ -121,13 +121,13 @@
return;
}
- if (!cdrom->read_ongoing) {+ if (!cdrom->ongoing_read_command) {cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_SETLOC;
cdrom->state = CD_STATE_SEND_RESP1;
} else {cdrom->irq_delay = DELAY_1MS;
- cdrom->delayed_command = CDL_READN;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
cdrom->state = CD_STATE_SEND_RESP2;
}
@@ -174,7 +174,7 @@
int m = PFIFO_POP;
if (!(VALID_BCD(m) && VALID_BCD(s) && VALID_BCD(f) && (f < 0x75))) {- cdrom->read_ongoing = false;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_ERROR;
cdrom->state = CD_STATE_ERROR;
@@ -257,7 +257,7 @@
}
void cdrom_cmd_readn(psx_cdrom_t* cdrom) {cdrom->delayed_command = CDL_NONE;
- cdrom->read_ongoing = 1;
+ cdrom->ongoing_read_command = 1;
switch (cdrom->state) { case CD_STATE_RECV_CMD: {@@ -396,7 +396,7 @@
switch (cdrom->state) { case CD_STATE_RECV_CMD: {- cdrom->read_ongoing = 0;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->cdda_playing = 0;
cdrom->irq_delay = DELAY_1MS;
@@ -429,7 +429,7 @@
switch (cdrom->state) { case CD_STATE_RECV_CMD: {- cdrom->read_ongoing = 0;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->cdda_playing = 0;
cdrom->irq_delay = DELAY_1MS;
@@ -468,7 +468,7 @@
switch (cdrom->state) { case CD_STATE_RECV_CMD: {- cdrom->read_ongoing = 0;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->cdda_playing = 0;
cdrom->irq_delay = DELAY_1MS;
@@ -504,7 +504,7 @@
cdrom->irq_delay = DELAY_1MS;
cdrom->state = CD_STATE_SEND_RESP1;
cdrom->delayed_command = CDL_INIT;
- cdrom->read_ongoing = 0;
+ cdrom->ongoing_read_command = CDL_NONE;
cdrom->mode = 0;
cdrom->dfifo_index = 0;
cdrom->dfifo_full = 0;
@@ -965,7 +965,7 @@
}
void cdrom_cmd_reads(psx_cdrom_t* cdrom) {cdrom->delayed_command = CDL_NONE;
- cdrom->read_ongoing = 1;
+ cdrom->ongoing_read_command = 1;
switch (cdrom->state) { case CD_STATE_RECV_CMD: {--- a/psx/dev/timer.c
+++ b/psx/dev/timer.c
@@ -26,6 +26,32 @@
#define T2_PAUSED timer->timer[2].paused
#define T2_IRQ_FIRED timer->timer[2].irq_fired
+// bool should_I_pause_the_timer(psx_timer_t* timer) {+// if ((timer->mode & 1) == 0) return false;
+// switch ((timer->mode >> 1) & 3) {+// case 0: return gpu.isXblank();
+// case 1: return false;
+// case 2: return !gpu.isXblank();
+// case 3: return gpu.gotXblankOnce();
+// }
+// }
+
+// bool did_timer_reach_target(Timer timer) {+// if ((timer.mode & 8) == 1) return timer.value >= timer.target;
+// return timer.value >= 0xffff;
+// }
+
+// bool should_I_reset_the_timer(Timer timer) {+// if (did_timer_reach_target(timer)) return true;
+// if ((timer.mode & 1) == 0) return false;
+// switch ((timer.mode >> 1) & 3) {+// case 1:
+// case 2:
+// return gpu.isXBlank();
+// }
+// return false;
+// }
+
const char* g_psx_timer_reg_names[] = {"counter", 0, 0, 0,
"mode", 0, 0, 0,
@@ -45,12 +71,16 @@
timer->ic = ic;
}
+int t1_counter = 0;
+
uint32_t psx_timer_read32(psx_timer_t* timer, uint32_t offset) {int index = offset >> 4;
int reg = offset & 0xf;
switch (reg) {- case 0: return timer->timer[index].counter;
+ case 0: {+ return timer->timer[index].counter;
+ } break;
case 4: {timer->timer[index].mode &= 0xffffe7ff;
--- a/psx/disc/cue.c
+++ b/psx/disc/cue.c
@@ -444,6 +444,9 @@
track = BTOI(track);
+ if (track > cue->num_tracks)
+ return DISC_ERR_TRACK_OUT_OF_BOUNDS;
+
if (!msf)
return 0;
@@ -450,15 +453,14 @@
if (!track) {msf->m = cue->end.m;
msf->s = cue->end.s;
+ msf->f = 0;
return 0;
}
- if (track > cue->num_tracks)
- return DISC_ERR_TRACK_OUT_OF_BOUNDS;
-
msf->m = cue->track[track - 1]->disc_offset.m;
msf->s = cue->track[track - 1]->disc_offset.s;
+ msf->f = 0;
return 0;
}
--- a/psx/msf.c
+++ b/psx/msf.c
@@ -31,6 +31,24 @@
}
}
+void msf_adjust_sub(msf_t* msf) {+ if ((int)msf->f < 0) {+ int f = ((int)msf->f) * -1;
+ int s = (f / 60) + 1;
+
+ msf->s -= s;
+ msf->f += CD_SECTORS_PS * f;
+ }
+
+ if ((int)msf->s < 0) {+ int s = ((int)msf->s) * -1;
+ int m = (s / 60) + 1;
+
+ msf->m -= m;
+ msf->s += 60 * m;
+ }
+}
+
void msf_to_bcd(msf_t* msf) {msf->m = ITOB(msf->m);
msf->s = ITOB(msf->s);
--- a/psx/msf.h
+++ b/psx/msf.h
@@ -89,6 +89,7 @@
void msf_copy(msf_t*, msf_t);
void msf_adjust(msf_t*);
+void msf_adjust_sub(msf_t*);
void msf_to_bcd(msf_t*);
void msf_from_bcd(msf_t*);
uint32_t msf_to_address(msf_t);
--- a/psx/psx.c
+++ b/psx/psx.c
@@ -108,7 +108,11 @@
return aspect;
}
-void psx_init(psx_t* psx, const char* bios_path) {+void atcons_tx(void* udata, char c) {+ putchar(c);
+}
+
+void psx_init(psx_t* psx, const char* bios_path, const char* exp_path) {memset(psx, 0, sizeof(psx_t));
psx->bios = psx_bios_create();
@@ -115,6 +119,7 @@
psx->ram = psx_ram_create();
psx->dma = psx_dma_create();
psx->exp1 = psx_exp1_create();
+ psx->exp2 = psx_exp2_create();
psx->mc1 = psx_mc1_create();
psx->mc2 = psx_mc2_create();
psx->mc3 = psx_mc3_create();
@@ -135,6 +140,7 @@
psx_bus_init_ram(psx->bus, psx->ram);
psx_bus_init_dma(psx->bus, psx->dma);
psx_bus_init_exp1(psx->bus, psx->exp1);
+ psx_bus_init_exp2(psx->bus, psx->exp2);
psx_bus_init_mc1(psx->bus, psx->mc1);
psx_bus_init_mc2(psx->bus, psx->mc2);
psx_bus_init_mc3(psx->bus, psx->mc3);
@@ -155,7 +161,8 @@
psx_mc3_init(psx->mc3);
psx_ram_init(psx->ram, psx->mc2);
psx_dma_init(psx->dma, psx->bus, psx->ic);
- psx_exp1_init(psx->exp1, psx->mc1);
+ psx_exp1_init(psx->exp1, psx->mc1, exp_path);
+ psx_exp2_init(psx->exp2, atcons_tx, NULL);
psx_ic_init(psx->ic, psx->cpu);
psx_scratchpad_init(psx->scratchpad);
psx_gpu_init(psx->gpu, psx->ic);
@@ -167,6 +174,10 @@
psx_cpu_init(psx->cpu, psx->bus);
}
+void psx_load_expansion(psx_t* psx, const char* path) {+ psx_exp1_init(psx->exp1, psx->mc1, path);
+}
+
void psx_hard_reset(psx_t* psx) { log_fatal("Hard reset not yet implemented");@@ -229,6 +240,10 @@
psx_exp1_t* psx_get_exp1(psx_t* psx) {return psx->exp1;
+}
+
+psx_exp2_t* psx_get_exp2(psx_t* psx) {+ return psx->exp2;
}
psx_mc1_t* psx_get_mc1(psx_t* psx) {--- a/psx/psx.h
+++ b/psx/psx.h
@@ -12,6 +12,7 @@
psx_ram_t* ram;
psx_dma_t* dma;
psx_exp1_t* exp1;
+ psx_exp2_t* exp2;
psx_mc1_t* mc1;
psx_mc2_t* mc2;
psx_mc3_t* mc3;
@@ -28,7 +29,8 @@
} psx_t;
psx_t* psx_create();
-void psx_init(psx_t*, const char*);
+void psx_init(psx_t*, const char*, const char*);
+void psx_load_expansion(psx_t*, const char*);
void psx_load_bios(psx_t*, const char*);
void psx_hard_reset(psx_t*);
void psx_soft_reset(psx_t*);
@@ -51,6 +53,7 @@
psx_ram_t* psx_get_ram(psx_t*);
psx_dma_t* psx_get_dma(psx_t*);
psx_exp1_t* psx_get_exp1(psx_t*);
+psx_exp2_t* psx_get_exp2(psx_t*);
psx_mc1_t* psx_get_mc1(psx_t*);
psx_mc2_t* psx_get_mc2(psx_t*);
psx_mc3_t* psx_get_mc3(psx_t*);
--- /dev/null
+++ b/working.txt
@@ -1,0 +1,11 @@
+Atari Anniversary Edition Redux (USA)
+Harmful Park (Japan)
+Kyuiin (Japan)
+NASCAR 98 Collector''s Edition (USA)
+Panzer Bandit (Japan)
+Puzzle Bobble 4 (Japan)
+World Soccer Jikkyou Winning Eleven 3 - World Cup France '98 (Japan) (Taikenban)
+Worms (USA)
+San Francisco Rush - Extreme Racing (USA)
+Samurai Shodown III - Blades of Blood (USA)
+Time Crisis - Project Titan (USA)
\ No newline at end of file
--
⑨