Skip to content

Commit

Permalink
intr.c (#7)
Browse files Browse the repository at this point in the history
* intr.c

* updates
  • Loading branch information
sozud authored Jan 26, 2025
1 parent 9503af2 commit 78fbe9e
Show file tree
Hide file tree
Showing 3 changed files with 267 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ def build_35():
'src/etc/intr_vb.c',
'src/etc/pad.c',
'src/etc/vmode.c',
'src/etc/intr.c'
]

add_lib_263(etc_srcs, "build/3.5/etc", "./psy-q/3.5/PSX/LIB/LIBETC.LIB", "-DVERSION=35", "3.5")
Expand Down
65 changes: 65 additions & 0 deletions src/etc/etc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#ifndef LIBETC_H
#define LIBETC_H

#define JB_PC 0
#define JB_SP 1
#define JB_FP 2
#define JB_S0 3
#define JB_S1 4
#define JB_S2 5
#define JB_S3 6
#define JB_S4 7
#define JB_S5 8
#define JB_S6 9
#define JB_S7 10
#define JB_GP 11
#define JB_SIZE 12

typedef int jmp_buf[JB_SIZE];
typedef void (*Callback)();
struct intrEnv_t {
u16 interruptsInitialized; // 2
u16 inInterrupt; // 2
Callback handlers[11]; // 44
u16 enabledInterruptsMask; // 2
u16 savedMask; // 2
struct Temp {
int savedPcr; // 4

This comment has been minimized.

Copy link
@ser-pounce

ser-pounce Jan 26, 2025

You mentioned in the PR on sotn

intrEnv gets initialized as 56 bytes then 4144 bytes.

I think savedPcr lives outside temp in that case.

This comment has been minimized.

Copy link
@sozud

sozud Jan 26, 2025

Author Owner

Seems not to work

+ {                               {
+   "Command2": {                   "Command2": {
+     "len": 56,                      "len": 60,
+     "bytes": [                      "bytes": [
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0,                              0,
+       0                               0,
+     ]                                 0,
+   }                                   0,
+ }                                     0,
+                                       0
+                                     ]
+                                   }
+                                 }
mismatch
+ {                               {
+   "Command8": {                   "Command8": {
+     "size": 4144                    "size": 44
+   }                               }
+ }                               }
mismatch
+ {                               {
+   "Command2": {                   "Command8": {
+     "len": 32,                      "size": 4096
+     "bytes": [                    }
+       0,                        }
+       0,                        
+       0,                        
+       0,                        
+       0,                        
+       0,                        
+       0,                        
+       0,                        
+       0,                        
+       0,                        

This comment has been minimized.

Copy link
@ser-pounce

ser-pounce Jan 26, 2025

It's weird because going by the code savedPcr doesn't look like it would have any business in that struct, but it's hard to argue with the comparison.

This comment has been minimized.

Copy link
@sozud

sozud Jan 26, 2025

Author Owner

It may be a problem with padding being generated but I don't know how to do __attribute__(packed) on this compiler. e.g. the first command shouldn't go to 60 bytes but it does for some reason. Not sure if that would be likely anyway. There's probably a better solution than what I found

jmp_buf buf; // 48
s32 stack[1024];
} temp;
};

struct Callbacks {
const char* rcsid; /* "$Id: intr.c,v 1.73 1995/11/10 05:29:40 suzu Exp $" */
void* (*DMACallback)(int dma, void (*func)());
Callback (*InterruptCallback)(int irq, Callback f);
void* (*ResetCallback)(void);
void* (*StopCallback)(void);
int (*VSyncCallbacks)(int ch, void (*f)());
void* (*RestartCallback)(void);
void* D_8002C2B8;
};

extern struct Callbacks* D_8002D340;

void VSyncCallback(void (*f)()); /* 13 */

extern void ChangeClearPAD(long); /* 28 */

int VSync(int mode);
int VSyncCallbacks(int ch, void (*f)());

void* DMACallback(int dma, void (*func)());
void* ResetCallback(void);
void* StopCallback(void);
void* RestartCallback(void);
int CheckCallback(void);

long SetVideoMode(long mode);

void PadInit(int mode);
u_long PadRead(int id);
void PadStop(void);

#endif
201 changes: 201 additions & 0 deletions src/etc/intr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#include "../types.h"
#include "etc.h"

typedef struct intrEnv_t intrEnv_t;
static Callback setIntr(s32 arg0, Callback arg1);
static void* startIntr();
static void* stopIntr();
static void* restartIntr();
static void memclr(void* ptr, s32 size);
static void trapIntr();
s32 setjmp(s32*);
void* startIntrVSync(); /* extern */
long long startIntrDMA();

static struct intrEnv_t intrEnv = {
0, // interruptsInitialized
0, // inInterrupt
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0}, // handlers (explicit zeros for each element)
0, // enabledInterruptsMask
0, // savedMask
{0}, // temp
};

static struct Callbacks callbacks = {
"$Id: intr.c,v 1.73 1995/11/10 05:29:40 suzu Exp $",
0,
setIntr,
startIntr,
stopIntr,
0,
restartIntr,
&intrEnv};

static struct Callbacks* pCallbacks = &callbacks;

void* ResetCallback(void) { return pCallbacks->ResetCallback(); }

void InterruptCallback(int irq, void (*f)()) {
pCallbacks->InterruptCallback(irq, f);
}

void* DMACallback(int dma, void (*func)()) {
return pCallbacks->DMACallback(dma, func);
}

void VSyncCallback(void (*f)()) { pCallbacks->VSyncCallbacks(0, f); }

int VSyncCallbacks(int ch, void (*f)()) {
return pCallbacks->VSyncCallbacks(ch, f);
}

void* StopCallback(void) { return pCallbacks->StopCallback(); }

void* RestartCallback(void) { return pCallbacks->RestartCallback(); }

int CheckCallback(void) { return intrEnv.inInterrupt; }

static volatile u16* i_mask = (u16*)0x1F801070;
static volatile u16* g_InterruptMask = (u16*)0x1F801074;
static volatile s32* d_pcr = (s32*)0x1F8010F0;

u16 GetIntrMask(void) { return *g_InterruptMask; }

u16 SetIntrMask(u16 arg0) {
u16 mask;

mask = *g_InterruptMask;
*g_InterruptMask = arg0;
return mask;
}

void* startIntr() {
if (intrEnv.interruptsInitialized != 0) {
return NULL;
}
*i_mask = *g_InterruptMask = 0;
*d_pcr = 0x33333333;
memclr(&intrEnv, sizeof(intrEnv) / sizeof(s32));
if (setjmp(intrEnv.temp.buf) != 0) {
trapIntr();
}
intrEnv.temp.buf[JB_SP] = (s32)&intrEnv.temp.stack[1004];
HookEntryInt((u16*)intrEnv.temp.buf);
intrEnv.interruptsInitialized = 1;
pCallbacks->VSyncCallbacks = startIntrVSync();
pCallbacks->DMACallback = startIntrDMA();
_96_remove();
ExitCriticalSection();
return &intrEnv;
}

static s32 D_8002D350 = 0;

void trapIntr() {
s32 i;
u16 mask;

if (intrEnv.interruptsInitialized == 0) {
printf("unexpected interrupt(%04x)\n", *i_mask);
ReturnFromException();
}
intrEnv.inInterrupt = 1;
mask = (intrEnv.enabledInterruptsMask & *i_mask) & *g_InterruptMask;
while (mask != 0) {
for (i = 0; mask && i < 11; ++i, mask >>= 1) {
if (mask & 1) {
*i_mask = ~(1 << i);
if (intrEnv.handlers[i] != NULL) {
intrEnv.handlers[i]();
}
}
}
mask = (intrEnv.enabledInterruptsMask & *i_mask) & *g_InterruptMask;
}
if (*i_mask & *g_InterruptMask) {
if (D_8002D350++ > 0x800) {
printf("intr timeout(%04x:%04x)\n", *i_mask, *g_InterruptMask);
D_8002D350 = 0;
*i_mask = 0;
}
} else {
D_8002D350 = 0;
}
intrEnv.inInterrupt = 0;
ReturnFromException();
}

Callback setIntr(s32 arg0, Callback arg1) {
Callback temp_s4;
u16 temp_v1;
s32 var_s3;

temp_s4 = intrEnv.handlers[arg0];
if ((arg1 != temp_s4) && (intrEnv.interruptsInitialized != 0)) {
temp_v1 = *g_InterruptMask;
*g_InterruptMask = 0;
var_s3 = temp_v1 & 0xFFFF;
if (arg1 != 0) {
intrEnv.handlers[arg0] = arg1;
var_s3 = var_s3 | (1 << arg0);
intrEnv.enabledInterruptsMask |= (1 << arg0);
} else {
intrEnv.handlers[arg0] = 0;
var_s3 = var_s3 & ~(1 << arg0);
intrEnv.enabledInterruptsMask &= ~(1 << arg0);
}
if (arg0 == 0) {
ChangeClearPAD(arg1 == 0);
ChangeClearRCnt(3, arg1 == 0);
}
if (arg0 == 4) {
ChangeClearRCnt(0, arg1 == 0);
}
if (arg0 == 5) {
ChangeClearRCnt(1, arg1 == 0);
}
if (arg0 == 6) {
ChangeClearRCnt(2, arg1 == 0);
}
*g_InterruptMask = var_s3;
}
return temp_s4;
}

void* stopIntr() {
if (intrEnv.interruptsInitialized == 0) {
return NULL;
}
EnterCriticalSection();
intrEnv.savedMask = *g_InterruptMask;
intrEnv.temp.savedPcr = *d_pcr;
*i_mask = *g_InterruptMask = 0;
*d_pcr &= 0x77777777;
ResetEntryInt();
intrEnv.interruptsInitialized = 0;
return &intrEnv;
}

void* restartIntr() {
if (intrEnv.interruptsInitialized != 0) {
return 0;
}

HookEntryInt((u16*)intrEnv.temp.buf);
intrEnv.interruptsInitialized = 1;
*g_InterruptMask = intrEnv.savedMask;
*d_pcr = intrEnv.temp.savedPcr;
ExitCriticalSection();
return &intrEnv;
}

void memclr(void* ptr, s32 size) {
s32 i;
s32* e = (s32*)ptr;

for (i = size - 1; i != -1; i--) {
*e = 0;
e++;
}
}

0 comments on commit 78fbe9e

Please sign in to comment.