ref: 5cf46ac69c883a0b09fe674c38bdff3bab894535
dir: /psx/dev/timer.h/
#ifndef TIMER_H
#define TIMER_H
#include <stdint.h>
#include "ic.h"
#include "gpu.h"
#define PSX_TIMER_BEGIN 0x1f801100
#define PSX_TIMER_SIZE 0x30
#define PSX_TIMER_END 0x1f80112f
/*
0 Synchronization Enable (0=Free Run, 1=Synchronize via Bit1-2)
1-2 Synchronization Mode (0-3, see lists below)
Synchronization Modes for Counter 0:
0 = Pause counter during Hblank(s)
1 = Reset counter to 0000h at Hblank(s)
2 = Reset counter to 0000h at Hblank(s) and pause outside of Hblank
3 = Pause until Hblank occurs once, then switch to Free Run
Synchronization Modes for Counter 1:
Same as above, but using Vblank instead of Hblank
Synchronization Modes for Counter 2:
0 or 3 = Stop counter at current value (forever, no h/v-blank start)
1 or 2 = Free Run (same as when Synchronization Disabled)
3 Reset counter to 0000h (0=After Counter=FFFFh, 1=After Counter=Target)
4 IRQ when Counter=Target (0=Disable, 1=Enable)
5 IRQ when Counter=FFFFh (0=Disable, 1=Enable)
6 IRQ Once/Repeat Mode (0=One-shot, 1=Repeatedly)
7 IRQ Pulse/Toggle Mode (0=Short Bit10=0 Pulse, 1=Toggle Bit10 on/off)
8-9 Clock Source (0-3, see list below)
Counter 0: 0 or 2 = System Clock, 1 or 3 = Dotclock
Counter 1: 0 or 2 = System Clock, 1 or 3 = Hblank
Counter 2: 0 or 1 = System Clock, 2 or 3 = System Clock/8
10 Interrupt Request (0=Yes, 1=No) (Set after Writing) (W=1) (R)
11 Reached Target Value (0=No, 1=Yes) (Reset after Reading) (R)
12 Reached FFFFh Value (0=No, 1=Yes) (Reset after Reading) (R)
13-15 Unknown (seems to be always zero)
16-31 Garbage (next opcode)
*/
#define MODE_SYNCEN 0x0001
#define MODE_SYNCMD 0x0006
#define T0MD_HBLPAUSE 0
#define T0MD_HBLRESET 1
#define T0MD_HBLRANDP 2
#define T0MD_HBLOSHOT 3
// #define T1MD_VBLPAUSE 0
// #define T1MD_VBLRESET 1
// #define T1MD_VBLRANDP 2
// #define T1MD_VBLOSHOT 3
// #define T2MD_STOPMODE 0
// #define T2MD_FREEMODE 1
#define MODE_RESETC 0x0008
#define MODE_TGTIRQ 0x0010
#define MODE_MAXIRQ 0x0020
#define MODE_IRQRMD 0x0040
#define MODE_IRQPMD 0x0080
#define MODE_CLK 0x0080
typedef struct {
uint32_t io_base, io_size;
psx_ic_t* ic;
struct {
uint16_t prev_counter;
uint16_t counter;
uint32_t mode;
uint32_t target;
int paused;
int irq_fired;
} timer[3];
} psx_timer_t;
psx_timer_t* psx_timer_create();
void psx_timer_init(psx_timer_t*, psx_ic_t*);
uint32_t psx_timer_read32(psx_timer_t*, uint32_t);
uint16_t psx_timer_read16(psx_timer_t*, uint32_t);
uint8_t psx_timer_read8(psx_timer_t*, uint32_t);
void psx_timer_write32(psx_timer_t*, uint32_t, uint32_t);
void psx_timer_write16(psx_timer_t*, uint32_t, uint16_t);
void psx_timer_write8(psx_timer_t*, uint32_t, uint8_t);
void psx_timer_update(psx_timer_t*, int);
void psx_timer_destroy(psx_timer_t*);
// GPU event handlers
void psxe_gpu_hblank_event_cb(psx_gpu_t*);
void psxe_gpu_hblank_end_event_cb(psx_gpu_t*);
void psxe_gpu_vblank_timer_event_cb(psx_gpu_t*);
void psxe_gpu_vblank_end_event_cb(psx_gpu_t*);
#endif