Master SH2 BIOS

Ask anything your want about the 32X Mushroom programming.

Moderator: BigEvilCorporation

Post Reply
ob1
Very interested
Posts: 463
Joined: Wed Dec 06, 2006 9:01 am
Location: Aix-en-Provence, France

Master SH2 BIOS

Post by ob1 » Fri Jan 26, 2007 3:58 pm

Here's a disassembly of the Master SH2 BIOS :

Code: Select all

	org	$0
* VBR
	dc.l	reset		; 0: POWER ON RESET PC
	dc.l	0x06040000	; 1: POWER ON RESER SP
	dc.l	reset		; 2: MANUAL RESET PC
	dc.l	0x06040000	; 3: MANUAL RESET SP
	dc.l	forever		; 4: GENERAL ILLEGAL INSTRUCTION
	dc.l	0x00000000	; 5: SEGA RESERVED
	dc.l	forever		; 6: SLOT ILLEGAL INSTRUCTION
	dc.l	0x20100400	; 7: SEGA RESERVED
	dc.l	0x20100420	; 8: SEGA RESERVED
	dc.l	forever		; CPU ADDRESS ERROR
	dc.l	forever		; DMA ADDRESS ERROR
	dc.l	forever		; NMI INTERRUPT
	dc.l	forever		; USER BREAK INTERRUPT

	org	$34
* 76 bytes, SEGA Reserved
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0

	org	$80
* CPU Traps
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever,forever

	org	$100
* INT
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever,forever

	org	$120
* Peripherals
	dc.l	forever,forever,forever,forever
	dc.l	forever,forever,forever

	org	$13C
forever:
0x0000013C: 0xAFFE		bra	0x0000013C
0x0000013E: 0x0009		nop

	org	$140
reset:
0x00000140: 0xD01A		mov.l	@(0x06C, pc), r0	; @0x000001AC = $000000F0
0x00000142: 0x400E		ldc	r0, sr			; Set Interrupt Mask Bits

GPRInit:
0x00000144: 0xE000		mov	#0x00, r0
0x00000146: 0xE100		mov	#0x00, r1
0x00000148: 0xE200		mov	#0x00, r2
0x0000014A: 0xE300		mov	#0x00, r3
0x0000014C: 0xE400		mov	#0x00, r4
0x0000014E: 0xE500		mov	#0x00, r5
0x00000150: 0xE600		mov	#0x00, r6
0x00000152: 0xE700		mov	#0x00, r7
0x00000154: 0xE800		mov	#0x00, r8
0x00000156: 0xE900		mov	#0x00, r9
0x00000158: 0xEA00		mov	#0x00, r10
0x0000015A: 0xEB00		mov	#0x00, r11
0x0000015C: 0xEC00		mov	#0x00, r12
0x0000015E: 0xED00		mov	#0x00, r13
0x00000160: 0xEE00		mov	#0x00, r14

BusStateCtrlInit:
0x00000162: 0xD86F		mov.l	@(0x1C0, pc), r8	; 0x00000320 ; r8 = $00000348
0x00000164: 0xD96F		mov.l	@(0x1C0, pc), r9	; 0x00000324 ; r9 = $FFFFFFE0		Bus Control Register 1
0x00000166: 0x6086		mov.l	@r8+, r0		; r0 = $00000348, r8 = $0000034C
0x00000168: 0x1900		mov.l	r0, @(0x000, r9)	; 
0x0000016A: 0x6086		mov.l	@r8+, r0
0x0000016C: 0x1901		mov.l	r0, @(0x004, r9)	; Bus Control Register 2
0x0000016E: 0x6086		mov.l	@r8+, r0
0x00000170: 0x1902		mov.l	r0, @(0x008, r9)	; Wait Control Register
0x00000172: 0x6086		mov.l	@r8+, r0
0x00000174: 0x1903		mov.l	r0, @(0x00C, r9)	; Memory Control Register
0x00000176: 0x6086		mov.l	@r8+, r0
0x00000178: 0x1904		mov.l	r0, @(0x010, r9)	; Refresh Timer Control / Status Register
0x0000017A: 0x6086		mov.l	@r8+, r0
0x0000017C: 0x1905		mov.l	r0, @(0x014, r9)	; Refresh Timer Counter
0x0000017E: 0x6086		mov.l	@r8+, r0
0x00000180: 0x1906		mov.l	r0, @(0x018, r9)	; Refresh Timer Constant Register

SDRAMMode:
0x00000182: 0xDE66		mov.l	@(0x19C, pc), r14	; 0x0000031C	r14 = $20004000
0x00000184: 0x4E1E		ldc	r14, gbr		; GBR = $20004000
0x00000186: 0xD877		mov.l	@(0x1E0, pc), r8	; 0x00000364, r8 = $FFFF8446
0x00000188: 0xE000		mov	#0x00, r0
0x0000018A: 0x2801		mov.w	r0, @r8			; Set CAS Latency to 2

InterruptMaskTest:
0x0000018C: 0xC400		mov.b	@(0x000, gbr), r0	; r0 = $20004000, SH2 Interrupt Mask Register
0x0000018E: 0xC802		tst	#0x02, r0		; if (Command Interrupt Mask is mask) {
0x00000190: 0x8B10		bf	0x000001B4
waitFor64kCycles:
0x00000192: 0xD007		mov.l	@(0x020, pc), r0	; 	int i = 0x00010000;
0x00000194: 0xE101		mov	#0x01, r1		; 	int j = 1;
0x00000196: 0x3018		sub	r1, r0			; 	i = i - j;
0x00000198: 0x8800		cmp/eq	#0x00, r0		; 	while (i>0) ;
0x0000019A: 0x8BFC		bf	0x00000196		; }

0x0000019C: 0xC101		mov.w	r0, @(0x002, gbr)	; ???
0x0000019E: 0xD863		mov.l	@(0x190, pc), r8	; 0x0000032C, r8 = $FFFFFE91	Standby Control Register
0x000001A0: 0xE09F		mov	#0x9F, r0
0x000001A2: 0x2800		mov.b	r0, @r8
0x000001A4: 0x001B		sleep
0x000001A6: 0xAFFE		bra	0x000001A6
0x000001A8: 0x0009		nop
	dc.w	$0		padder

	org	$1AC
	dc.l	$000000F0	Status Interrupt Mask bits
	dc.l	$00010000

CacheInit:
0x000001B4: 0xD85D		mov.l	@(0x178, pc), r8	; 0x0000032C, r8 = $FFFFFE91	Standby Control Register
0x000001B6: 0xE000		mov	#0x00, r0
0x000001B8: 0x2800		mov.b	r0, @r8
0x000001BA: 0xD95B		mov.l	@(0x170, pc), r9	; 0x00000328, r9 = $FFFFFE92	Cache Control Register
0x000001BC: 0xE011		mov	#0x11, r0
0x000001BE: 0x2900		mov.b	r0, @r9			; Cache Purge, Cache Enabled, 4-way

SDRAMInit:
0x000001C0: 0xD860		mov.l	@(0x184, pc), r8	; 0x00000344, r8 = $26040000
0x000001C2: 0xD95F		mov.l	@(0x180, pc), r9	; 0x00000340, r9 = $26000000
0x000001C4: 0xE000		mov	#0x00, r0
0x000001C6: 0x2805		mov.w	r0, @-r8
0x000001C8: 0x7001		add	#0x01, r0
0x000001CA: 0x2805		mov.w	r0, @-r8
0x000001CC: 0x7001		add	#0x01, r0		; SDRAM = $0000, $0001, $0002, ...
0x000001CE: 0x2805		mov.w	r0, @-r8
0x000001D0: 0x7001		add	#0x01, r0
0x000001D2: 0x2805		mov.w	r0, @-r8
0x000001D4: 0x7001		add	#0x01, r0
0x000001D6: 0x3980		cmp/eq	r8, r9
0x000001D8: 0x8BF5		bf	0x000001C6

SDRAMCheck:
0x000001DA: 0xD85A		mov.l	@(0x16C, pc), r8	; 0x00000344, r8 = $26040000
0x000001DC: 0xD958		mov.l	@(0x164, pc), r9	; 0x00000340, r9 = $26000000
0x000001DE: 0xE000		mov	#0x00, r0
0x000001E0: 0xE102		mov	#0x02, r1
0x000001E2: 0xE201		mov	#0x01, r2
0x000001E4: 0xD305		mov.l	@(0x018, pc), r3	; 0x000001FC, r3 = $0000FFFF
0x000001E6: 0x3818		sub	r1, r8
0x000001E8: 0x6481		mov.w	@r8, r4
0x000001EA: 0x2439		and	r3, r4
0x000001EC: 0x2039		and	r3, r0
0x000001EE: 0x3400		cmp/eq	r0, r4
0x000001F0: 0x8B06		bf	0x00000200
0x000001F2: 0x7001		add	#0x01, r0
0x000001F4: 0x3980		cmp/eq	r8, r9
0x000001F6: 0x8BF6		bf	0x000001E6
0x000001F8: 0xA008		bra	0x0000020C
0x000001FA: 0x0009		nop

	org	$1FC
	dc.l	$0000FFFF

SDRAMError:
0x00000200: 0xD001		mov.l	@(0x008, pc), r0	; 0x00000208, r0 = 'SDER'
0x00000202: 0xC208		mov.l	r0, @(0x020, gbr)	; Communication Port
0x00000204: 0xAFFC		bra	0x00000200
0x00000206: 0x0009		nop

	org	$208
	dc.l	$53444552	; SDER SDRAM Check Error

SDRAMClear:
0x0000020C: 0xD84D		mov.l	@(0x138, pc), r8	; 0x00000344, r8 = $26040000
0x0000020E: 0xD94C		mov.l	@(0x134, pc), r9	; 0x00000340, r9 = $26000000
0x00000210: 0xE000		mov	#0x00, r0
0x00000212: 0x2806		mov.l	r0, @-r8
0x00000214: 0x2806		mov.l	r0, @-r8
0x00000216: 0x2806		mov.l	r0, @-r8
0x00000218: 0x2806		mov.l	r0, @-r8
0x0000021A: 0x3980		cmp/eq	r8, r9
0x0000021C: 0x8BF9		bf	0x00000212

PWMMaskTest:
0x0000021E: 0xC400		mov.b	@(0x000, gbr), r0
0x00000220: 0xC801		tst	#0x01, r0
0x00000222: 0x8B59		bf	0x000002D8
0x00000224: 0xDD43		mov.l	@(0x110, pc), r13	; 0x00000334, r13 = $22000400
0x00000226: 0xDC06		mov.l	@(0x01C, pc), r12	; 0x00000240, r12 = $0000036C
0x00000228: 0xDB06		mov.l	@(0x01C, pc), r11	; 0x00000244, r11 = $0000076C
InitialProgramCheck:
0x0000022A: 0x67C5		mov.w	@r12+, r7		; r7 = $46FC, r12 = $0000036E
0x0000022C: 0x607D		extu.w	r7, r0			; r0 = $000046FC
0x0000022E: 0x66D5		mov.w	@r13+, r6		; r6 = $46FC, read from cartridge, r13 = $22000402
0x00000230: 0x616D		extu.w	r6, r1			; r1 = $000046FC
0x00000232: 0x3100		cmp/eq	r0, r1
0x00000234: 0x8B08		bf	0x00000248		; Ensure the Intial Program is present
0x00000236: 0x3BC0		cmp/eq	r12, r11
0x00000238: 0x8BF7		bf	0x0000022A
0x0000023A: 0xA00D		bra	0x00000258
0x0000023C: 0x0009		nop
0x0000023E: 0x0000		unrecognized

	org	$240
	dc.l	$0000036C
	dc.l	$0000076C

InitialProgramError:
0x00000248: 0xD002		mov.l	@(0x00C, pc), r0	; 0x00000254, r0 = 'SQER'
0x0000024A: 0xC208		mov.l	r0, @(0x020, gbr)	; Communication Port
0x0000024C: 0xE080		mov	#0x80, r0
0x0000024E: 0xC000		mov.b	r0, @(0x000, gbr)	; VDP access to Megadrive only
0x00000250: 0xAFFA		bra	0x00000248
0x00000252: 0x0009		nop

	org	$254
	dc.l	$53514552	; SQER Security Code Mismatch

ChecksumCompute:
0x00000258: 0xD816		mov.l	@(0x05C, pc), r8	; 0x000002B4, r8 = $22000200
0x0000025A: 0xD917		mov.l	@(0x060, pc), r9	; 0x000002B8, r9 = $2200018E Checksum
0x0000025C: 0x6191		mov.w	@r9, r1
0x0000025E: 0x601D		extu.w	r1, r0
0x00000260: 0x8800		cmp/eq	#0x00, r0
0x00000262: 0x890F		bt	0x00000284		; if cheksum is not null {
0x00000264: 0xD915		mov.l	@(0x058, pc), r9	; 0x000002BC, r9 = $220001A4
0x00000266: 0x6792		mov.l	@r9, r7			; r7 = End of ROM
0x00000268: 0xD015		mov.l	@(0x058, pc), r0	; 0x000002C0, r0 = $00000200
0x0000026A: 0x3708		sub	r0, r7
0x0000026C: 0x4701		shlr	r7
0x0000026E: 0xD115		mov.l	@(0x058, pc), r1	; 0x000002C4, r1 = $003FFFFF
0x00000270: 0x2719		and	r1, r7
0x00000272: 0x7701		add	#0x01, r7
0x00000274: 0xE000		mov	#0x00, r0
0x00000276: 0xD314		mov.l	@(0x054, pc), r3	; 0x000002C8, r3 = $0000FFFF
ChecksumLoop:
0x00000278: 0x6285		mov.w	@r8+, r2
0x0000027A: 0x2239		and	r3, r2
0x0000027C: 0x302C		add	r2, r0
0x0000027E: 0x2039		and	r3, r0
0x00000280: 0x4710		dt	r7
0x00000282: 0x8BF9		bf	0x00000278

CopyCartridgeIntoSDRAM:
0x00000284: 0xC114		mov.w	r0, @(0x028, gbr)
0x00000286: 0xDD2A		mov.l	@(0x0AC, pc), r13	; 0x00000330, r13 = $220003D4
0x00000288: 0x68D6		mov.l	@r13+, r8		; r8 = Source from cartridge
0x0000028A: 0x69D6		mov.l	@r13+, r9		; r9 = Destination from cartridge
0x0000028C: 0x60D6		mov.l	@r13+, r0		; r0 = Size from cartridge
0x0000028E: 0xD10F		mov.l	@(0x040, pc), r1	; 0x000002CC, r1 = $22000000
0x00000290: 0x381C		add	r1, r8
0x00000292: 0xD10F		mov.l	@(0x040, pc), r1	; 0x000002D0, r1 = $06000000
0x00000294: 0x391C		add	r1, r9
0x00000296: 0xE204		mov	#0x04, r2
CopyCartridgeIntoSDRAMLoop:
0x00000298: 0x6186		mov.l	@r8+, r1
0x0000029A: 0x2912		mov.l	r1, @r9
0x0000029C: 0x7904		add	#0x04, r9
0x0000029E: 0x3028		sub	r2, r0
0x000002A0: 0x8800		cmp/eq	#0x00, r0
0x000002A2: 0x8BF9		bf	0x00000298

0x000002A4: 0x50D2		mov.l	@(0x008, r13), r0	; r0 = Master SH2 VBR from cartridge
0x000002A6: 0x402E		ldc	r0, vbr
0x000002A8: 0x68D2		mov.l	@r13, r8		; r8 = Master SH2 Start Address from cartridge
0x000002AA: 0xD00A		mov.l	@(0x02C, pc), r0	; Put M_OK on CommPort($20)
0x000002AC: 0xC208		mov.l	r0, @(0x020, gbr)	
0x000002AE: 0x482B		jmp	@r8
0x000002B0: 0x0009		nop
0x000002B2: 0x0000		unrecognized

	org	$2B4
	dc.l	$22000200
	dc.l	$2200018E
	dc.l	$220001A4
	dc.l	$00000200
	dc.l	$003FFFFF
	dc.l	$0000FFFF
	dc.l	$22000000
	dc.l	$06000000
	dc.l	$4D5F4F4B	; M_OK


0x000002D8: 0xD123		mov.l	@(0x090, pc), r1	; 0x00000368, r1 = '_CD_'
0x000002DA: 0xC608		mov.l	@(0x020, gbr), r0	; while (CommPort($20)!='_CD_') ;
0x000002DC: 0x3100		cmp/eq	r0, r1
0x000002DE: 0x8BFC		bf	0x000002DA

* Request FrameBuffer Access
0x000002E0: 0xE080		mov	#0x80, r0
0x000002E2: 0xC000		mov.b	r0, @(0x000, gbr)
0x000002E4: 0xC400		mov.b	@(0x000, gbr), r0
0x000002E6: 0xC880		tst	#0x80, r0
0x000002E8: 0x89FC		bt	0x000002E4

* Copy Frame Buffer into SDRAM ???
0x000002EA: 0xD813		mov.l	@(0x050, pc), r8	; 0x00000338, r8 = $24000018
0x000002EC: 0x5980		mov.l	@(0x000, r8), r9	; r9 = $24000018
0x000002EE: 0x5081		mov.l	@(0x004, r8), r0	; r0 = $2400001C
0x000002F0: 0x5A82		mov.l	@(0x008, r8), r10	; r10 = $24000020
0x000002F2: 0x5B84		mov.l	@(0x010, r8), r11	; r11 = $24000028
0x000002F4: 0x7820		add	#0x20, r8		; r8 = $24000038
0x000002F6: 0xD311		mov.l	@(0x048, pc), r3	; 0x0000033C, r3 = $0001FFE0
0x000002F8: 0xE400		mov	#0x00, r4
0x000002FA: 0xE204		mov	#0x04, r2
0x000002FC: 0x6186		mov.l	@r8+, r1		; r1 = $4AAD008 from cartridge ???
0x000002FE: 0x2912		mov.l	r1, @r9
0x00000300: 0x7904		add	#0x04, r9
0x00000302: 0x3028		sub	r2, r0
0x00000304: 0x3328		sub	r2, r3
0x00000306: 0x3340		cmp/eq	r4, r3
0x00000308: 0x8901		bt	0x0000030E
0x0000030A: 0x8800		cmp/eq	#0x00, r0
0x0000030C: 0x8BF6		bf	0x000002FC
0x0000030E: 0xD002		mov.l	@(0x00C, pc), r0	; 0x00000318, r0 = 'M_OK'
0x00000310: 0xC208		mov.l	r0, @(0x020, gbr)
0x00000312: 0x4B2E		ldc	r11, vbr
0x00000314: 0x4A2B		jmp	@r10
0x00000316: 0x0009		nop

	org	$318
	dc.l	$4D5F4F4B	; M_OK
	dc.l	$20004000
	dc.l	$00000348
	dc.l	$FFFFFFE0
	dc.l	$FFFFFE92
	dc.l	$FFFFFE91
	dc.l	$220003D4
	dc.l	$220003D4
	dc.l	$22000400
	dc.l	$24000018
	dc.l	$0001FFE0
	dc.l	$26000000
	dc.l	$26040000
	dc.l	$A55A0001
	dc.l	$A55A00A8
	dc.l	$A55A0055
	dc.l	$A55A0AB8
	dc.l	$A55A0008
	dc.l	$A55A0000
	dc.l	$A55A0059
	dc.l	$FFFF8446
	dc.l	$5F43445F	; _CD_

	org	$36C
	incbin	"ip.bin"

0x0000076C: 0xFFFF		unrecognized
...
0x000007FE: 0xFFFF		unrecognized
ip.bin is the initial program you'd find in the cartridge from $400 to $800.

Not very useful. Except for history.

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Fri Jan 26, 2007 5:02 pm

Great :) I think i already saw the disasm somewhere ;)

"0x0000018A: 0x2801 mov.w r0, @r8 ; Set CAS Latency to 2 "
Umm? You can change CAS speed? Doesn't this involve the DRAM writting speed?

ob1
Very interested
Posts: 463
Joined: Wed Dec 06, 2006 9:01 am
Location: Aix-en-Provence, France

Post by ob1 » Fri Jan 26, 2007 5:49 pm

Not change, but set.
The 7604 Hardware Manual states in £7.5.8 (Power-On Sequence) that CAS latency must be set before any CS0 access. So you've got to write something (any data) to register :
- FFFF 8426h for CAS latency 1, 16 bits
- FFFF 8446h for CAS latency 2, 16 bits
- FFFF 8466h for CAS latency 3, 16 bits
- FFFF 8848h for CAS latency 1, 32 bits
- FFFF 8888h for CAS latency 2, 32 bits
- FFFF88C8h for CAS latency 3, 32 bits

I think this setting can not be change once set.

I think I see where you wanna go, but I'd be doubtful about "overclocking" SDRAM. Do we know what memory chips is into 32x ? Especially wait time and CAS. But I'm pretty damn sure they won't go under CAS 2.

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Fri Jan 26, 2007 7:57 pm

Yeah, but i think it have something to do with the latency that let "both SH to access at same time" (of course they don't access exactly at same time)...

If you work with only one SH2 (and through the SH2 cached area maybe?) maybe it is possible to set faster DRAM?

Haha, i'm dreaming but it is simply wierd we can select this value :)

Remember, the main problem with 32x is the DRAM / VRAM speed... Eats up to 6cycles in write mode if i'm not wrong ;) So any improvement/trick would be welcome :D

ob1
Very interested
Posts: 463
Joined: Wed Dec 06, 2006 9:01 am
Location: Aix-en-Provence, France

Post by ob1 » Fri Jan 26, 2007 11:02 pm

Fonzie wrote:the main problem with 32x is the DRAM / VRAM speed...
Are you sure the SDRAM speed, or FB speed is the main problem ? I would have guessed some missings features were much more a concern : no fill polygon, no scroll no scaling/rotation/distortion ... no hardware graphics function.

Anyway, there are several ways to improve memory speed :
- use 2way cache to create a dedicaced RAM area in the CPU
- use cache to improve acces time and rate
- use DMA to improve rate (not access time, obviously)

ob1
Very interested
Posts: 463
Joined: Wed Dec 06, 2006 9:01 am
Location: Aix-en-Provence, France

Post by ob1 » Fri Jan 26, 2007 11:31 pm

I've been thinking of what you told me for an hour, and I conclude that you're absolutely right : any mean that makes memory access or rate go faster will be welcome !

Great piece of advice, Fonz'

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Sat Jan 27, 2007 9:06 am

ob1 wrote:
Fonzie wrote:the main problem with 32x is the DRAM / VRAM speed...
Are you sure the SDRAM speed, or FB speed is the main problem ? I would have guessed some missings features were much more a concern : no fill polygon, no scroll no scaling/rotation/distortion ... no hardware graphics function.

Anyway, there are several ways to improve memory speed :
- use 2way cache to create a dedicaced RAM area in the CPU
- use cache to improve acces time and rate
- use DMA to improve rate (not access time, obviously)
Of course polygon fill or other advanced video features would have been a great addition in the hardware. But the SH-2 offers you a lot of CPU power and you can do many stuff in software with them. Unfortunatly as said Fonz, the SDRAM and even more the VRAM speed limits the SH-2 CPU. It's why you have to use the cache and register as much you can.

ob1
Very interested
Posts: 463
Joined: Wed Dec 06, 2006 9:01 am
Location: Aix-en-Provence, France

Post by ob1 » Sat Jan 27, 2007 9:56 am

Stef wrote:... you have to use the cache and register as much you can.
Got it !

But man, ... I've never thought of developping software tile distortion .... I miss the Saturn VDP 1 (sigh...)

Anyway, coding a fill polygon function is quite of a challenge, and stimulating enough !!!

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Sat Jan 27, 2007 12:34 pm

32x vdp have a Horizontal line filling hardware if i recall correctly :)
I'm not speaking of the RLE vram mode, but a equivalent of VRAM fill.

Just take a look at the 32x vdp documentation, you'll find the fill function ;)

About the CAS mode1 selector, nobody can confirm it can be used if only one SH is used?

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Sat Jan 27, 2007 1:53 pm

I can't confirm but i don't think that having only one CPU accessing permit a lower CAS value. normally the sub CPU work in cycle steal mode, the main CPU has priority on the BUS : sub CPU access when main CPU don't need it.

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Sat Jan 27, 2007 7:50 pm

I see...

Anyway, a benchmark would be required to know what does it change :)

I was talking with somebody that did coding for 32x and had some issues by writting the SDRAM from the cached code... He told me the data was corrupted. Maybe it had something to do with the CAS thing. :/

I really hope there is something we can do about it :) ;)

Mask of Destiny
Very interested
Posts: 615
Joined: Thu Nov 30, 2006 6:30 am

Post by Mask of Destiny » Wed Jan 31, 2007 5:20 am

CAS latency has nothing to do with there being 2 processors on the bus it's a property of the RAM itself. Setting it to a lower value might work on some 32X units and it might not work on others or it might work on none of them as you'll probably be pushing the RAM chips out of spec.
I was talking with somebody that did coding for 32x and had some issues by writting the SDRAM from the cached code... He told me the data was corrupted. Maybe it had something to do with the CAS thing. :/
The SH-2 doesn't support hardware cache coherency. For instance, let's say both SH-2s have cached a certain memory location and then the first SH-2 modifies that memory location. The SH-2 uses write-through caching so it will update it's cached copy of the memory and the physical memory at the same time; however, the second SH-2 doesn't know that it's cache is out of date so if it tries to read that memory location it will get the old one instead of the new one until that cache line is flushed.

This greatly complicates the task of trying to get both SH-2s to work together as you either have to bypass the cache completely (which is slow), manually flush the cache (which gets complicated in a non-trivial program) or have them perform two completely separate tasks that require little communication.

ob1
Very interested
Posts: 463
Joined: Wed Dec 06, 2006 9:01 am
Location: Aix-en-Provence, France

Re: Master SH2 BIOS

Post by ob1 » Fri Feb 19, 2021 1:56 pm

Sorry to resurrect such an old topic, but I thought the work I've recently done one the BIOS disassembly would be useful.
Now, it compiles with asmsh /ol!

Code: Select all

	DC.L	resetPC		; Power-on reset PC
	DC.L	$06040000	;Power-on reset SP
	DC.L	resetPC		; Manual reset PC
	DC.L	$06040000	;Manual reset SP
	DC.L	ERR		;General illegal instruction
	DC.L	0		;Reserved
	DC.L	ERR		;Slot illegal instruction
	DC.L	$20100400	;Reserved
	DC.L	$20100420	;Reserved
	DC.L	ERR		;CPU address error
	DC.L	ERR		;DMA address error
	DC.L	ERR		;Interrupt NMI
	DC.L	ERR		;Interrupt

	DS.B	$80-*

	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR,ERR
	DC.L	ERR,ERR,ERR

ERR:
	BRA	ERR
	NOP

resetPC:
	MOV.L	MASK_ALL_INT,R0
	LDC	R0,SR

	MOV	#0,R0
	MOV	#0,R1
	MOV	#0,R2
	MOV	#0, R3
	MOV	#0,R4
	MOV	#0,R5
	MOV	#0,R6
	MOV	#0,R7
	MOV	#0,R8
	MOV	#0,R9
	MOV	#0,R10
	MOV	#0,R11
	MOV	#0,R12
	MOV	#0,R13
	MOV	#0,R14

	MOV.L	HW_REGISTERS,R8
	MOV.L	BCR1,R9
	MOV.L	@R8+,R0
	MOV.L	R0,@(0,R9)
	MOV.L	@R8+,R0
	MOV.L	R0,@(4,R9)
	MOV.L	@R8+,R0
	MOV.L	R0,@(8,R9)
	MOV.L	@R8+,R0
	MOV.L	R0,@($C,R9)
	MOV.L	@R8+,R0
	MOV.L	R0,@($10,R9)
	MOV.L	@R8+,R0
	MOV.L	R0,@($14,R9)
	MOV.L	@R8+,R0
	MOV.L	R0,@($18,R9)

	MOV.L	GBR_VALUE,R14
	LDC	R14,GBR		; GBR = $20004000

	MOV.L	CAS_LATENCY2,R8
	MOV	#0,R0
	MOV.W	R0,@R8

	MOV.B	@(0,GBR),R0
	TST	#2,R0		; if (R0 & #2 == 0), 1 -> T <=> 
	BF	adenIsSet

	MOV.L	SLEEPER,R0
	MOV	#1, R1
!wait:
	SUB	R1,R0
	CMP/EQ	#0,R0
	BF	!wait

	MOV.W	R0,@(2,GBR)	; Standby Changer Register
	MOV.L	SBYCR,R8
	MOV	#$9F,R0
	MOV.B	R0, @R8
	SLEEP
!infLoop:
	BRA	!infLoop
	NOP

	.align	4
MASK_ALL_INT:	DC.L	$000000F0
SLEEPER:	DC.L	$00010000



adenIsSet:
	MOV.L	SBYCR,R8
	MOV	#0,R0
	MOV.B	R0, @R8

	MOV.L	CCR,R9
	MOV	#$11,R0
	MOV.B	R0, @R9		; Four-way mode cache


; =============================================================================
; Check SDRAM
; =============================================================================
	MOV.L	SDRAM_END,R8
	MOV.L	SDRAM_START,R9
	MOV	#0,R0
!sdramWrite:
	MOV.W	R0,@-R8
	ADD	#1,R0
	MOV.W	R0,@-R8
	ADD	#1,R0
	MOV.W	R0,@-R8
	ADD	#1,R0
	MOV.W	R0,@-R8
	ADD	#1,R0
	CMP/EQ	R8,R9
	BF	!sdramWrite

	MOV.L	SDRAM_END,R8
	MOV.L	SDRAM_START,R9
	MOV	#0,R0
	MOV	#2,R1
	MOV	#1,R2
	MOV.L	MASK_HI_WORD,R3
!sdramCheck:
	SUB	R1,R8
	MOV.W	@R8,R4
	AND	R3,R4
	AND	R3,R0
	CMP/EQ	R0,R4
	BF	sdramFailed
	ADD	#1,R0
	CMP/EQ	R8,R9
	BF	!sdramCheck
	BRA	sdramSuccess
	NOP

MASK_HI_WORD:	DC.L	$0000FFFF

sdramFailed:
	MOV.L	SDER,R0
	MOV.L	R0,@($20,GBR)
	BRA	sdramFailed
	NOP

SDER:		DC.B	'SDER'

sdramSuccess:
	MOV.L	SDRAM_END,R8
	MOV.L	SDRAM_START,R9
	MOV	#0,R0
!sdramClear:
	MOV.L	R0,@-R8
	MOV.L	R0,@-R8
	MOV.L	R0,@-R8
	MOV.L	R0,@-R8
	CMP/EQ	R8,R9
	BF	!sdramClear





	MOV.B	@(0,GBR),R0
	TST	#1,R0
	BF	cartNotInserted

	MOV.L	ICD_CART_START,R13
	MOV.L	ICD_ROM_START,R12
	MOV.L	ICD_ROM_END,R11
!checkIcd:
	MOV.W	@R12+,R7
	EXTU.W	R7,R0
	MOV.W	@R13+,R6
	EXTU.W	R6,R1
	CMP/EQ	R0,R1
	BF	icdFailed
	CMP/EQ	R12,R11
	BF	!checkIcd
	BRA	icdSuccess
	NOP

	.align	4
ICD_ROM_START:	DC.L	IcdAllStart
ICD_ROM_END:	DC.L	IcdAllEnd

icdFailed:
	MOV.L	SQER,R0
	MOV.L	R0,@($20,GBR)
	MOV	#$80,R0
	MOV.B	R0,@(0,GBR)	; Set FM
	BRA	icdFailed
	NOP

SQER:		DC.B	'SQER'

icdSuccess:
	MOV.L	TABLE_INT,R8
	MOV.L	CK_CART,R9
	MOV.W	@R9,R1
	EXTU.W	R1,R0
	CMP/EQ	#0,R0
	BT	noChecksum
	MOV.L	CART_ROM_END,R9
	MOV.L	@R9,R7
	MOV.L	_0x200,R0
	SUB	R0,R7
	SHLR	R7
	MOV.L	BIGGEST_CART,R1
	AND	R1,R7
	ADD	#1,R7
	MOV	#0,R0
	MOV.L	MASK_HI_WORD2,R3
!checksum:
	MOV.W	@R8+,R2
	AND	R3,R2
	ADD	R2,R0
	AND	R3,R0
	DT	R7
	BF	!checksum

noChecksum:
	MOV.W	R0,@($28,GBR)
	MOV.L	SH2_CODE_START,R13
	MOV.L	@R13+,R8	; R8 = SH2 code start in Cart
	MOV.L	@R13+,R9	; R9 = SH2 code destination in SDRAM
	MOV.L	@R13+,R0	; R0 = SH2 code size
	MOV.L	CART_ADDR,R1
	ADD	R1,R8
	MOV.L	SDRAM_ADDR,R1
	ADD	R1,R9
	MOV	#4, R2
!copyCodeIntoSdram:
	MOV.L	@R8+,R1
	MOV.L	R1,@R9
	ADD	#4,R9
	SUB	R2,R0
	CMP/EQ	#0,R0
	BF	!copyCodeIntoSdram
	MOV.L	@(8,R13),R0
	LDC	R0,VBR
	MOV.L	@R13,R8
	MOV.L	M_OK,R0
	MOV.L	R0,@($20,GBR)
	JMP	@R8
	NOP

	.align	4
TABLE_INT:	DC.L	$22000200
CK_CART:	DC.L	$2200018E
CART_ROM_END:	DC.L	$220001A4
_0x200:		DC.L	$00000200
BIGGEST_CART:	DC.L	$003FFFFF
MASK_HI_WORD2:	DC.L	$0000FFFF
CART_ADDR:	DC.L	$22000000
SDRAM_ADDR:	DC.L	$06000000
M_OK:		DC.B	'M_OK'

cartNotInserted:
	MOV.L	_CD_,R1
!waitForCD:
	MOV.L	@($20,GBR),R0
	CMP/EQ	R0,R1
	BF	!waitForCD

	MOV	#$80,R0
	MOV.B	R0,@(0,GBR)	; Set FM
!waitForFM:
	MOV.B	@(0,GBR), R0
	TST	#$80,R0
	BT	!waitForFM

	MOV.L	FRAME_BUFFER,R8
	MOV.L	@(0,R8),R9
	MOV.L	@(4,R8),R0
	MOV.L	@(8,R8),R10
	MOV.L	@($10,R8),R11

	ADD	#$20,R8
	MOV.L	_128k,R3
	MOV	#0,R4
	MOV	#4,R2
!copyFrameBuffer:
	MOV.L	@R8+,R1
	MOV.L	R1,@R9
	ADD	#4,R9
	SUB	R2,R0
	SUB	R2,R3
	CMP/EQ	R4,R3
	BT	success
	CMP/EQ	#0,R0
	BF	!copyFrameBuffer

success:
	MOV.L	!M_OK,R0
	MOV.L	R0,@($20,GBR)
	LDC	R11,VBR
	JMP	@R10
	NOP

!M_OK:		DC.B	'M_OK'

GBR_VALUE:	DC.L	$20004000
HW_REGISTERS:	DC.L	REG_VALUES
BCR1:		DC.L	$FFFFFFE0
CCR:		DC.L	$FFFFFE92
SBYCR:		DC.L	$FFFFFE91
SH2_CODE_START:	DC.L	$220003D4
ICD_CART_START:	DC.L	$22000400
FRAME_BUFFER:	DC.L	$24000018
_128k:		DC.L	$0001FFE0
SDRAM_START:	DC.L	$26000000
SDRAM_END:	DC.L	$26040000

REG_VALUES:
	DC.L	$A55A0001	; BCR1	Bus Control Register 1
	DC.L	$A55A00A8	; BCR2	Bus Control Register 2
	DC.L	$A55A0055	; WCR	Wait Control Register
	DC.L	$A55A0AB8	; MCR
	DC.L	$A55A0008	; RTCSR	Refresh Timer Control/Status Register
	DC.L	$A55A0000	; RTCNT	Refresh Timer Counter
	DC.L	$A55A0059	; RTCOR	Refresh Time Constant Register
CAS_LATENCY2:	DC.L	$FFFF8446
_CD_:		DC.B	'_CD_'

IcdAllStart:
	incbin	"icd_mars_without2FirstInstructions.bin"
IcdAllEnd:

	DC.L	$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
	DC.L	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF

Post Reply