diff --git a/build-deps.ps1 b/build-deps.ps1 index 81d9e44..59753e6 100644 --- a/build-deps.ps1 +++ b/build-deps.ps1 @@ -5,4 +5,6 @@ if (Test-Path "SDL2-2.30.3") { $SDL2_URL = "https://github.com/libsdl-org/SDL/releases/download/release-2.30.3/SDL2-devel-2.30.3-mingw.zip" Invoke-WebRequest -URI $SDL2_URL -OutFile "sdl2.zip" -Expand-Archive "sdl2.zip" -DestinationPath "." -Force \ No newline at end of file +Expand-Archive "sdl2.zip" -DestinationPath "." -Force + +Remove-Item "sdl2.zip" \ No newline at end of file diff --git a/psx/cpu.c b/psx/cpu.c index ee626af..b6d544f 100644 --- a/psx/cpu.c +++ b/psx/cpu.c @@ -1477,15 +1477,23 @@ int32_t gte_clamp_mac(psx_cpu_t* cpu, int i, int64_t value) { if (i == 3) cpu->s_mac3 = value; - if (value < -0x80000000000) { + if (value < -0x80000000000ll) { R_FLAG |= 0x8000000 >> (i - 1); - } else if (value > 0x7ffffffffff) { + } else if (value > 0x7ffffffffffll) { R_FLAG |= 0x40000000 >> (i - 1); } return (int32_t)(((value << 20) >> 20) >> cpu->gte_sf); } +void gte_check_mac(psx_cpu_t* cpu, int i, int64_t value) { + if (value < -0x80000000000ll) { + R_FLAG |= 0x8000000 >> (i - 1); + } else if (value > 0x7ffffffffffll) { + R_FLAG |= 0x40000000 >> (i - 1); + } +} + int32_t gte_clamp_ir0(psx_cpu_t* cpu, int32_t value) { if (value < 0) { R_FLAG |= 0x1000; @@ -1841,9 +1849,21 @@ void psx_gte_i_invalid(psx_cpu_t* cpu) { R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm); \ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \ R_IR3 = gte_clamp_ir(cpu, 3, R_MAC3, cpu->gte_lm); \ - R_MAC1 = gte_clamp_mac(cpu, 1, (I64(R_RBK) << 12) + (I64(R_LR1) * I64(R_IR1)) + (I64(R_LR2) * I64(R_IR2)) + (I64(R_LR3) * I64(R_IR3))); \ - R_MAC2 = gte_clamp_mac(cpu, 2, (I64(R_GBK) << 12) + (I64(R_LG1) * I64(R_IR1)) + (I64(R_LG2) * I64(R_IR2)) + (I64(R_LG3) * I64(R_IR3))); \ - R_MAC3 = gte_clamp_mac(cpu, 3, (I64(R_BBK) << 12) + (I64(R_LB1) * I64(R_IR1)) + (I64(R_LB2) * I64(R_IR2)) + (I64(R_LB3) * I64(R_IR3))); \ + gte_check_mac(cpu, 1, ((I64(R_RBK) << 12) + (I64(R_LR1) * I64(R_IR1)))); \ + gte_check_mac(cpu, 2, ((I64(R_GBK) << 12) + (I64(R_LG1) * I64(R_IR1)))); \ + gte_check_mac(cpu, 3, ((I64(R_BBK) << 12) + (I64(R_LB1) * I64(R_IR1)))); \ + gte_check_mac(cpu, 1, I64(R_LR2) * I64(R_IR2)); \ + gte_check_mac(cpu, 2, I64(R_LG2) * I64(R_IR2)); \ + gte_check_mac(cpu, 3, I64(R_LB2) * I64(R_IR2)); \ + gte_check_mac(cpu, 1, I64(R_LR3) * I64(R_IR3)); \ + gte_check_mac(cpu, 2, I64(R_LG3) * I64(R_IR3)); \ + gte_check_mac(cpu, 3, I64(R_LB3) * I64(R_IR3)); \ + R_MAC1 = gte_clamp_mac(cpu, 1, ((I64(R_RBK) << 12) + (I64(R_LR1) * I64(R_IR1))) + (I64(R_LR2) * I64(R_IR2)) + (I64(R_LR3) * I64(R_IR3))); \ + R_MAC2 = gte_clamp_mac(cpu, 2, ((I64(R_GBK) << 12) + (I64(R_LG1) * I64(R_IR1))) + (I64(R_LG2) * I64(R_IR2)) + (I64(R_LG3) * I64(R_IR3))); \ + R_MAC3 = gte_clamp_mac(cpu, 3, ((I64(R_BBK) << 12) + (I64(R_LB1) * I64(R_IR1))) + (I64(R_LB2) * I64(R_IR2)) + (I64(R_LB3) * I64(R_IR3))); \ + /* R_MAC1 = gte_clamp_mac(cpu, 1, () + () + ()); */ \ + /* R_MAC2 = gte_clamp_mac(cpu, 2, () + () + ()); */ \ + /* R_MAC3 = gte_clamp_mac(cpu, 3, () + () + ()); */ \ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm); \ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm); \ R_IR3 = gte_clamp_ir(cpu, 3, R_MAC3, cpu->gte_lm); \ diff --git a/psx/dev/cdrom.c b/psx/dev/cdrom.c index 2d43dd7..1fb9a6f 100644 --- a/psx/dev/cdrom.c +++ b/psx/dev/cdrom.c @@ -253,7 +253,7 @@ void cdrom_cmd_getstat(psx_cdrom_t* cdrom) { return; } - cdrom->irq_delay = DELAY_1MS; + cdrom->irq_delay = DELAY_1MS * 2; cdrom->state = CD_STATE_SEND_RESP1; cdrom->delayed_command = CDL_GETSTAT; } break; @@ -262,7 +262,7 @@ void cdrom_cmd_getstat(psx_cdrom_t* cdrom) { SET_BITS(ifr, IFR_INT, IFR_INT3); RESP_PUSH( GETSTAT_MOTOR | - ((cdrom->cdda_playing || cdrom->xa_playing) ? GETSTAT_PLAY : 0) | + (cdrom->cdda_playing ? GETSTAT_PLAY : 0) | (cdrom->ongoing_read_command ? GETSTAT_READ : 0) | (cdrom->disc ? 0 : GETSTAT_TRAYOPEN) ); @@ -271,7 +271,7 @@ void cdrom_cmd_getstat(psx_cdrom_t* cdrom) { // printf("getstat 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; + cdrom->irq_delay = DELAY_1MS * 2; } else { cdrom->delayed_command = CDL_NONE; cdrom->state = CD_STATE_RECV_CMD; @@ -379,15 +379,15 @@ void cdrom_cmd_play(psx_cdrom_t* cdrom) { case CD_STATE_RECV_CMD: { int track = 0; - if (cdrom->cdda_playing) { - cdrom->pfifo_index = 0; + // if (cdrom->cdda_playing) { + // cdrom->pfifo_index = 0; - cdrom->irq_delay = DELAY_1MS; - cdrom->state = CD_STATE_SEND_RESP1; - cdrom->delayed_command = CDL_PLAY; + // cdrom->irq_delay = DELAY_1MS; + // cdrom->state = CD_STATE_SEND_RESP1; + // cdrom->delayed_command = CDL_PLAY; - return; - } + // return; + // } // Optional track number parameter if (cdrom->pfifo_index) @@ -461,6 +461,7 @@ void cdrom_cmd_readn(psx_cdrom_t* cdrom) { if (cdrom->mode & MODE_XA_ADPCM) { cdrom->xa_msf = cdrom->seek_msf; + cdrom->xa_current_msf = cdrom->xa_msf; cdrom->xa_playing = 1; cdrom->xa_remaining_samples = 0; @@ -883,7 +884,7 @@ void cdrom_cmd_getparam(psx_cdrom_t* cdrom) { void cdrom_cmd_getlocl(psx_cdrom_t* cdrom) { switch (cdrom->state) { case CD_STATE_RECV_CMD: { - cdrom->irq_delay = DELAY_1MS; + cdrom->irq_delay = DELAY_1MS * 4; cdrom->delayed_command = CDL_GETLOCL; cdrom->state = CD_STATE_SEND_RESP1; } break; @@ -903,7 +904,7 @@ void cdrom_cmd_getlocl(psx_cdrom_t* cdrom) { // 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; + cdrom->irq_delay = DELAY_1MS * 4; } else { cdrom->delayed_command = CDL_NONE; cdrom->state = CD_STATE_RECV_CMD; @@ -914,7 +915,7 @@ void cdrom_cmd_getlocl(psx_cdrom_t* cdrom) { void cdrom_cmd_getlocp(psx_cdrom_t* cdrom) { switch (cdrom->state) { case CD_STATE_RECV_CMD: { - cdrom->irq_delay = DELAY_1MS; + cdrom->irq_delay = DELAY_1MS * 8; cdrom->delayed_command = CDL_GETLOCP; cdrom->state = CD_STATE_SEND_RESP1; } break; @@ -968,7 +969,7 @@ void cdrom_cmd_getlocp(psx_cdrom_t* cdrom) { printf("getlocp 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; + cdrom->irq_delay = DELAY_1MS * 8; } else { cdrom->delayed_command = CDL_NONE; cdrom->state = CD_STATE_RECV_CMD; @@ -1234,10 +1235,10 @@ void cdrom_cmd_test(psx_cdrom_t* cdrom) { // 95h,05h,16h,C1h SET_BITS(ifr, IFR_INT, IFR_INT3); - RESP_PUSH(0xc1); - RESP_PUSH(0x16); - RESP_PUSH(0x05); - RESP_PUSH(0x95); + RESP_PUSH(0xc0); + RESP_PUSH(0x19); + RESP_PUSH(0x09); + RESP_PUSH(0x94); cdrom->state = CD_STATE_RECV_CMD; } break; @@ -1327,6 +1328,7 @@ void cdrom_cmd_reads(psx_cdrom_t* cdrom) { if (cdrom->mode & MODE_XA_ADPCM) { cdrom->xa_msf = cdrom->seek_msf; + cdrom->xa_current_msf = cdrom->xa_msf; cdrom->xa_playing = 1; cdrom->xa_remaining_samples = 0; @@ -2086,8 +2088,6 @@ void cdrom_decode_xa_sector(psx_cdrom_t* cdrom, void* buf) { int16_t left[28]; int16_t right[28]; - int16_t left_h[2] = { 0, 0 }; - int16_t right_h[2] = { 0, 0 }; int16_t* left_ptr = cdrom->xa_left_buf; int16_t* right_ptr = cdrom->xa_right_buf; @@ -2096,20 +2096,20 @@ void cdrom_decode_xa_sector(psx_cdrom_t* cdrom, void* buf) { for (int i = 0; i < 18; i++) { for (int blk = 0; blk < 4; blk++) { if (cdrom->xa_sector_buf[0x13] & 1) { - cdrom_decode_xa_block(cdrom, src, blk, 0, left, left_h); - cdrom_decode_xa_block(cdrom, src, blk, 1, right, right_h); + cdrom_decode_xa_block(cdrom, src, blk, 0, left, cdrom->xa_left_h); + cdrom_decode_xa_block(cdrom, src, blk, 1, right, cdrom->xa_right_h); for (int i = 0; i < 28; i++) { *left_ptr++ = left[i]; *right_ptr++ = right[i]; } } else { - cdrom_decode_xa_block(cdrom, src, blk, 0, left, left_h); + cdrom_decode_xa_block(cdrom, src, blk, 0, left, cdrom->xa_left_h); for (int i = 0; i < 28; i++) *mono_ptr++ = left[i]; - cdrom_decode_xa_block(cdrom, src, blk, 1, left, left_h); + cdrom_decode_xa_block(cdrom, src, blk, 1, left, cdrom->xa_left_h); for (int i = 0; i < 28; i++) *mono_ptr++ = left[i]; @@ -2124,6 +2124,7 @@ void cdrom_fetch_xa_sector(psx_cdrom_t* cdrom) { while (true) { if (psx_disc_seek(cdrom->disc, cdrom->xa_msf)) { cdrom->xa_playing = 0; + cdrom->xa_remaining_samples = 0; return; } @@ -2132,12 +2133,12 @@ void cdrom_fetch_xa_sector(psx_cdrom_t* cdrom) { msf_add_f(&cdrom->xa_msf, 1); - // Check for EOR, EOF bits - if (cdrom->xa_sector_buf[0x12] & 0x80) + // Check for EOR bit + if (cdrom->xa_sector_buf[0x12] & 1) return; - // Check RT and Audio bit - if ((cdrom->xa_sector_buf[0x12] & 4) != 4) + // Check Audio bit + if (!(cdrom->xa_sector_buf[0x12] & 4)) continue; // If we get here it means this is a real-time audio sector. @@ -2185,15 +2186,19 @@ void psx_cdrom_get_cdda_samples(psx_cdrom_t* cdrom, void* buf, int size, psx_spu if (!cdrom->xa_remaining_samples) { cdrom_fetch_xa_sector(cdrom); - if (cdrom->xa_sector_buf[0x12] & 0x80) { + if (cdrom->xa_sector_buf[0x12] & 0x01) { SET_BITS(status, STAT_ADPBUSY_MASK, 0); + printf("Pausing XA-ADPCM playback\n"); + cdrom->xa_playing = 0; cdrom->xa_remaining_samples = 0; return; } + msf_add_f(&cdrom->xa_current_msf, 1); + stereo = (cdrom->xa_sector_buf[0x13] & 1) == 1; cdrom_decode_xa_sector(cdrom, buf); diff --git a/psx/dev/cdrom.h b/psx/dev/cdrom.h index 6f12213..2340912 100644 --- a/psx/dev/cdrom.h +++ b/psx/dev/cdrom.h @@ -11,10 +11,10 @@ #include "../msf.h" #include "spu.h" -// #define DELAY_1MS (0xc4e1) +#define DELAY_1MS (0xc4e1) // #define READ_SINGLE_DELAY (0x6e1cd) // #define READ_DOUBLE_DELAY (0x36cd2) -#define DELAY_1MS (PSX_CPU_CPS / 1000) +// #define DELAY_1MS (PSX_CPU_CPS / 1000) #define READ_SINGLE_DELAY (PSX_CPU_CPS / 75) #define READ_DOUBLE_DELAY (PSX_CPU_CPS / (2 * 75)) @@ -210,11 +210,14 @@ typedef struct { // XA-ADPCM uint8_t* xa_sector_buf; msf_t xa_msf; + msf_t xa_current_msf; int xa_playing; int xa_mute; uint8_t xa_file; uint8_t xa_channel; uint8_t xa_coding; + int16_t xa_left_h[2]; + int16_t xa_right_h[2]; int16_t* xa_left_buf; int16_t* xa_right_buf; int16_t* xa_mono_buf; diff --git a/psx/dev/dma.c b/psx/dev/dma.c index 3f0a4ed..6723fe4 100644 --- a/psx/dev/dma.c +++ b/psx/dev/dma.c @@ -345,14 +345,10 @@ void psx_dma_do_cdrom(psx_dma_t* dma) { uint32_t size = BCR_SIZE(cdrom); - if (!size) { + if (!size) printf("0 sized CDROM DMA\n"); - return; - exit(1); - } - - dma->cdrom_irq_delay = size * 24; + dma->cdrom_irq_delay = 1; if (!CHCR_TDIR(cdrom)) { for (int i = 0; i < size; i++) { diff --git a/psx/dev/gpu.c b/psx/dev/gpu.c index f954400..7d86d0b 100644 --- a/psx/dev/gpu.c +++ b/psx/dev/gpu.c @@ -825,6 +825,8 @@ void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vert } } +#define I32(v, b) (((int32_t)((v) << (31-b))) >> (31-b)) + void gpu_rect(psx_gpu_t* gpu) { switch (gpu->state) { case GPU_STATE_RECV_CMD: { @@ -1516,8 +1518,8 @@ void gpu_cmd_02(psx_gpu_t* gpu) { // gpu->ysiz // ); - for (uint32_t y = gpu->v0.y; y < (gpu->v0.y + gpu->ysiz); y++) { - for (uint32_t x = gpu->v0.x; x < (gpu->v0.x + gpu->xsiz); x++) { + for (int y = gpu->v0.y; y < (gpu->v0.y + gpu->ysiz); y++) { + for (int x = gpu->v0.x; x < (gpu->v0.x + gpu->xsiz); x++) { // This shouldn't be needed int bc = (x >= gpu->draw_x1) && (x <= gpu->draw_x2) && (y >= gpu->draw_y1) && (y <= gpu->draw_y2); @@ -1645,8 +1647,8 @@ void psx_gpu_update_cmd(psx_gpu_t* gpu) { gpu->draw_y2 = (gpu->buf[0] >> 10) & 0x1ff; } break; case 0xe5: { - gpu->off_x = (gpu->buf[0] >> 0 ) & 0x7ff; - gpu->off_y = (gpu->buf[0] >> 11) & 0x7ff; + gpu->off_x = ((int32_t)((gpu->buf[0] >> 0 ) & 0x7ff) << 21) >> 21; + gpu->off_y = ((int32_t)((gpu->buf[0] >> 11) & 0x7ff) << 21) >> 21; } break; case 0xe6: { /* To-do: Implement mask bit thing */ @@ -1791,8 +1793,9 @@ void gpu_hblank_event(psx_gpu_t* gpu) { // Player Select. It probably uses T2 IRQs to time // GetlocP commands, if the timer is too slow it will // break. - if (!(gpu->line & 7)) - psx_ic_irq(gpu->ic, IC_TIMER2); + // if (!(gpu->line & 7)) + // psx_ic_irq(gpu->ic, IC_TIMER2); + // psx_ic_irq(gpu->ic, IC_SPU); } else { gpu->gpustat &= ~(1 << 31); } @@ -1808,8 +1811,6 @@ void gpu_hblank_event(psx_gpu_t* gpu) { 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); - gpu->line = 0; } } diff --git a/psx/dev/gpu.h b/psx/dev/gpu.h index f362520..6170020 100644 --- a/psx/dev/gpu.h +++ b/psx/dev/gpu.h @@ -130,7 +130,7 @@ struct psx_gpu_t { uint32_t draw_x2, draw_y2; // Drawing offset - uint32_t off_x, off_y; + int32_t off_x, off_y; // Texture Window uint32_t texw_mx, texw_my; diff --git a/psx/dev/spu.c b/psx/dev/spu.c index b0e8455..65f17d5 100644 --- a/psx/dev/spu.c +++ b/psx/dev/spu.c @@ -89,12 +89,13 @@ psx_spu_t* psx_spu_create(void) { return (psx_spu_t*)malloc(sizeof(psx_spu_t)); } -void psx_spu_init(psx_spu_t* spu) { +void psx_spu_init(psx_spu_t* spu, psx_ic_t* ic) { memset(spu, 0, sizeof(psx_spu_t)); spu->io_base = PSX_SPU_BEGIN; spu->io_size = PSX_SPU_SIZE; + spu->ic = ic; spu->ram = (uint8_t*)malloc(SPU_RAM_SIZE); memset(spu->ram, 0, SPU_RAM_SIZE); @@ -141,6 +142,9 @@ void spu_read_block(psx_spu_t* spu, int v) { int32_t f0 = g_spu_pos_adpcm_table[filter]; int32_t f1 = g_spu_neg_adpcm_table[filter]; + if ((spu->irq9addr << 3) == addr) + psx_ic_irq(spu->ic, IC_SPU); + for (int j = 0; j < 28; j++) { uint16_t n = (spu->ram[addr + 2 + (j >> 1)] >> ((j & 1) * 4)) & 0xf; @@ -357,6 +361,10 @@ int spu_handle_write(psx_spu_t* spu, uint32_t offset, uint32_t value) { spu_kon(spu, value << (16 * high)); } return 1; + // case SPUR_SPUIRQA: { + // spu->irq9addr = value << 3; + // } return 1; + case SPUR_KOFFL: case SPUR_KOFFH: { int high = (offset & 2) != 0; diff --git a/psx/dev/spu.h b/psx/dev/spu.h index 4d84d03..d2b78f4 100644 --- a/psx/dev/spu.h +++ b/psx/dev/spu.h @@ -3,6 +3,8 @@ #include +#include "ic.h" + #define PSX_SPU_BEGIN 0x1f801c00 #define PSX_SPU_SIZE 0x400 #define PSX_SPU_END 0x1f801fff @@ -32,11 +34,13 @@ #define SPUR_TCTRL 0x1ac #define SPUR_SPUSTAT 0x1ae #define SPUR_MBASE 0x1a2 +#define SPUR_SPUIRQA 0x1a4 typedef struct __attribute__((__packed__)) { uint32_t bus_delay; uint32_t io_base, io_size; + psx_ic_t* ic; uint8_t* ram; struct __attribute__((__packed__)) { @@ -166,7 +170,7 @@ typedef struct __attribute__((__packed__)) { } psx_spu_t; psx_spu_t* psx_spu_create(void); -void psx_spu_init(psx_spu_t*); +void psx_spu_init(psx_spu_t*, psx_ic_t*); uint32_t psx_spu_read32(psx_spu_t*, uint32_t); uint16_t psx_spu_read16(psx_spu_t*, uint32_t); uint8_t psx_spu_read8(psx_spu_t*, uint32_t); diff --git a/psx/dev/timer.c b/psx/dev/timer.c index 0478738..deceb50 100644 --- a/psx/dev/timer.c +++ b/psx/dev/timer.c @@ -91,8 +91,32 @@ void timer_set_mode(psx_timer_t* timer, int index, uint16_t value) { timer->timer[index].blank_once = 0; timer->timer[index].paused = 0; - if (index == 2) - printf("timer_set_mode %u %04x\n", index, value); + // printf( + // "timer_set_mode %u %04x\n" + // "sync_enable %u\n" + // "sync_mode %u\n" + // "reset_target %u\n" + // "irq_target %u\n" + // "irq_max %u\n" + // "irq_repeat %u\n" + // "irq_toggle %u\n" + // "clk_source %u\n" + // "target_reached %u\n" + // "max_reached %u\n" + // "target %04x\n", + // index, value, + // timer->timer[index].sync_enable, + // timer->timer[index].sync_mode, + // timer->timer[index].reset_target, + // timer->timer[index].irq_target, + // timer->timer[index].irq_max, + // timer->timer[index].irq_repeat, + // timer->timer[index].irq_toggle, + // timer->timer[index].clk_source, + // timer->timer[index].target_reached, + // timer->timer[index].max_reached, + // timer->timer[index].target + // ); switch (index) { case 0: { @@ -209,20 +233,19 @@ void psx_timer_write8(psx_timer_t* timer, uint32_t offset, uint8_t value) { void timer_handle_irq(psx_timer_t* timer, int i) { int irq = 0; - int prev_target_reached = timer->timer[i].target_reached; - int prev_max_reached = timer->timer[i].max_reached; int target_reached = timer->timer[i].counter > timer->timer[i].target; int max_reached = timer->timer[i].counter > 65535.0f; if (target_reached) { timer->timer[i].target_reached = 1; - if (timer->timer[i].reset_target) { + // if ((i == 2) && (T2_CLKSRC == 2)) + // printf("target %04x (%f) reached\n", timer->timer[i].target, timer->timer[i].counter); + + if (timer->timer[i].reset_target) timer->timer[i].counter = 0; - timer->timer[i].div_counter = 0; - } - if (timer->timer[i].irq_target && !prev_target_reached) + if (timer->timer[i].irq_target) irq = 1; } @@ -230,12 +253,10 @@ void timer_handle_irq(psx_timer_t* timer, int i) { timer->timer[i].counter -= 65536.0f; timer->timer[i].max_reached = 1; - if (timer->timer[i].irq_max && !prev_max_reached) + if (timer->timer[i].irq_max) irq = 1; } - timer->timer[i].div_counter &= 0xffff; - if (!irq) return; @@ -258,8 +279,9 @@ void timer_handle_irq(psx_timer_t* timer, int i) { timer->timer[i].irq = 1; if (trigger) { - // printf("timer %u irq fire\n", i); - + // if ((i == 1)) + // printf("timer 1 irq fire\n"); + psx_ic_irq(timer->ic, 16 << i); } } @@ -308,10 +330,9 @@ void timer_update_timer2(psx_timer_t* timer, int cyc) { return; if (T2_CLKSRC <= 1) { - T2_COUNTER += cyc; + T2_COUNTER += (float)cyc; } else { - T2_COUNTER += ((float)cyc) * (1.0f / 8.0f); - // T2_COUNTER = T2_DIV_COUNTER >> 3; + T2_COUNTER += ((float)cyc) / 8.0f; } timer_handle_irq(timer, 2); @@ -331,9 +352,12 @@ void psxe_gpu_hblank_event_cb(psx_gpu_t* gpu) { timer->hblank = 1; - if ((T1_CLKSRC & 1) && !T1_PAUSED) + if ((T1_CLKSRC & 1) && !T1_PAUSED) { ++T1_COUNTER; + timer_handle_irq(timer, 1); + } + if (!T0_SYNC_EN) return; diff --git a/psx/msf.c b/psx/msf.c index 916b5e6..54bc54f 100644 --- a/psx/msf.c +++ b/psx/msf.c @@ -23,7 +23,7 @@ void msf_adjust(msf_t* msf) { msf->f -= CD_SECTORS_PS * s; } - if (msf->s > 60) { + if (msf->s >= 60) { int m = msf->s / 60; msf->m += m; diff --git a/psx/psx.c b/psx/psx.c index d394675..5fa3ab6 100644 --- a/psx/psx.c +++ b/psx/psx.c @@ -174,7 +174,7 @@ void psx_init(psx_t* psx, const char* bios_path, const char* exp_path) { psx_ic_init(psx->ic, psx->cpu); psx_scratchpad_init(psx->scratchpad); psx_gpu_init(psx->gpu, psx->ic); - psx_spu_init(psx->spu); + psx_spu_init(psx->spu, psx->ic); psx_timer_init(psx->timer, psx->ic, psx->gpu); psx_cdrom_init(psx->cdrom, psx->ic); psx_pad_init(psx->pad, psx->ic);