Hi you guys.
It seems forever to me I didn't post here.
First of all, let me congratulate Kan and Steph' for making KMod 0.7 possible.
Here I am striking back. Your remember ? I want to use the 32X as a video card for the genny.
I use the Comm Port as a bus between the 2 systems :
Offset 0h : STATUS. Indicates the state of the Comm Port : who can write, who can read, ...
2h : CTRL. Tells the 32X what function to execute : empty the Frame Buffer, allocate a vertex, draw a triangle, ...
4h to Ch : DATA0 to DATA4. Used for the functions. You'd guess that a function drawing a triangle will need 3 vertex for the triangle to be drawn.
Eh : RESULT. Sometimes, the 32X can gives some results back. I don't see anything more than allocate : the 68k asks the 32X to allocate a vertex. The 32X gives the address back, so that 68k and 32X could speak of the same vertex.
The Comm Port has five states :
WRITE_ME. The 68k can write to the Comm Port.
WRITING. The 68k is writing to the Comm Port.
READ_ME. The Comm Port can be read by one SH2.
READING_M. The Master SH2 is reading the Comm Port.
READING_S. The Slave SH2 is reading the Comm Port.
Here's the code for the 68k to write something to the Comm Port :
Code: Select all
void putVDP(int ctrl, int data0, int data1, ...) {
while (COMM_PORT(STATUS) != WRITE_ME) ;
COMM_PORT(STATUS) = WRITING;
COMM_PORT(CTRL) = ctrl;
COMM_PORT(DATA0) = data0;
COMM_PORT(DATA1) = data1;
// wriesg others DATA
COMM_PORT(STATUS) = READ_ME;
}
Here's the code for the Master SH2 to read something from the Comm Port :
Code: Select all
void readVDP() {
int entrance = 1;
int instr;
int data0;
int data1;
/* Wait for READ_ME, than, wait for READING_M. Between READ_ME and
setting READING_M, the Slave SH2 may have written READING_S */
while (entrance | COMM_PORT(STATUS)==READING_M) {
entrance = 0;
while (COMM_PORT(STATUS) != READ_ME) ;
COMM_PORT(STATUS) = READING_M;
}
instr = COMM_PORT(CTRL);
data0 = COMM_PORT(DATA0);
data1 = COMM_PORT(DATA1);
// read others DATA
COMM_PORT(STATUS) = WRITE_ME;
}
I could do the same for the slave SH2, but I rather re-use this bit of code. It will help the lisibility and the maintainability of the program. I can tell each SH2 if it's Master of Slave. All I have to do, is set a bit that just them will know : in private Work RAM for example. So, I set the cache as 2 way, for each SH2, and, at their own C000 0000h, I write respectively READING_M and READING_S. In the ROM, at 3E0h and 3E4h, there are the Master and Slave Start Address. Here's a SH2 bootstrap :
Code: Select all
READING_M equ 3
READING_S equ 4
MASTER_INIT:
; set cache as 2way
MOV READ_STATUS,R1
MOV READING_M,@R1
BRA MAIN
SLAVE_INIT:
; set cache as 2way
MOV READ_STATUS,R1
MOV READING_S,@R1
BRA MAIN
READ_STATUS:
dc.l $C0000000
MAIN:
; 32X SH2 main code
The code for reading becomes, for each SH2 :
Code: Select all
void readVDP() {
int * READ_STATUS = (int *) 0xC0000000;
int entrance = 1;
int instr;
int data0;
int data1;
while (entrance | COMM_PORT(STATUS)==*READ_STATUS) {
entrance = 0;
while (COMM_PORT(STATUS) != READ_ME) ;
COMM_PORT(STATUS) = *READ_STATUS;
}
instr = COMM_PORT(CTRL);
data0 = COMM_PORT(DATA0);
data1 = COMM_PORT(DATA1);
// read others DATA
COMM_PORT(STATUS) = WRITE_ME;
}
Here it is. I think it's pretty fast. I don't know it the 32X still is efficient like this, and I don't even know if the 32X has already benn used like this. But I find it a little funny, so ... expect more to come soon. Actually, I just hope the synchronization (waiting, looking, ....) doesn't waste too much time. Wait and see, as everything that is written here just runs ... in my brain !
Oh, by the way. I can tell now that I know what the 32X is. It took me nearly 18 monthes between knowing what the genesis was, and having got some skills for develop ...