(Link to AcmlmWiki) Offline: thank ||bass
Register | Login
Views: 13,040,846
Main | Memberlist | Active users | Calendar | Chat | Online users
Ranks | FAQ | ACS | Stats | Color Chart | Search | Photo album
04-29-24 01:50 PM
0 users currently in ROM Hacking.
Acmlm's Board - I3 Archive - ROM Hacking - Question about an SPC instruction New poll | |
Add to favorites | Next newer thread | Next older thread
User Post
MathOnNapkins

1100

In SPC700 HELL


 





Since: 11-18-05

Last post: 6279 days
Last view: 6279 days
Posted on 02-03-06 08:30 AM Link | Quote
While I've been mostly able to follow SPC instructions either from finding a source or just intuitively, TCALL is bugging me. Since the documentation for the SPC's instruction set is poor, I was forced to consult a pdf reference manual for the GMS81508B (what an ugly name) Microcontroller. It's apparently somewhat similar in design, along with a few other chips I looked at. It says the following about TCALL:

Table Call (TCALL) causes the CPU to jump to each TCALL address, where it commences the execution of the service routine. The Table Call service area spaces 2-byte for every TCALL: $FFC0 for TCALL15, $FFC2 for
TCALL14, etc., as shown in Figure 8-7.

The opcode is X1, where X is the vector* to use. (01, 11, 21, ..., F1)
Basically it looks like a software interrupt similar to BRK on the 65816.

So far in the code I'm examining (The N-SPC) I have not hit a TCALL instruction. Here's what bothers me - $FFC0-$FFFF is used as the bootstramp ROM on the SPC-700. So it won't contain any vectors in that address space. So either 1. Nintendo didn't intend the SPC-700 to be used with this instruction or 2. The table for the vectors is located elsewhere. Entirely possible since it's a totally differen't chip from the GMS81508B.

* In this context, vector means a pointer to a special routine.
QBRADQ

Goomba


 





Since: 01-18-06
From: Eastern Oklahoma

Last post: 6630 days
Last view: 6630 days
Posted on 02-03-06 11:30 AM Link | Quote
*Warning: Over Confident Coder*

I'd put my money on the idea that the Big N's SPC does not support the interupt routines. And when you think about it, why would it? The SPC is itself controled via interupts from the main CPU.

We are talking about the SNES's sound processor right?

The SNES is a lot like the NES, right?

Maybe I should read more...

QBRADQ
MathOnNapkins

1100

In SPC700 HELL


 





Since: 11-18-05

Last post: 6279 days
Last view: 6279 days
Posted on 02-03-06 11:36 AM Link | Quote
The CPU communicates with the SPC via 4 I/O ports, not interrupts. .

The SNES is a lot like the NES, right?

In the area of sound processing, not even remotely close.

No offense, but I'd really like an answer from somebody who has coded or disassembled SPC code before.
Goplat
Newcomer


 





Since: 01-29-06

Last post: 6655 days
Last view: 6655 days
Posted on 02-03-06 01:24 PM Link | Quote
I looked at the Snes9x source code, and it does read the TCALL vector from $FFC0-$FFDF. It may not be entirely useless, however; Snes9x lets you swap the ROM in and out by writing a byte to $F1 with bit #$80 set. I don't know if the real SPC-700 does this; SPC-700 documentation is pretty rare.
d4s

Shyguy








Since: 12-01-05

Last post: 6402 days
Last view: 6299 days
Posted on 02-03-06 07:19 PM Link | Quote
i've written both a mod music player and a brr streamer for the spc, but never used and never cared about the tcall opcode.

i had a look at the official manual, but it didnt contain any info regarding the tcall instruction, apart from mentioning its existance.

checked out the sourcecode of the kankichi musicplayer (nintendos first musicplayer for the snes, coded in 1989 ), and it didnt make use of the tcall instruction, either.

just added a tcall instruction in my mod player to be 100% sure.
your document is indeed right.

it assumes the vector table to be located in the $ffc0-ffdf range.

i'm sure the spc wasnt designed to take advantage of it, because the area is obviously occupied by the ipl rom (at least at startup, you can disable the ipl rom to have access to the full 64kb ram), but it works.

however, i'd prefer a software jump table over that tcall stuff any day.

heres a small snippet of tcall in action:


FFF9 D0 DB BNE $FFD6 A:00 X:00 Y:00 S:EF P:nvpbhiZc 219l 1156l 1152l

;jumps to uploaded code here:
FFFB 1F 00 00 JMP ($0000+X) A:00 X:00 Y:00 S:EF P:nvpbhiZc 219l 1196l 1194l
0280 00 NOP A:00 X:00 Y:00 S:EF P:nvpbhiZc 219l 1330l 1320l
0281 20 CLRP A:00 X:00 Y:00 S:EF P:nvpbhiZc 219l 1366l 1362l

;fetches vector from $ffde here:
0282 01 TCALL0 A:00 X:00 Y:00 S:EF P:nvpbhiZc 220l 0038l 0036l
F5E4 FF STOP A:00 X:00 Y:00 S:ED P:nvpbhiZc 220l 0218l 0204l


(edited by d4s on 02-03-06 06:21 PM)
(edited by d4s on 02-03-06 06:22 PM)
(edited by d4s on 02-03-06 06:36 PM)
MathOnNapkins

1100

In SPC700 HELL


 





Since: 11-18-05

Last post: 6279 days
Last view: 6279 days
Posted on 02-03-06 09:43 PM Link | Quote
Ah, thanks for the confirmation of that. And by disable the ipl rom, you mean just write over it later on via the SPC itself? I mean, you can't do it during the initial data transfer b/c that is what is loading the data in the first place. And is this true what Goplat says about $00F1?

This is the best documentation I could find on that register. It's from SPC.log, from neviksti's starter kit, I believe.

$F1 SPCCON1 bits 0-2 timer enables (1=on), bits 4-5
are I/O port clear bits (11=clear all)

Doesn't even mention bit7, or bit6 or 3, for that matter.

The NSPC engine writes the value #$F0 to this register before starting its main execution loop. (It would of course happen again once you loaded a different bank of SPC Data.) Why would the programmer send data to bit 6 and 7 of register $00F1? The NSPC can load new data itself without using the ipl rom. Actually, when it does load new data through it's own routines, it does MOV $00F1, #$31 at the end, which makes more sense.
d4s

Shyguy








Since: 12-01-05

Last post: 6402 days
Last view: 6299 days
Posted on 02-06-06 03:35 PM Link | Quote
Originally posted by MathOnNapkins
Ah, thanks for the confirmation of that. And by disable the ipl rom, you mean just write over it later on via the SPC itself? I mean, you can't do it during the initial data transfer b/c that is what is loading the data in the first place. And is this true what Goplat says about $00F1?

This is the best documentation I could find on that register. It's from SPC.log, from neviksti's starter kit, I believe.

$F1 SPCCON1 bits 0-2 timer enables (1=on), bits 4-5
are I/O port clear bits (11=clear all)

Doesn't even mention bit7, or bit6 or 3, for that matter.

The NSPC engine writes the value #$F0 to this register before starting its main execution loop. (It would of course happen again once you loaded a different bank of SPC Data.) Why would the programmer send data to bit 6 and 7 of register $00F1? The NSPC can load new data itself without using the ipl rom. Actually, when it does load new data through it's own routines, it does MOV $00F1, #$31 at the end, which makes more sense.



thats a bit hard to answer.
the problem here is that the official nintendo documentation doesnt even mention that you can disable the ipl rom, so this isn't really confirmed.
appearently, bit 7 of register $f1 controls ipl enable toggle.

however, i wouldnt trust the emulators on that one.
snes9x for example lets you write to the ipl region no matter what the content of $f1 is. my wild guess would be that they just copy the ipl rom to that ram area at startup. thats not correct, of course.

i think i will test that on a real snes sometime in the future, i'll try to throw together some kind of spc memory viewer.

i've read that terranigma uses the tcall vector stuff, maybe have a look at that.


(edited by d4s on 02-06-06 02:36 PM)
(edited by d4s on 02-06-06 02:37 PM)
MathOnNapkins

1100

In SPC700 HELL


 





Since: 11-18-05

Last post: 6279 days
Last view: 6279 days
Posted on 02-07-06 07:48 AM Link | Quote
Well for the time being I'll just change it from #$F0 to #$30 in the binary and load it up on my SNES to see (hear) if it does anything notably different. It could be a complete mistake for all I know. But I agree, some testing and extended documenation are in order.
Goplat
Newcomer


 





Since: 01-29-06

Last post: 6655 days
Last view: 6655 days
Posted on 02-07-06 12:09 PM Link | Quote
Originally posted by d4s
snes9x for example lets you write to the ipl region no matter what the content of $f1 is. my wild guess would be that they just copy the ipl rom to that ram area at startup. thats not correct, of course.


It does let you write there any time, but your changes won't be visible until you disable the ROM. From apumem.h:

if (Address < 0xffc0)
    IAPU.RAM [Address] = byte;
else
{
    APU.ExtraRAM [Address - 0xffc0] = byte;
    if (!APU.ShowROM)
        IAPU.RAM [Address] = byte;
}


APU.ExtraRAM is the actual contents of FFC0-FFFF, IAPU.RAM is what's currently visible (when the ROM is enabled, it contains a copy of it; when the ROM is disabled, a copy of ExtraRAM)
byuu
Newcomer


 





Since: 01-11-06

Last post: 6534 days
Last view: 6534 days
Posted on 02-08-06 07:32 PM Link | Quote
Your assertions are correct, but I'll go ahead and post anyway because I'm bored.

[code]tcall_0(0x01, 0),
tcall_1(0x11, 1),
tcall_2(0x21, 2),
tcall_3(0x31, 3),
tcall_4(0x41, 4),
tcall_5(0x51, 5),
tcall_6(0x61, 6),
tcall_7(0x71, 7),
tcall_8(0x81, 8),
tcall_9(0x91, 9),
tcall_10(0xa1, 10),
tcall_11(0xb1, 11),
tcall_12(0xc1, 12),
tcall_13(0xd1, 13),
tcall_14(0xe1, 14),
tcall_15(0xf1, 15) {
1:dp = 0xffde - ($1 << 1);
rd = op_read(OPMODE_ADDR, dp);
2:rd |= op_read(OPMODE_ADDR, dp + 1) << 8;
3:
4:
5:
6:stack_write(regs.pc >> 8);
7:stack_write(regs.pc);
regs.pc = rd;
}[/code]

Fairly simple. There is 64kb of SPCRAM. A full 64kb, 0000-ffff.
There is also a 64-byte IPLROM. When enabled (via $f1 bit 7 being set), all reads from $ffc0-$ffff return the IPLROM data instead. Writes to this area go to the SPCRAM even with IPLROM enabled.

$00F1 - CONTROL
bit 7 - IPLROM enable (1=yes, 0=no)
bit 6 - no known effect
bit 5 - clear ports 2 and 3 (the APU will now read $00 from $f6 and $f7, the CPU will still have the old data on $2142 and $2143)
bit 4 - same as bit 5, but for ports 0 and 1
bit 3 - no known effect
bit 2-0 - timer 2, 1, 0 enable (1=yes, 0=no) -- writing 1 when the timer is disabled will reset the timer position

You want real fun, try figuring out what $00F0 - TEST does.

And no, snes9x didn't just decide to make up $f1 bit 7. A real SNES has IPLROM disable as well. Otherwise TCALL would be almost completely useless.
TCALL reads will read from the IPLROM with $f1.d7=1, by the way.
Add to favorites | Next newer thread | Next older thread
Acmlm's Board - I3 Archive - ROM Hacking - Question about an SPC instruction |


ABII

Acmlmboard 1.92.999, 9/17/2006
©2000-2006 Acmlm, Emuz, Blades, Xkeeper

Page rendered in 0.017 seconds; used 399.38 kB (max 494.06 kB)