From 073a859acf16ccbc0f49364e38126bf2bf03aa3d Mon Sep 17 00:00:00 2001 From: spicyjpeg Date: Sat, 30 Jul 2022 00:53:31 +0200 Subject: Deprecate u_short, u_int and u_long types in libpsn00b --- libpsn00b/include/psxapi.h | 156 +++++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 76 deletions(-) (limited to 'libpsn00b/include/psxapi.h') diff --git a/libpsn00b/include/psxapi.h b/libpsn00b/include/psxapi.h index 1298d29..1bdbdbf 100644 --- a/libpsn00b/include/psxapi.h +++ b/libpsn00b/include/psxapi.h @@ -1,5 +1,15 @@ -#ifndef __PSXAPI__ -#define __PSXAPI__ +/* + * PSn00bSDK kernel API library + * (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed + */ + +#ifndef __PSXAPI_H +#define __PSXAPI_H + +#include +#include + +/* Definitions */ #define DescHW 0xf0000000 #define DescSW 0xf4000000 @@ -32,29 +42,31 @@ #define RCntMdFR 0x0000 #define RCntMdGATE 0x0010 +/* Structure definitions */ + typedef struct { // Thread control block - int status; - int mode; + int status; + int mode; union { - unsigned int reg[37]; + uint32_t reg[37]; struct { - unsigned int zero, at; - unsigned int v0, v1; - unsigned int a0, a1, a2, a3; - unsigned int t0, t1, t2, t3, t4, t5, t6, t7; - unsigned int s0, s1, s2, s3, s4, s5, s6, s7; - unsigned int t8, t9; - unsigned int k0, k1; - unsigned int gp, sp, fp, ra; - - unsigned int cop0r14; - unsigned int hi; - unsigned int lo; - unsigned int cop0r12; - unsigned int cop0r13; + uint32_t zero, at; + uint32_t v0, v1; + uint32_t a0, a1, a2, a3; + uint32_t t0, t1, t2, t3, t4, t5, t6, t7; + uint32_t s0, s1, s2, s3, s4, s5, s6, s7; + uint32_t t8, t9; + uint32_t k0, k1; + uint32_t gp, sp, fp, ra; + + uint32_t cop0r14; + uint32_t hi; + uint32_t lo; + uint32_t cop0r12; + uint32_t cop0r13; }; }; - int _reserved[9]; + int _reserved[9]; } TCB; typedef struct { // Process control block @@ -85,17 +97,17 @@ typedef struct { // Device control block } DCB; typedef struct { // File control block - int status; - unsigned int diskid; - void *trns_addr; - unsigned int trns_len; - unsigned int filepos; - unsigned int flags; - unsigned int lasterr; - DCB *dcb; - unsigned int filesize; - unsigned int lba; - unsigned int fcbnum; + int status; + uint32_t diskid; + void *trns_addr; + uint32_t trns_len; + uint32_t filepos; + uint32_t flags; + uint32_t lasterr; + DCB *dcb; + uint32_t filesize; + uint32_t lba; + uint32_t fcbnum; } FCB; struct DIRENTRY { // Directory entry @@ -108,34 +120,31 @@ struct DIRENTRY { // Directory entry }; struct EXEC { - unsigned int pc0; - unsigned int gp0; - unsigned int t_addr; - unsigned int t_size; - unsigned int d_addr; - unsigned int d_size; - unsigned int b_addr; - unsigned int b_size; - unsigned int s_addr; - unsigned int s_size; - unsigned int sp,fp,rp,ret,base; + uint32_t pc0, gp0; + uint32_t t_addr, t_size; + uint32_t d_addr, d_size; + uint32_t b_addr, b_size; + uint32_t s_addr, s_size; + uint32_t sp, fp, rp, ret, base; }; struct JMP_BUF { - unsigned int ra, sp, fp; - unsigned int s0, s1, s2, s3, s4, s5, s6, s7; - unsigned int gp; + uint32_t ra, sp, fp; + uint32_t s0, s1, s2, s3, s4, s5, s6, s7; + uint32_t gp; }; // Not recommended to use these functions to install IRQ handlers typedef struct { - unsigned int* next; - unsigned int* func2; - unsigned int* func1; - unsigned int pad; + uint32_t *next; + uint32_t *func2; + uint32_t *func1; + int _reserved; } INT_RP; +/* API */ + #ifdef __cplusplus extern "C" { #endif @@ -143,30 +152,27 @@ extern "C" { void SysEnqIntRP(int pri, INT_RP *rp); void SysDeqIntRP(int pri, INT_RP *rp); -// Event handler stuff - -int OpenEvent(unsigned int cl, int spec, int mode, void (*func)()); -int CloseEvent(int ev_desc); -int EnableEvent(int ev_desc); -int DisableEvent(int ev_desc); - -// BIOS file functions +int OpenEvent(uint32_t cl, uint32_t spec, int mode, void (*func)()); +int CloseEvent(int event); +int WaitEvent(int event); +int TestEvent(int event); +int EnableEvent(int event); +int DisableEvent(int event); +void DeliverEvent(uint32_t cl, uint32_t spec); +void UnDeliverEvent(uint32_t cl, uint32_t spec); int open(const char *name, int mode); int close(int fd); -int seek(int fd, unsigned int offset, int mode); -int read(int fd, char *buff, unsigned int len); -int write(int fd, const char *buff, unsigned int len); +int seek(int fd, uint32_t offset, int mode); +int read(int fd, uint8_t *buff, size_t len); +int write(int fd, const uint8_t *buff, size_t len); int ioctl(int fd, int cmd, int arg); struct DIRENTRY *firstfile(const char *wildcard, struct DIRENTRY *entry); struct DIRENTRY *nextfile(struct DIRENTRY *entry); int erase(const char *name); int chdir(const char *path); -//#define delete( p ) erase( p ) // May conflict with delete operator in C++ -#define cd( p ) chdir( p ) // For compatibility - -// BIOS device functions +//#define cd(p) chdir(p) int AddDev(DCB *dcb); int DelDev(const char *name); @@ -175,18 +181,17 @@ void AddDummyTty(void); void EnterCriticalSection(void); void ExitCriticalSection(void); +void SwEnterCriticalSection(void); +void SwExitCriticalSection(void); -// BIOS CD functions void _InitCd(void); void _96_init(void); void _96_remove(void); -// BIOS pad functions -void InitPAD(char *buff1, int len1, char *buff2, int len2); +void InitPAD(uint8_t *buff1, int len1, uint8_t *buff2, int len2); void StartPAD(void); void StopPAD(void); -// BIOS memory card functions void InitCARD(int pad_enable); void StartCARD(void); void StopCARD(void); @@ -198,32 +203,31 @@ int _card_status(int chan); int _card_wait(int chan); int _card_clear(int chan); int _card_chan(void); -int _card_read(int chan, int sector, unsigned char *buf); -int _card_write(int chan, int sector, unsigned char *buf); +int _card_read(int chan, int sector, uint8_t *buf); +int _card_write(int chan, int sector, uint8_t *buf); void _new_card(void); -// Timers -int SetRCnt(int spec, unsigned short target, int mode); +int SetRCnt(int spec, uint16_t target, int mode); int GetRCnt(int spec); int StartRCnt(int spec); int StopRCnt(int spec); int ResetRCnt(int spec); -// BIOS IRQ acknowledge control void ChangeClearPAD(int mode); void ChangeClearRCnt(int t, int m); -// Executable functions +uint32_t OpenTh(uint32_t (*func)(), uint32_t sp, uint32_t gp); +int CloseTh(uint32_t thread); +int ChangeTh(uint32_t thread); + int Exec(struct EXEC *exec, int argc, char **argv); void FlushCache(void); -// BIOS setjmp functions void b_setjmp(struct JMP_BUF *buf); void b_longjmp(struct JMP_BUF *buf, int param); void SetDefaultExitFromException(void); void SetCustomExitFromException(struct JMP_BUF *buf); -// Misc functions int GetSystemInfo(int index); void *GetB0Table(void); void *GetC0Table(void); -- cgit v1.2.3 From ec3ed1574dac08b1c07a8126f6090adce0e7efb8 Mon Sep 17 00:00:00 2001 From: spicyjpeg Date: Sat, 13 Aug 2022 21:26:36 +0200 Subject: Rewrite libpsxetc in C, add ResetCallback() --- libpsn00b/include/psxapi.h | 5 +- libpsn00b/include/psxetc.h | 22 +++- libpsn00b/psxetc/dmacallback.s | 191 ---------------------------- libpsn00b/psxetc/getinterruptcallback.s | 19 --- libpsn00b/psxetc/interruptcallback.s | 48 ------- libpsn00b/psxetc/interrupts.c | 214 ++++++++++++++++++++++++++++++++ libpsn00b/psxetc/isr.s | 107 ---------------- libpsn00b/psxetc/restartcallback.s | 54 -------- libpsn00b/psxgpu/common.c | 13 +- 9 files changed, 235 insertions(+), 438 deletions(-) delete mode 100644 libpsn00b/psxetc/dmacallback.s delete mode 100644 libpsn00b/psxetc/getinterruptcallback.s delete mode 100644 libpsn00b/psxetc/interruptcallback.s create mode 100644 libpsn00b/psxetc/interrupts.c delete mode 100644 libpsn00b/psxetc/isr.s delete mode 100644 libpsn00b/psxetc/restartcallback.s (limited to 'libpsn00b/include/psxapi.h') diff --git a/libpsn00b/include/psxapi.h b/libpsn00b/include/psxapi.h index 1bdbdbf..5d1097e 100644 --- a/libpsn00b/include/psxapi.h +++ b/libpsn00b/include/psxapi.h @@ -224,9 +224,10 @@ int Exec(struct EXEC *exec, int argc, char **argv); void FlushCache(void); void b_setjmp(struct JMP_BUF *buf); -void b_longjmp(struct JMP_BUF *buf, int param); +void b_longjmp(const struct JMP_BUF *buf, int param); void SetDefaultExitFromException(void); -void SetCustomExitFromException(struct JMP_BUF *buf); +void SetCustomExitFromException(const struct JMP_BUF *buf); +void ReturnFromException(void); int GetSystemInfo(int index); void *GetB0Table(void); diff --git a/libpsn00b/include/psxetc.h b/libpsn00b/include/psxetc.h index a55e593..24485d9 100644 --- a/libpsn00b/include/psxetc.h +++ b/libpsn00b/include/psxetc.h @@ -1,15 +1,25 @@ -#ifndef _PSXETC_H -#define _PSXETC_H +/* + * PSn00bSDK interrupt management library + * (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed + */ + +#ifndef __PSXETC_H +#define __PSXETC_H + +/* Public API */ #ifdef __cplusplus extern "C" { #endif -// Interrupt callback functions -void *DMACallback(int dma, void (*func)(void)); void *InterruptCallback(int irq, void (*func)(void)); -void *GetInterruptCallback(int irq); // Original -void RestartCallback(); +void *GetInterruptCallback(int irq); +void *DMACallback(int dma, void (*func)(void)); +void *GetDMACallback(int dma); + +int ResetCallback(void); +void RestartCallback(void); +void StopCallback(void); #ifdef __cplusplus } diff --git a/libpsn00b/psxetc/dmacallback.s b/libpsn00b/psxetc/dmacallback.s deleted file mode 100644 index 8ea8ec0..0000000 --- a/libpsn00b/psxetc/dmacallback.s +++ /dev/null @@ -1,191 +0,0 @@ -.set noreorder - -.include "hwregs_a.h" - -.section .text - -.global DMACallback -.type DMACallback, @function -DMACallback: - - # a0 - DMA channel - # a1 - Callback function - - addiu $sp, -8 - sw $ra, 0($sp) - - beqz $a1, .Lremove_cb # Remove callback if function is NULL - nop - - addiu $sp, -8 # Install IRQ handler for DMA handler - sw $a0, 0($sp) # if not set installed yet - sw $a1, 4($sp) - - jal GetInterruptCallback - li $a0, 3 - - bnez $v0, .Lskip_install - nop - - la $a1, _dma_handler - jal InterruptCallback - li $a0, 3 - -.Lskip_install: - - lw $a0, 0($sp) - lw $a1, 4($sp) - addiu $sp, 8 - - la $v0, _dma_func_table - sll $v1, $a0, 2 - addu $v0, $v1 - lw $v1, 0($v0) - sw $a1, 0($v0) - sw $v1, 4($sp) - - lui $a2, IOBASE - - lw $v0, DMA_DICR($a2) # Enable DMA interrupt - lui $v1, 0x1 - sll $v1, $a0 - or $v0, $v1 - lui $v1, 0x80 - or $v0, $v1 - sw $v0, DMA_DICR($a2) - - b .Lskip_remove - nop - -.Lremove_cb: - - la $v0, _dma_func_table # Set callback address - sll $v1, $a0, 2 - addu $v0, $v1 - lw $v1, 0($v0) - sw $a1, 0($v0) - sw $v1, 4($sp) - - lui $a2, IOBASE # Disable DMA interrupt - lw $v0, DMA_DICR($a2) - lui $v1, 0x1 - sll $v1, $a0 - .set noat - addiu $at, $0, -1 - xor $v1, $at - and $v0, $v1 - lui $v1, 0x7f00 - xor $v1, $at - and $v0, $v1 - .set at - sw $v0, DMA_DICR($a2) - - jal _dma_has_cb # Check if callbacks are present - nop - bnez $v0, .Lskip_remove - nop - sw $0 , DMA_DICR($a2) - - jal GetInterruptCallback # Check if callback is the DMA handler - li $a0, 3 - la $v1, _dma_handler - bne $v0, $v1, .Lskip_remove - nop - - li $a0, 3 - jal InterruptCallback - move $a1, $0 - -.Lskip_remove: - - lw $ra, 0($sp) - lw $v0, 4($sp) - jr $ra - addiu $sp, 8 - - -.type _dma_has_cb, @function -_dma_has_cb: - - la $v1, _dma_func_table - li $t0, 6 - -.Lscan_loop: - - lw $v0, 0($v1) - addiu $v1, 4 - bnez $v0, .Lhas_cb - nop - - bgtz $t0, .Lscan_loop - addiu $t0, -1 - - jr $ra - move $v0, $0 - -.Lhas_cb: - - jr $ra - li $v0, 1 - - -.type _dma_handler, @function -_dma_handler: - - addiu $sp, -12 - sw $ra, 0($sp) - sw $s0, 4($sp) - sw $s1, 8($sp) - - move $s0, $0 - la $s1, _dma_func_table - -.Lhandler_loop: - - lui $a0, IOBASE - lw $v0, DMA_DICR($a0) - li $v1, 24 - addu $v1, $s0 - srl $v0, $v1 - andi $v0, 0x1 - - lw $v1, 0($s1) - - beqz $v0, .Lno_irq - addiu $s1, 4 - - beqz $v1, .Lno_irq - nop - - jalr $v1 - nop - -.Lno_irq: - - blt $s0, 6, .Lhandler_loop - addi $s0, 1 - - lui $a0, IOBASE - lw $v0, DMA_DICR($a0) - nop - sw $v0, DMA_DICR($a0) - - lw $ra, 0($sp) - lw $s0, 4($sp) - lw $s1, 8($sp) - - jr $ra - addiu $sp, -12 - - -.section .data - -_dma_func_table: - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - \ No newline at end of file diff --git a/libpsn00b/psxetc/getinterruptcallback.s b/libpsn00b/psxetc/getinterruptcallback.s deleted file mode 100644 index 510447f..0000000 --- a/libpsn00b/psxetc/getinterruptcallback.s +++ /dev/null @@ -1,19 +0,0 @@ -.set noreorder - -.section .text - -.global GetInterruptCallback -.type GetInterruptCallback, @function -GetInterruptCallback: - - # a0 - Interrupt number - - la $a1, _irq_func_table - sll $a0, 2 - addu $a1, $a0 - lw $v0, 0($a1) - nop - jr $ra - nop - - \ No newline at end of file diff --git a/libpsn00b/psxetc/interruptcallback.s b/libpsn00b/psxetc/interruptcallback.s deleted file mode 100644 index 78e5e6e..0000000 --- a/libpsn00b/psxetc/interruptcallback.s +++ /dev/null @@ -1,48 +0,0 @@ -.set noreorder - -.include "hwregs_a.h" - -.section .text - -.global InterruptCallback -.type InterruptCallback, @function -InterruptCallback: - - # a0 - Interrupt number - # a1 - Callback function - - lui $a2, IOBASE - - beqz $a1, .Ldisable_irq - nop - - lw $v0, IRQ_MASK($a2) # Enable interrupt mask - li $v1, 1 - sll $v1, $a0 - or $v0, $v1 - - b .Lcont - sw $v0, IRQ_MASK($a2) - -.Ldisable_irq: - -.set noat - lw $v0, IRQ_MASK($a2) # Disable interrupt mask - li $v1, 1 - sll $v1, $a0 - addiu $at, $0 , -1 - xor $v1, $at -.set at - and $v0, $v1 - sw $v0, IRQ_MASK($a2) - -.Lcont: - - la $a2, _irq_func_table # Get address to IRQ function table - - sll $v1, $a0, 2 # Compute the slot - addu $v1, $a2, $v1 - lw $v0, 0($v1) # Get old handler address - - jr $ra # Return and set new IRQ handler - sw $a1, 0($v1) diff --git a/libpsn00b/psxetc/interrupts.c b/libpsn00b/psxetc/interrupts.c new file mode 100644 index 0000000..e5c4705 --- /dev/null +++ b/libpsn00b/psxetc/interrupts.c @@ -0,0 +1,214 @@ +/* + * PSn00bSDK interrupt management library + * (C) 2022 spicyjpeg - MPL licensed + */ + +#include +#include +#include +#include + +#define NUM_IRQ_CHANNELS 11 +#define NUM_DMA_CHANNELS 7 +#define ISR_STACK_SIZE 0x1000 + +/* Internal globals */ + +static void (*_irq_handlers[NUM_IRQ_CHANNELS])(void) = { (void *) 0 }; +static void (*_dma_handlers[NUM_DMA_CHANNELS])(void) = { (void *) 0 }; +static int _num_dma_handlers = 0; + +static uint32_t _saved_irq_mask, _saved_dma_dpcr, _saved_dma_dicr; +static int _isr_installed = 0; + +/* Custom ISR jmp_buf */ + +// The ISR and all functions called by it (thus, all callbacks registered using +// InterruptCallback() and DMACallback()) use an independent stack, isolated +// from the main thread's stack. As the size of this stack is limited, custom +// callbacks shall keep the number of nested subroutine calls to a minimum and +// avoid allocating large buffers (e.g. for receiving a sector from the CD +// drive) on the stack. +static uint8_t _isr_stack[ISR_STACK_SIZE]; + +extern uint8_t _gp[]; +static void _global_isr(void); + +static const struct JMP_BUF _isr_jmp_buf = { + .ra = (uint32_t) &_global_isr, + .sp = (uint32_t) &_isr_stack[ISR_STACK_SIZE], + .fp = 0, + .s0 = 0, + .s1 = 0, + .s2 = 0, + .s3 = 0, + .s4 = 0, + .s5 = 0, + .s6 = 0, + .s7 = 0, + .gp = (uint32_t) _gp +}; + +/* Internal IRQ and DMA handlers */ + +static void _global_isr(void) { + uint32_t stat = IRQ_STAT, mask = IRQ_MASK; + + // Clear all IRQ flags in one shot. This is not the "proper" way to do it + // but it's much faster than clearing one flag at a time. + IRQ_STAT = ~mask; + + //for (int i = 0; i < NUM_IRQ_CHANNELS; i++) { + for (int i = 0; stat; i++, stat >>= 1) { + if (!(stat & 1)) + continue; + + if (_irq_handlers[i]) + _irq_handlers[i](); + } + + ReturnFromException(); +} + +static void _global_dma_handler(void) { + uint32_t stat = DMA_DICR; + + // Clear all DMA IRQ flags in one shot (note that flags are cleared by + // writing 1 to them rather than 0). + stat &= 0x7fff0000; + DMA_DICR = stat; + stat >>= 24; + + //for (int i = 0; i < NUM_DMA_CHANNELS; i++) { + for (int i = 0; stat; i++, stat >>= 1) { + if (!(stat & 1)) + continue; + + if (_dma_handlers[i]) + _dma_handlers[i](); + } +} + +/* Callback registration API */ + +void *InterruptCallback(int irq, void (*func)(void)) { + if ((irq < 0) || (irq >= NUM_IRQ_CHANNELS)) + return 0; + + void *old_callback = _irq_handlers[irq]; + _irq_handlers[irq] = func; + + // Enable or disable the IRQ in the IRQ_MASK register depending on whether + // the callback is being registered or removed. + if (func) + IRQ_MASK |= 1 << irq; + else + IRQ_MASK &= ~(1 << irq); + + return old_callback; +} + +void *GetInterruptCallback(int irq) { + if ((irq < 0) || (irq >= NUM_IRQ_CHANNELS)) + return 0; + + return _irq_handlers[irq]; +} + +void *DMACallback(int dma, void (*func)(void)) { + if ((dma < 0) || (dma >= NUM_DMA_CHANNELS)) + return 0; + + void *old_callback = _dma_handlers[dma]; + _dma_handlers[dma] = func; + + // Enable or disable the IRQ in the DMA_DICR register depending on whether + // the callback is being registered or removed. The main DMA IRQ dispatcher + // is also registered if this is the first DMA callback being configured, + // or disabled if it's the last one being removed. + if (func) { + DMA_DICR |= (0x10000 << dma) | (1 << 23); + + if (!(_num_dma_handlers++)) + InterruptCallback(3, &_global_dma_handler); + } else { + if (--_num_dma_handlers) { + DMA_DICR &= ~(0x10000 << dma); + } else { + DMA_DICR = 0; + InterruptCallback(3, 0); + } + } + + return old_callback; +} + +void *GetDMACallback(int dma) { + if ((dma < 0) || (dma >= NUM_DMA_CHANNELS)) + return 0; + + return _dma_handlers[dma]; +} + +/* Hook installation/removal API */ + +int ResetCallback(void) { + if (_isr_installed) + return -1; + + _saved_irq_mask = 0; + _saved_dma_dpcr = 0x03333333; + _saved_dma_dicr = 0; + + _96_remove(); + RestartCallback(); + return 0; +} + +void RestartCallback(void) { + if (_isr_installed) + return; + + IRQ_STAT = 0; + IRQ_MASK = _saved_irq_mask; + DMA_DPCR = _saved_dma_dpcr; + DMA_DICR = _saved_dma_dicr; + + // Install the ISR hook and prevent the kernel's internal handlers from + // automatically acknowledging SPI and timer IRQs. + SetCustomExitFromException(&_isr_jmp_buf); + ChangeClearPAD(0); + ChangeClearRCnt(0, 0); + ChangeClearRCnt(1, 0); + ChangeClearRCnt(2, 0); + ChangeClearRCnt(3, 0); + + _isr_installed = 1; + ExitCriticalSection(); +} + +void StopCallback(void) { + if (!_isr_installed) + return; + + // Save the state of IRQ and DMA registers, then reset them and undo the + // changes that were made to the kernel's state. + EnterCriticalSection(); + _saved_irq_mask = IRQ_MASK; + _saved_dma_dpcr = DMA_DPCR; + _saved_dma_dicr = DMA_DICR; + + IRQ_STAT = 0; + IRQ_MASK = 0; + DMA_DPCR = _saved_dma_dpcr & 0x07777777; + DMA_DICR = 0; + + SetDefaultExitFromException(); + ChangeClearPAD(1); + ChangeClearRCnt(0, 1); + ChangeClearRCnt(1, 1); + ChangeClearRCnt(2, 1); + ChangeClearRCnt(3, 1); + + _isr_installed = 0; +} diff --git a/libpsn00b/psxetc/isr.s b/libpsn00b/psxetc/isr.s deleted file mode 100644 index 440be50..0000000 --- a/libpsn00b/psxetc/isr.s +++ /dev/null @@ -1,107 +0,0 @@ -.set noreorder - -.include "hwregs_a.h" - -.set ISR_STACK_SIZE, 4096 - - -.section .text - -# Global ISR handler of PSn00bSDK - -.set at - -.type _global_isr, @function -_global_isr: - -.Lisr_loop: - - #la $gp, _gp # Keep restoring GP since it gets - # changed elsewhere sometimes - - lui $a0, IOBASE # Get IRQ status - lw $v0, IRQ_MASK($a0) - nop - - srl $v0, $s1 # Check IRQ mask bit if set - andi $v0, 0x1 - - beqz $v0, .Lno_irq # Don't execute callback if IRQ not enabled - nop - - lw $v0, IRQ_STAT($a0) - nop - srl $v0, $s1 # Check IRQ status bit if set - andi $v0, 0x1 - beqz $v0, .Lno_irq # Don't execute callback if no IRQ - nop - - lw $v1, 0($s0) # Load IRQ callback function - nop - - lw $v0, IRQ_STAT($a0) # Acknowledge the IRQ (by writing a 0 bit) - li $a1, 1 - sll $a1, $s1 - addiu $a2, $0 , -1 - xor $a1, $a2 - sw $a1, IRQ_STAT($a0) - - beqz $v1, .Lno_irq # Don't execute if callback is not set - nop - - jalr $v1 # Call interrupt handler - nop - -.Lno_irq: - - addiu $s0, 4 - - blt $s1, 11, .Lisr_loop - addiu $s1, 1 - - j ReturnFromException - nop - - -.section .data - -# Global ISR callback table - -.global _irq_func_table -.type _irq_func_table, @object -_irq_func_table: - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - -# Global ISR hook structure -.global _custom_exit -.type _custom_exit, @object -_custom_exit: - .word _global_isr # pc - .word _isr_stack+ISR_STACK_SIZE # sp - .word 0 # fp - .word _irq_func_table # s0 - .word 0 # s1 - .word 0 # s2 - .word 0 # s3 - .word 0 # s4 - .word 0 # s5 - .word 0 # s6 - .word 0 # s7 - .word _gp # gp - -# Global ISR stack -# .fill 1024 -#_custom_exit_stack: -# .fill 4 -.comm _isr_stack, ISR_STACK_SIZE+4 diff --git a/libpsn00b/psxetc/restartcallback.s b/libpsn00b/psxetc/restartcallback.s deleted file mode 100644 index 036a5a0..0000000 --- a/libpsn00b/psxetc/restartcallback.s +++ /dev/null @@ -1,54 +0,0 @@ -.set noreorder - -.include "hwregs_a.h" - -.section .text - -.global RestartCallback -.type RestartCallback, @function -RestartCallback: - - addiu $sp, -4 - sw $ra, 0($sp) - - la $a0, _custom_exit - jal SetCustomExitFromException - addiu $sp, -4 - addiu $sp, 4 - - move $a0, $0 - jal ChangeClearPAD - addiu $sp, -4 - addiu $sp, 4 - - li $a0, 3 - move $a1, $0 - jal ChangeClearRCnt - addiu $sp, -8 - addiu $sp, 8 - - la $a0, _irq_func_table - move $a1, $0 - move $v0, $0 - -.Lcheck_cbs: # Set up the interrupt masks - lw $v1, 0($a0) - nop - beqz $v1, .Lno_cb - addiu $a0, 4 - li $v1, 1 - sll $v1, $a1 - or $v0, $v1 -.Lno_cb: - blt $a1, 10, .Lcheck_cbs - addiu $a1, 1 - - lui $a0, IOBASE - sw $0 , IRQ_STAT($a0) - sw $v0, IRQ_MASK($a0) - - lw $ra, 0($sp) - addiu $sp, 4 - jr $ra - nop - \ No newline at end of file diff --git a/libpsn00b/psxgpu/common.c b/libpsn00b/psxgpu/common.c index 4591012..d338d93 100644 --- a/libpsn00b/psxgpu/common.c +++ b/libpsn00b/psxgpu/common.c @@ -58,23 +58,14 @@ static void _gpu_dma_handler(void) { void ResetGraph(int mode) { // Perform some basic system initialization when ResetGraph() is called for // the first time. - static int setup_done = 0; - if (!setup_done) { + if (!ResetCallback()) { EnterCriticalSection(); - - DMA_DPCR = 0x03333333; - DMA_DICR = 0; - IRQ_MASK = 0; - InterruptCallback(0, &_vblank_handler); DMACallback(2, &_gpu_dma_handler); - RestartCallback(); - _96_remove(); _gpu_video_mode = (GPU_GP1 >> 20) & 1; - setup_done = 1; - ExitCriticalSection(); + printf("psxgpu: setup done, default mode is %s\n", _gpu_video_mode ? "PAL" : "NTSC"); } -- cgit v1.2.3