Template code

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

Template code

Post by ob1 » Fri Mar 09, 2007 3:35 pm

Here are the first bytes took from egypt MARS sample.
Especially, the SH2 register are needed :

Code: Select all

	org	$0
	dc.l	$06000120
	dc.l	$06040000
	dc.l	$06000120
	dc.l	$06040000
	dc.l	$060003D4
	dc.l	$00000000
	dc.l	$060003D4
	dc.l	$20100400
	dc.l	$20100420
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4

	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000
	dc.l	$00000000

	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4
	dc.l	$060003D4

	dc.l	$06000220
	dc.l	$06000220
	dc.l	$06000220
	dc.l	$06000220
	dc.l	$06000220
	dc.l	$06000220
	dc.l	$06000220
	dc.l	$06000220

	org	$120
	mov.l	REG_32X,R14
	ldc	R14,GBR
	mov	#$20,R0
	ldc	R0,SR
	mov.l	REG_TIER,R1
	mov	#0,R0
	mov.b	R0,@R1
	mov.b	#$E2,R0
	mov.b	R0,@(7,R1)	; TOCR
	mov	#0,R0
	mov.b	R0,@(4,R1)	; OCRB
	mov	#1,R0
	mov.b	R0,@(5,R1)	; TCR
	mov	#0,R0
	mov.b	R0,@(6,R1)	; TCR
	mov	#1,R0
	mov.b	R0,@(1,R1)	; FTCSR
	mov	#0,R0
	mov.b	R0,@(3,r1)	; OCRA
	mov.b	r0,@(2,r1)	; FRC
test:
	mov.l	@(8,GBR),r0
	add	#1,R10
	cmp/eq	#0,r0
	bra	test
	nop

REG_32X:	dc.l	$20004000
REG_TIER:	dc.l	$FFFFFE10
SH2 registers (TIER, OCRB, ...) init is needed indeed (funny to write).
Beware ASMSH is not as good than what I had believed : it adds 15 leading bytes and 1 tailing byte.

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Re: Template code

Post by TascoDLX » Sun Mar 11, 2007 4:51 am

If you're looking for template code, you can probably do better than the Egypt demo. Nevertheless, you should also copy the interrupt routine while you're at it.

Now, about that free running timer....
ob1 wrote:SH2 registers (TIER, OCRB, ...) init is needed indeed (funny to write).
Note this:

Code: Select all

	mov.l	REG_TIER,R1
	mov	#0,R0
	mov.b	R0,@R1
	mov.b	#$E2,R0
	mov.b	R0,@(7,R1)	; TOCR
	mov	#0,R0
	mov.b	R0,@(4,R1)	; OCR high (!)
	mov	#1,R0
	mov.b	R0,@(5,R1)	; OCR low (!)
	mov	#0,R0
	mov.b	R0,@(6,R1)	; TCR
	mov	#1,R0
	mov.b	R0,@(1,R1)	; FTCSR
	mov	#0,R0
	mov.b	R0,@(3,r1)	; FRC low (!)
	mov.b	r0,@(2,r1)	; FRC high (!)
Still a little funny but the order does make sense... for the most part.

If you're not easily confused, read the 32X Hardware Manual Supplement 2.
Limitations Concerning the SH2 Interrupt

Poor performance occurs in the SH2 concerning the following interrupts.

1. If an external interrupt (VRES, V, H, CMD, PWM) input is input in the acknowledge period for interrupt inputs, or external interrupt of lower levels, SH2 will not recognize the external interrupt.

...

Corrective Action

1. Corrective action is taken by controlling the free-run-timer output of SH2 by software. The corrective process must be done within the external interrupt process routine. A pipeline operation must be considered to prevent the same interrupt from being duplicated.
That almost makes sense, right? Pipeline? Whatever. Also:
With the EVA chip cut 2.5, operation is normal although no corrective action is taken since the trouble above is corrected, but because an unmodified chip is used in the initial version of the actual device, corrective action must be taken.
So, for compatibility reasons if nothing else.

In the interrupt handler:

Code: Select all

	mov.l	#_FRT,r1			; External Interrupt Corrective Action
	mov.b	@(_TORC,r1),r0
	xor	#h'02,r0
	mov.b	r0,@(_TORC,r1)
Also, mask the SR beforehand, and write to the corresponding INT reset register. And, according to the Supplement, take a few clock cycles after the reset (you'll often see NOP, NOP, NOP, NOP). You'll probably want to disassemble at least one game to see it in context.

Note: In Kolibri, for example, the "corrective action" isn't made when significant processing is done during the interrupt. Could be the same for other titles but I just haven't checked.

So there you go. A little useless information for the dev-heads. Enjoy!

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

My template code

Post by ob1 » Tue Mar 13, 2007 9:34 am

Code: Select all

_INT	equ	$06000000+INT

	dc.l	$06000120	; Power-on reset PC
	dc.l	$06040000	; Power-on reset SP
	dc.l	$06000120	; Manual reset PC
	dc.l	$06040000	; Manual reset SP
	dc.l	_INT		; General illegal instruction
	dc.l	_INT		; Reserved
	dc.l	_INT		; Slot illegal instruction
	dc.l	_INT		; Reserved
	dc.l	_INT		; Reserved
	dc.l	_INT		; CPU address error
	dc.l	_INT		; DMA address error
	dc.l	_INT		; Interrupt NMI
	dc.l	_INT		; Interrupt

*	Reserved - Vector 13-31
	dc.l	_INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT
	dc.l	_INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT
	dc.l	_INT,_INT,_INT

*	Trap instruction (user vector) - Vector 32-63
	dc.l	_INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT
	dc.l	_INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT
	dc.l	_INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT
	dc.l	_INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT

*	IRL - Vector 64-71
	dc.l	_INT	; IRL1
	dc.l	_INT	; IRL2/3
	dc.l	_INT	; IRL4/5
	dc.l	$06000000+PWM_INT	; IRL6/7
	dc.l	$06000000+CMD_INT	; IRL8/9
	dc.l	$06000000+H_INT		; IRL10/11
	dc.l	$06000000+V_INT		; IRL12/13
	dc.l	$06000000+VRES_INT	; IRL14/15

*	org	$120
*	CPU Init
	mov.l	REG_32X,R14
	ldc	R14,GBR
	mov	#$20,R0
	ldc	R0,SR
	mov.l	REG_TIER,R1
	mov	#0,R0
	mov.b	R0,@R1
	mov.b	#$E2,R0
	mov.b	R0,@(7,R1)	; TOCR
	mov	#0,R0
	mov.b	R0,@(4,R1)	; OCRB
	mov	#1,R0
	mov.b	R0,@(5,R1)	; TCR
	mov	#0,R0
	mov.b	R0,@(6,R1)	; TCR
	mov	#1,R0
	mov.b	R0,@(1,R1)	; FTCSR
	mov	#0,R0
	mov.b	R0,@(3,r1)	; OCRA
	mov.b	r0,@(2,r1)	; FRC

	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	#0,R15

	mov	#1,R0
	mov.l	REG_CCR,R1
	mov.b	R0,@R1			; Cache enable

	mov.w	@(0,GBR),R0
	or	#8,R0
	mov.w	R0,@(0,GBR)		; Enable V INT

test:
	add	#1,R13		; Main runner
	bra	test
	nop

INT:
	rte
	nop

PWM_INT:
	rte
	nop

CMD_INT:
	rte
	nop

H_INT:
	rte
	nop

V_INT:
	add	#1,R12		; Frame runner
	mov	#0,R0
	mov.w	R0,@(16,GBR)		; Clear VINT
	rte
	nop

VRES_INT:
	rte
	nop

REG_32X:	dc.l	$20004000
REG_TIER:	dc.l	$FFFFFE10

REG_CCR:	dc.l	$FFFFFE92
BMP_MODE_REG:	dc.l	$20004100
FB_CTRL_REG:	dc.l	$2000410A
Of course, since this code is intend to be run from RAM (start address = 0600 0000h), the interrupts addresses have to be slided the same way.

Post Reply