32X SCI Use
Moderator: BigEvilCorporation
32X SCI Use
Has anyone written any code that works with the 32X SCI interfaces in the SH2? I've been bashing on some code for a few days now and haven't gotten anywhere. I want to send data from the master to the slave. It looks like the master side of things is working (at least, it doesn't seem to be locking up), but the slave is never receiving anything. It just spins waiting for RDRF to go to 1.
Looking at the Mars test ROM, it appears that it only receives by interrupt. I'm not using interrupts - only polling. Could that be it?
Which games use the SCI? Which emulators emulate it fully?
Looking at the Mars test ROM, it appears that it only receives by interrupt. I'm not using interrupts - only polling. Could that be it?
Which games use the SCI? Which emulators emulate it fully?
The 32X Hardware Manual (valpocl.com/SuperVDP/32x_hardware_manual.pdf) states :
The Hitachi SH2 Hardware Manual §13 will give you all the needed explainations. In particular, you won't be able to reach more than 150kb/s. If you have a large amount of data to send from one CPU to the other, you should use SCI Interrupt and transfer data via SDRAM.
(japanese roughly translated in english, I guess)Built-in SCI (Serial Communication I/F) :
SH2 has one SCI channel. In the 32X, the master and slave are connected to each other making serial communication possible. If data receive interrupt is used, timing is effective in severe cases. Data is set in the SDRAM described below and timing can be taken by SCI. Since the 32X is not equipped with any external clock source for the SH2 SCI, an internal clock must be selected. Otherwise any setting can be done.
The Hitachi SH2 Hardware Manual §13 will give you all the needed explainations. In particular, you won't be able to reach more than 150kb/s. If you have a large amount of data to send from one CPU to the other, you should use SCI Interrupt and transfer data via SDRAM.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
I haven't played around with the SCI since it's pretty worthless. Anything you can do with the SCI can be done easier and faster in a variety of other ways. For example, exchanging words via the communication registers in the 32X IO, or using blocks of uncached sdram. About the only useful thing the SCI can do is trigger an interrupt in the other SH2... after some latency due to the serial transmission of data.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
A little more on that... if you had a fully interrupt-driven cross processor communication handler for your program, the SCI would be your way to generate an int. However, that level of multi-processor communications is not really needed to make the 32X useful. You don't gain anything by making an SH2 wait on an interrupt compared to checking a communication register in the system regs. I don't even bother making the 68000 wait on ints as I normally have it running from work ram to keep it off the bus.ob1 wrote:+1Chilly Willy wrote:About the only useful thing the SCI can do is trigger an interrupt in the other SH2
It's simple and easy to make the Master SH2 watch one set of comm regs, the Slave watch another, and the 68000 yet another. The comm regs (being in the system regs) are uncached, so you don't need to worry about cache issues; they're also much faster to read than a corresponding sdram location due to burst read hardware. The 32X is hardwired to do burst reads on the sdram, and single writes. That means a read of 8 words (one cache line) is done in 12 cycles, or 1.5 cycles per word. However, even when reading a single word that is uncached, it still does a burst read - 8 words are read in 12 cycles, and the other 7 are tossed out. So reading an uncached word in sdram is the slowest thing you can do on the SH2s. You'd be better off putting the variable in vram than sdram! Keeping in mind the burst reads on the SH2 is one of the key things to remember when designing code for the 32X when trying to get as much speed as possible. Note, the DMA in the SH2 can use this burst mode when put in 16-byte mode. If you're trying to get the best speed from DMA, put the source data on 16 byte boundaries, and use the 16 byte transfer word size.
Re: 32X SCI Use
All right, by looking into Sega SDK\SEGADTS\32X\DEMO\SOJ_32X, I could achieve something (well, I sent a byte from Master to Slave on real Hardware).
Here's the stuff:
with
Then, on the slave side :
Now, for sending, from the Master:
Finally, for the Slave to receive :
As you can see, I don't bother with ORER, but it was just a quick and dirty test.
Truth is, it's a lot of hassle (not very well emulated, not very well documented), for not so much of a result.
Here's the stuff:
Code: Select all
initMaster:
* ...
MOV #$80,R4
MOV #74,R5
MOV #$20,R6 ; TE | SCK is output
BSR initSci
NOP
* ...
Code: Select all
initSci:
* IN R4 SMR
* R5 BRR
* R6 SCR
STS.L PR,@-R15
MOV.L R0,@-R15
MOV.L R1,@-R15
MOV.W !SCI_REGS,R1
MOV #0,R0
MOV.B R0,@(2,R1) ; Clear TE and RE bits in SCR to 0
MOV R4,R0 ; C//A | CKS0
MOV.B R0,@R1 ; Set SMR
MOV R5,R0
MOV.B R0,@(1,R1) ; Set BRR
MOV #0,R0
MOV.B R0,@(2,R1) ; Clear SCR
MOV R5,R0
SHLL2 R0
!waitABit:
NOP
DT R0
BF !waitABit
MOV R6,R0
MOV.B R0,@(2,R1) ; Set SCR
MOV.L @R15+,R1
MOV.L @R15+,R0
LDS.L @R15+,PR
RTS
NOP
!SCI_REGS DC.W $FE00
Code: Select all
initSlave:
* ...
MOV #$80,R4
MOV #74,R5
MOV #$12,R6 ; RE | SCK is input
BSR initSci
NOP
* ...
Code: Select all
send:
* IN R4 data
STS.L PR,@-R15
MOV.L R0,@-R15
MOV.L R1,@-R15
MOV.W !SCI_REGS,R1
!waitForTDRESet:
mov.b @(4,r1),r0
tst #%10000000,r0 ; if (TDRE == 0), 1 -> T
bt !waitForTDRESet
mov r4,r0
mov.b r0,@(3,r1)
!waitForTENDSet:
mov.b @(4,r1),r0
tst #%00000100,r0 ; if (TEND == 0), 1 -> T
bt !waitForTENDSet
mov #0,r0
mov.b r0,@(4,r1) ; Clear SSR
MOV.L @R15+,R1
MOV.L @R15+,R0
LDS.L @R15+,PR
RTS
NOP
!SCI_REGS DC.W $FE00
Finally, for the Slave to receive :
Code: Select all
receive:
* OUT R0 data
STS.L PR,@-R15
MOV.L R1,@-R15
MOV.L R2,@-R15
MOV.W !SCI_REGS,R1
mov #%00010000,r0
mov.b r0,@(2,r1) ; Set RE
mov.b @(4,r1),r0
tst #%01000000,r0 ; if (RDRF == 0), 1 -> T
bt !noData
mov.b @(5,r1),r0 ; Read RDR
MOV R0,R2
mov #0,r0
mov.b r0,@(4,r1) ; Clear SSR
mov.b r0,@(2,r1) ; Clear SCR, Reset RE
MOV R2,R0
!epilog:
MOV.L @R15+,R2
MOV.L @R15+,R1
LDS.L @R15+,PR
RTS
NOP
!SCI_REGS DC.W $FE00
!noData:
MOV #-2,R0
BRA !epilog
NOP
Truth is, it's a lot of hassle (not very well emulated, not very well documented), for not so much of a result.