Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
1 user currently in Rom Hacking: hukka | 2 guests
Acmlm's Board - I2 Archive - Rom Hacking - SPC bootstrap rom | |
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
User Post
MathOnNapkins

Math n' Hacks
Level: 67

Posts: 1967/2189
EXP: 2495887
For next: 96985

Since: 03-18-04
From: Base Tourian

Since last post: 1 hour
Last activity: 32 min.
Posted on 06-11-05 11:43 AM Link | Quote
I was looking through the snes9x source code when I happened upon the rom that the SPC boots up with. I decided to try to convert it to assembly code, in spite never having looked at SPC700 asm before O_o. ouch.... here goes


//added by MONapkins
/* above rom reads in spc opcodes:

MOV X, #$EF
MOV SP, X // the stack is at $EF

LOOPBACK:

MOV A, #$00
MOV (X), A // zero out $01 through $EF
DEC X

BNE #$FC (LOOPBACK)

MOV $F4, #$AA // #$BBAA is the classic value you see on the 65816
MOV $F5, #$BB // side of things, indicating the SPC is "ready"

LOOPBACK2:

CMP $F4, #$CC // another value seen on the 65816 side, when preparing to send data. As I recall, this value is fed from the 65816 side through the $F4 port.

BNE #$FB (LOOPBACK2) // Hence, until we receive that message, we do nothing.

BRA #$19 (BRANCH2)

LOOPBACK3:

MOV Y, $F4 // put that lower byte in Y

BNE $FC (LOOPBACK3) // maybe an internal process insures $F4 will drop down to zero. Otherwise this is an infinite loop.

LOOPBACK4:

CMP Y, $F4

BNE #$0B (BRANCH1)

MOVZ A, $F5
MOV $F4, Y
MOV [$00+Y], A
INC Y

BNE #$F3 (LOOPBACK4)

INCZ $01 // again, you got me on the specification here.

BRANCH1:

BPL #$EF (LOOPBACK4)

CMP Y, $F4

BPL #$EB (LOOPBACK4)

BRANCH2:

MOVW YA, $F6 // move a word of data received from the 65816 ($2142-3)
MOVW $00, YA // move it to $00-$01
MOVW YA, $F4 // check the word on the other port.
MOVZ $F4, A // it's called MOV with zero extended, but I'm not sure what exactly that means. Maybe it erases the upper byte, i.e. $F5
MOV A, Y //
MOV X, A // chain along the upper byte to X

BNE #$DB (LOOPBACK3) // if it wasn't 0, loop back and do some stuff

JMP [$0000+X]

DI // no fricken clue...

STOP
*/


for posterity I will also provide the data in the globals.cpp file

uint8 APUROM [64] =
{
0xCD,0xEF,0xBD,0xE8,0x00,0xC6,0x1D,0xD0,0xFC,0x8F,0xAA,0xF4,0x8F,0xBB,0xF5,0x78,
0xCC,0xF4,0xD0,0xFB,0x2F,0x19,0xEB,0xF4,0xD0,0xFC,0x7E,0xF4,0xD0,0x0B,0xE4,0xF5,
0xCB,0xF4,0xD7,0x00,0xFC,0xD0,0xF3,0xAB,0x01,0x10,0xEF,0x7E,0xF4,0x10,0xEB,0xBA,
0xF6,0xDA,0x00,0xBA,0xF4,0xC4,0xF4,0xDD,0x5D,0xD0,0xDB,0x1F,0x00,0x00,0xC0,0xFF
};

So anyways, just out of curiosity, anybody know what MOVZ and DI are for? I've read some docs on MOVZ, but it's a little unclear. And DI is on the SPC700 opcode list, but I can't figure out what it does from any source I've seen.


(edited by MathOnNapkins on 06-10-05 08:40 PM)
neviksti

Goomba
Level: 8

Posts: 3/25
EXP: 1510
For next: 677

Since: 06-09-05

Since last post: 36 days
Last activity: 30 days
Posted on 06-11-05 03:01 PM Link | Quote
The MOVZ and INCZ aren't part of the "standard" spc700 opcode list that I am used to. What did you use to disassemble it? (Or where did you get the list of opcodes if you did it by hand?)

Anyway, it appears they are using "Z" to denote "byte" (as opposed to the MOVW opcode, etc). Also, the ending of the boot rom isn't code, it's just the reset vector. So don't worry about trying to interpret that.

Anyway, here is the code I commented up for myself:

Start:
MOV X, #$EF ;setup the stack to 0x01EF
MOV SP, X

MOV A, #$00 ;Note: on reset DP=0
ClearLoop:
MOV (X), A ;save $00 --> 0x0001 - 0x00EF
DEC X ;
BNE ClearLoop ;

MOV $AA, #$F4 ;make initial value port $F4 = 0xAA
MOV $BB, #$F5 ;make initial value port $F5 = 0xBB
WaitForInit:
CMP $CC, #$F4 ;Is there a 0xCC on port $F4?
BNE WaitForInit ; no -> look again
BRA StartBlock ; yes -> goto StartBlock

GetMem:
MOV Y, $F4 ;wait for $F4 to be set to zero, saying that the first byte is ready
BNE GetMem ;if $F4 != 0x00 goto GetMem
NextByte:
CMP Y, $F4 ;Y = current count, $F4 tells current data byte # that is on $F5
BNE Blah ;if the byte we need isn't there yet, goto Blah
MOV A, $F5 ; get data
MOV $F4, Y ; echo count
MOV [$00]+Y, A ; store data
INC Y ; count++
BNE NextByte ; if count didn't roll over then goto NextByte
INC $01 ; else increase the address pointer (the high byte)
Blah:
BPL NextByte ;=blah= if >= 0 goto NextByte
CMP Y, $F4 ;
BPL NextByte ;if Y >= $F4 goto NextByte

StartBlock:
MOVW YA, $F6 ;get address from $F6-$F7 (2142H-2143H from SNES side)
MOVW $00, YA ; store address at 0x0000-0x0001
MOVW YA, $F4 ; read $F4-$F5
MOV $F4, A ;echo the $F4 read, back into $F4 (tell SNES we got the value)

MOV A, Y ;
MOV X, A ; put $F5 into x
BNE GetMem ; if $F5 != $#00, then this isn't the terminal block, goto "GetMem"

JMP [$0000+X] ;run program...

ResetVector:
.dw $FFC0



Edit: grr... the board keeps clipping my post (the lines don't wrap around). Should I
not be using "pre" tags? It seems to mess everything up after it, even though I've
closed the tag. Oh well, for now I'll just manually enter the line breaks.

Edit: The point of the "blah" section is to check if the bootstrap is being signalled
to move onto the next block (this is done by changing the counter by more than 1,
ie not just incrementing it). As I said, the above is just comments I wrote for
myself ... so you may want to comment it up yourself for it to be more useful.

Hope it helps though.


(edited by neviksti on 06-10-05 10:07 PM)
(edited by neviksti on 06-10-05 10:10 PM)
(edited by neviksti on 06-10-05 10:11 PM)
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
Acmlm's Board - I2 Archive - Rom Hacking - SPC bootstrap rom | |


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.013 seconds.