32x Porting Issue

Ask anything your want about the 32X Mushroom programming.

Moderator: BigEvilCorporation

Post Reply
IronSonic
Newbie
Posts: 2
Joined: Thu Sep 24, 2009 1:01 am

32x Porting Issue

Post by IronSonic » Thu Sep 24, 2009 1:30 am

Alright, for those of you who care, I'm from Sonic Retro. I've been working on a project for the past few months that has to do with porting from MD to 32x. So far, most all of the porting has gone well...

...except for the booting part. a7 locks itself within the first 2 seconds of booting and effectively hangs the rest of the booting.

Code: Select all

StartOfRom:
    if * <> 0
	fatal "StartOfRom was $\{*} but it should be 0"
    endif

; <><><><><>
;PWM_First_Location = $FFFFC600

	dc.l	0,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS
	dc.l	ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS
	dc.l	ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS
	dc.l	ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS
	dc.l	ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS
	dc.l	ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS
	dc.l	ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS
	dc.l	ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS,ICD_MARS

	dc.b	"SEGA MEGA DRIVE "
	dc.b	"(C)SEGA 2009.SEP"
	dc.b	"PROJECT         "
	dc.b	"DEIMOS          "
	dc.b	"                "
	dc.b	"PROJECT         "
	dc.b	"DEIMOS          "
	dc.b	"                "
	dc.b	"GM 00001051-32"

	dc.w	$0000

	dc.b	"J6              "

	dc.l	$00000000,$003fffff
	dc.l	$00000000,$00ffffff
	dc.b	"                "
	dc.b	"                "
	dc.b	"                "
	dc.b	"                "
	dc.b	"JUE             "

;	Reset Code
	jmp	$880000+__start
;	ds.b	6-($206-($200+6*0))	; Do not change this line

;	Bus Error
	rte
	ds.b	6-($208-($200+6*1))	; Do not change this line
;        ds.b    4

;	Address Error
	rte
	ds.b	6-($20E-($200+6*2))	; Do not change this line
;        ds.b    4

;	Illegal Instruction
	rte
	ds.b	6-($214-($200+6*3))	; Do not change this line
;        ds.b    4

;	Divide by 0
	rte
	ds.b	6-($21A-($200+6*4))	; Do not change this line
;        ds.b    4

;	CHK Instruction
	rte
	ds.b	6-($220-($200+6*5))	; Do not change this line
;        ds.b    4

;	TRAPV Instruction
	rte
	ds.b	6-($226-($200+6*6))	; Do not change this line
;        ds.b    4

;	Privilege Violation
	rte
	ds.b	6-($22C-($200+6*7))	; Do not change this line
;        ds.b    4

;	Trace
	rte
	ds.b	6-($232-($200+6*8))	; Do not change this line
;        ds.b    4

;	Line 1010 Emulator
	rte
	ds.b	6-($238-($200+6*9))	; Do not change this line
;        ds.b    4

;	Line 1111 Emulator
	rte
	ds.b	78-($23E-($200+6*10))	; Do not change this line

;	Spurious Interrupt
	rte
	ds.b	6-($28C-($200+6*23))	; Do not change this line

;	Level 1 Interrupt
	rte
	ds.b	6-($292-($200+6*24))	; Do not change this line

;	Level 2 Interrupt (TH)
	rte
	ds.b	6-($298-($200+6*25))	; Do not change this line

;	Level 3 Interrupt
	rte
	ds.b	6-($29E-($200+6*26))	; Do not change this line

;	Level 4 Interrupt (H-Blank)
	jmp	$880000+H_Int
;        jmp     $880000+__HBlank
;        rte
;	ds.b	6-($2A6-($200+6*27))	; Do not change this line

;	Level 5 Interrupt
	rte
	ds.b	6-($2AA-($200+6*28))	; Do not change this line

;	Level 6 Interrupt (V-Blank)
	jmp	$880000+V_Int
;        jmp     $880000+__VBlank
;        rte
;	ds.b	6-($2B2-($200+6*29))	; Do not change this line

;	Level 7 Interrupt
	rte
	ds.b	6-($2B6-($200+6*30))	; Do not change this line

;	Trap #0 Instruction
	rte
	ds.b	6-($2BC-($200+6*31))	; Do not change this line

;	Trap #1 Instruction
	rte
	ds.b	6-($2C2-($200+6*32))	; Do not change this line

;	Trap #2 Instruction
	rte
	ds.b	6-($2C8-($200+6*33))	; Do not change this line

;	Trap #3 Instruction
	rte
	ds.b	6-($2CE-($200+6*34))	; Do not change this line

;	Trap #4 Instruction
	rte
	ds.b	6-($2D4-($200+6*35))	; Do not change this line

;	Trap #5 Instruction
	rte
	ds.b	6-($2DA-($200+6*36))	; Do not change this line

;	Trap #6 Instruction
	rte
	ds.b	6-($2E0-($200+6*37))	; Do not change this line

;	Trap #7 Instruction
	rte
	ds.b	6-($2E6-($200+6*38))	; Do not change this line

;	Trap #8 Instruction
	rte
	ds.b	6-($2EC-($200+6*39))	; Do not change this line

;	Trap #9 Instruction
	rte
	ds.b	6-($2F2-($200+6*40))	; Do not change this line

;	Trap #10 Instruction
	rte
	ds.b	6-($2F8-($200+6*41))	; Do not change this line

;	Trap #11 Instruction
	rte
	ds.b	6-($2FE-($200+6*42))	; Do not change this line

;	Trap #12 Instruction
	rte
	ds.b	6-($304-($200+6*43))	; Do not change this line

;	Trap #13 Instruction
	rte
	ds.b	6-($30A-($200+6*44))	; Do not change this line

;	Trap #14 Instruction
	rte
	ds.b	6-($310-($200+6*45))	; Do not change this line

;	Trap #15 Instruction
	rte
	ds.b	6-($316-($200+6*46))	; Do not change this line


	ds.b	186
	dc.l	__sh2_m				; Source
	dc.l	$00000000			; Destination
	dc.l	__sh2_e-__sh2_m			; Size
	dc.l	$06000000+$120			; Master SH2 Jump
	dc.l	$06000000+$120+(__sh2_s-__sh2_m); Slave SH2 Jump
	dc.l	$06000000			; Master SH2 VBR
	dc.l	$06000000+(__sh2_s-__sh2_m)	; Slave SH2 VBR

ICD_MARS:
	dc.w	$287C,$FFFF,$FFC0,$23FC,$0000,$0000,$00A1,$5128
	dc.w	$46FC,$2700,$4BF9,$00A1,$0000,$7001,$0CAD,$4D41
	dc.w	$5253,$30EC,$6600,$03E6,$082D,$0007,$5101,$67F8
	dc.w	$4AAD,$0008,$6710,$4A6D,$000C,$670A,$082D,$0000
	dc.w	$5101,$6600,$03B8,$102D,$0001,$0200,$000F,$6706
	dc.w	$2B78,$055A,$4000,$7200,$2C41,$4E66,$41F9,$0000
	dc.w	$04D4,$6100,$0152,$6100,$0176,$47F9,$0000,$04E8
	dc.w	$43F9,$00A0,$0000,$45F9,$00C0,$0011,$3E3C,$0100
	dc.w	$7000,$3B47,$1100,$3B47,$1200,$012D,$1100,$66FA
	dc.w	$7425,$12DB,$51CA,$FFFC,$3B40,$1200,$3B40,$1100
	dc.w	$3B47,$1200,$149B,$149B,$149B,$149B,$41F9,$0000
	dc.w	$04C0,$43F9,$00FF,$0000,$22D8,$22D8,$22D8,$22D8
	dc.w	$22D8,$22D8,$22D8,$22D8,$41F9,$00FF,$0000,$4ED0
	dc.w	$1B7C,$0001,$5101,$41F9,$0000,$06BC,$D1FC,$0088
	dc.w	$0000,$4ED0,$0404,$303C,$076C,$0000,$0000,$FF00
	dc.w	$8137,$0002,$0100,$0000,$AF01,$D91F,$1127,$0021
	dc.w	$2600,$F977,$EDB0,$DDE1,$FDE1,$ED47,$ED4F,$D1E1
	dc.w	$F108,$D9C1,$D1E1,$F1F9,$F3ED,$5636,$E9E9,$9FBF
	dc.w	$DFFF,$4D41,$5253,$2049,$6E69,$7469,$616C,$2026
	dc.w	$2053,$6563,$7572,$6974,$7920,$5072,$6F67,$7261
	dc.w	$6D20,$2020,$2020,$2020,$2020,$2043,$6172,$7472
	dc.w	$6964,$6765,$2056,$6572,$7369,$6F6E,$2020,$2020
	dc.w	$436F,$7079,$7269,$6768,$7420,$5345,$4741,$2045
	dc.w	$4E54,$4552,$5052,$4953,$4553,$2C4C,$5444,$2E20
	dc.w	$3139,$3934,$2020,$2020,$2020,$2020,$2020,$2020
	dc.w	$2020,$2020,$2020,$2020,$2020,$2020,$2020,$2020
	dc.w	$2020,$2020,$2020,$524F,$4D20,$5665,$7273,$696F
	dc.w	$6E20,$312E,$3000,$48E7,$C040,$43F9,$00C0,$0004
	dc.w	$3011,$303C,$8000,$323C,$0100,$3E3C,$0012,$1018
	dc.w	$3280,$D041,$51CF,$FFF8,$4CDF,$0203,$4E75,$48E7
	dc.w	$81C0,$41F9,$0000,$063E,$43F9,$00C0,$0004,$3298
	dc.w	$3298,$3298,$3298,$3298,$3298,$3298,$2298,$3341
	dc.w	$FFFC,$3011,$0800,$0001,$66F8,$3298,$3298,$7000
	dc.w	$22BC,$C000,$0000,$7E0F,$3340,$FFFC,$3340,$FFFC
	dc.w	$3340,$FFFC,$3340,$FFFC,$51CF,$FFEE,$22BC,$4000
	dc.w	$0010,$7E09,$3340,$FFFC,$3340,$FFFC,$3340,$FFFC
	dc.w	$3340,$FFFC,$51CF,$FFEE,$4CDF,$0381,$4E75,$8114
	dc.w	$8F01,$93FF,$94FF,$9500,$9600,$9780,$4000,$0080
	dc.w	$8104,$8F02,$48E7,$C140,$43F9,$00A1,$5180,$08A9
	dc.w	$0007,$FF80,$66F8,$3E3C,$00FF,$7000,$7200,$337C
	dc.w	$00FF,$0004,$3341,$0006,$3340,$0008,$4E71,$0829
	dc.w	$0001,$000B,$66F8,$0641,$0100,$51CF,$FFE8,$4CDF
	dc.w	$0283,$4E75,$48E7,$8180,$41F9,$00A1,$5200,$08A8
	dc.w	$0007,$FF00,$66F8,$3E3C,$001F,$20C0,$20C0,$20C0
	dc.w	$20C0,$51CF,$FFF6,$4CDF,$0181,$4E75,$41F9,$00FF
	dc.w	$0000,$3E3C,$07FF,$7000,$20C0,$20C0,$20C0,$20C0
	dc.w	$20C0,$20C0,$20C0,$20C0,$51CF,$FFEE,$3B7C,$0000
	dc.w	$1200,$7E0A,$51CF,$FFFE,$43F9,$00A1,$5100,$7000
	dc.w	$2340,$0020,$2340,$0024,$1B7C,$0003,$5101,$2E79
	dc.w	$0088,$0000,$0891,$0007,$66FA,$7000,$3340,$0002
	dc.w	$3340,$0004,$3340,$0006,$2340,$0008,$2340,$000C
	dc.w	$3340,$0010,$3340,$0030,$3340,$0032,$3340,$0038
	dc.w	$3340,$0080,$3340,$0082,$08A9,$0000,$008B,$66F8
	dc.w	$6100,$FF12,$08E9,$0000,$008B,$67F8,$6100,$FF06
	dc.w	$08A9,$0000,$008B,$6100,$FF3C,$303C,$0040,$2229
	dc.w	$0020,$0C81,$5351,$4552,$6700,$0092,$303C,$0080
	dc.w	$2229,$0020,$0C81,$5344,$4552,$6700,$0080,$21FC
	dc.w	$0088,$02A2,$0070,$303C,$0002,$7200,$122D,$0001
	dc.w	$1429,$0080,$E14A,$8242,$0801,$000F,$660A,$0801
	dc.w	$0006,$6700,$0058,$6008,$0801,$0006,$6600,$004E
	dc.w	$7020,$41F9,$0088,$0000,$3C28,$018E,$4A46,$6700
	dc.w	$0010,$3429,$0028,$0C42,$0000,$67F6,$B446,$662C
	dc.w	$7000,$2340,$0028,$2340,$002C,$3E14,$2C7C,$FFFF
	dc.w	$FFC0,$4CD6,$7FF9,$44FC,$0000,$6014,$43F9,$00A1
	dc.w	$5100,$3340,$0006,$303C,$8000,$6004,$44FC,$0001



__start:

	bra	__entry


	align 4

__sh2_m:			; Start of Master SH2 execution
	binclude	"sh2_m.bin"
__sh2_s:
	binclude	"sh2_s.bin"
;	dc.l	PWMSamples+$22000000	;dirty hack to reference the PWMSamples in SH2

__sh2_e:

	align 4

;--------------------------------
; CODE START - DO NOT EDIT ANYTHING ABOVE
;--------------------------------

__entry:

; loc_206:
EntryPoint:
	tst.l	(Z80_Port_1_Control).l	; test port A control
	bne.s	PortA_Ok
	tst.w	(Z80_Expansion_Control).l	; test port C control

; loc_214:
PortA_Ok:
	bne	PortC_OK ; skip the VDP and Z80 setup code if port A or C is ok...?
	lea	SetupValues(pc),a5
	movem.w	(a5)+,d5-d7
	movem.l	(a5)+,a0-a4
	move.b	Z80_Version-Z80_Bus_Request(a1),d0	; get hardware version
	andi.b	#$F,d0
	beq.s	SkipSecurity ; branch if hardware is older than Genesis III
	move.l	#'SEGA',Security_Addr-Z80_Bus_Request(a1) ; satisfy the TMSS

; loc_234:
SkipSecurity:
	move.w	(a4),d0	; check if VDP works
	moveq	#0,d0
	movea.l	d0,a6
	move.l	a6,usp	; set usp to $0
	moveq	#$17,d1 ; run the following loop $18 times

; loc_23E:
VDPInitLoop:
	move.b	(a5)+,d5	; add $8000 to value
	move.w	d5,(a4)	; move value to VDP register
	add.w	d7,d5	; next register
	dbf	d1,VDPInitLoop

	move.l	(a5)+,(a4)	; set VRAM write mode
	move.w	d0,(a3)	; clear the screen
	move.w	d7,(a1)	; stop the Z80
	move.w	d7,(a2)	; reset the Z80

; loc_250:
WaitForZ80:
	btst	d0,(a1)	; has the Z80 stopped?
	bne.s	WaitForZ80	; if not, branch
	moveq	#Z80StartupCodeEnd-Z80StartupCodeBegin-1,d2

; loc_256:
Z80InitLoop:
	move.b	(a5)+,(a0)+
	dbf	d2,Z80InitLoop

	move.w	d0,(a2)
	move.w	d0,(a1)	; start the Z80
	move.w	d7,(a2)	; reset the Z80

; loc_262:
ClrRAMLoop:
	move.l	d0,-(a6)
	dbf	d6,ClrRAMLoop	; clear the entire RAM
	move.l	(a5)+,(a4)	; set VDP display mode and increment
	move.l	(a5)+,(a4)	; set VDP to CRAM write
	moveq	#$1F,d3

; loc_26E:
ClrCRAMLoop:
	move.l	d0,(a3)
	dbf	d3,ClrCRAMLoop	; clear the CRAM
	move.l	(a5)+,(a4)
	moveq	#$13,d4

; loc_278:
ClrVDPStuff:
	move.l	d0,(a3)
	dbf	d4,ClrVDPStuff
	moveq	#3,d5

; loc_280:
PSGInitLoop:
	move.b	(a5)+,$11(a3)	; reset the PSG
	dbf	d5,PSGInitLoop
	move.w	d0,(a2)
	movem.l	(a6),d0-a6	; clear all registers
	move	#$2700,sr	; set the sr

 ; loc_292:
PortC_OK: ;;
	bra.s	GameProgram
; ===========================================================================
; byte_294:
SetupValues:
	dc.w	$8000,$3FFF,$100

	dc.l	Z80_RAM
	dc.l	Z80_Bus_Request
	dc.l	Z80_Reset
	dc.l	VDP_data_port, VDP_control_port

	; values for VDP registers
	dc.b	  4, $14, $30, $3C
	dc.b	$07, $6C, $00, $00
	dc.b	$00, $00, $FF, $00
	dc.b	$81, $37, $00, $01
	dc.b	$01, $00, $00, $FF
	dc.b	$FF, $00, $00, $80

	dc.l	$40000080 ; value for VRAM write mode

	; Z80 instructions (not the sound driver; that gets loaded later)
	; I think this is basically unused but I've made some sense of it anyway...
Z80StartupCodeBegin: ; loc_2CA:
    if (*)+$26 < $10000
    CPU Z80 ; start compiling Z80 code
    phase 0 ; pretend we're at address 0
	xor     a	; clear a to 0
	ld      bc,((Z80_RAM_End-Z80_RAM)-zStartupCodeEndLoc)-1 ; prepare to loop this many times
	ld      de,zStartupCodeEndLoc+1	; initial destination address
	ld      hl,zStartupCodeEndLoc	; initial source address
	ld      sp,hl	; set the address the stack starts at
	ld      (hl),a	; set first byte of the stack to 0
	ldir    	; loop to fill the stack (entire remaining available Z80 RAM) with 0
	pop     ix	; clear ix
	pop     iy	; clear iy
	ld      i,a	; clear i
	ld      r,a	; clear r
	pop     de	; clear de
	pop     hl	; clear hl
	pop     af	; clear af
	ex      af,af'	; swap af with af'
	exx		; swap bc/de/hl with their shadow registers too
	pop     bc	; clear bc
	pop     de	; clear de
	pop     hl	; clear hl
	pop     af	; clear af
	ld      sp,hl	; clear sp
	di      	; clear iff1 (for interrupt handler)
	im      1	; interrupt handling mode = 1
	ld      (hl),0E9H ; replace the first instruction with a jump to itself
	jp      (hl)      ; jump to the first instruction (to stay there forever)
    zStartupCodeEndLoc:
    dephase ; stop pretending
    CPU 68000	; switch back to 68000 code
    padding off ; unfortunately our flags got reset so we have to set them again...
    listing off
    supmode on
    else ; due to an address range limitation I could work around but don't think is worth doing so:
	message "Warning: using pre-assembled Z80 startup code."
    	dc.w $AF01,$D91F,$1127,$0021,$2600,$F977,$EDB0,$DDE1,$FDE1,$ED47,$ED4F,$D1E1,$F108,$D9C1,$D1E1,$F1F9,$F3ED,$5636,$E9E9
    endif
Z80StartupCodeEnd:

	dc.w	$8104	; value for VDP display mode
	dc.w	$8F02	; value for VDP increment
	dc.l	$C0000000	; value for CRAM write mode
	dc.l	$40000010	; unknown (VSRAM?)

	dc.b	$9F,$BF,$DF,$FF	; values for PSG channel volumes
; ===========================================================================

	even

; loc_300:
GameProgram:
	tst.w	(VDP_control_port).l

; loc_306:
CheckSumCheck:
	move.w	(VDP_control_port).l,d1
	btst	#1,d1
	bne.s	CheckSumCheck
	btst	#6,(Z80_Expansion_Control+1).l
;	beq.s	ChecksumTest
        beq.s   checksum_good
	cmpi.l	#'init',(Checksum_fourcc).w ; has checksum routine already run?
	beq.w	GameInit

checksum_good:
        lea     (System_Stack).w,a6
	moveq	#0,d7
	move.w	#$7F,d6

Checksum_Loop:
	move.l	d7,(a6)+
	dbf	d6,Checksum_Loop
	move.b	(Z80_Version).l,d0
	andi.b	#$C0,d0
	move.b	d0,(Graphics_Flags).w
	move.l	#'init',(Checksum_fourcc).w ; set flag so checksum won't be run again

; loc_370:
GameInit:
	lea	($FF0000).l,a6
	moveq	#0,d7
	move.w	#$3F7F,d6

; loc_37C:
GameClrRAM:
	move.l	d7,(a6)+
	dbf	d6,GameClrRAM
	bsr.w	VDPSetupGame
	bsr.w	JmpTo_SoundDriverLoad
	bsr.w	JoypadInit
	move.b	#0,(Game_Mode).w	; => SegaScreen

; loc_394:
MainGameLoop:
	move.b	(Game_Mode).w,d0
	andi.w	#$3C,d0
	jsr	GameModesArray(pc,d0.w)
	bra.s	MainGameLoop
I'm pretty sure that at least some people on this board will know what game it is (heck, I left in most all of the original comments from the disasm), so for those who know, please don't tell.

Anyway, this is pretty much the header and boot sequence. It's been modified to work with AS.

The main issue that presents itself is that when I compile and run it, it attempts to boot, then when the sr is set to #2700, a7 locks itself on $FFFFFFF6. I've been looking at this for awhile, and I'm pretty sure I'm missing something pretty simple. Still, can anyone help? I can post the V-Int and H-Int code if needed, as well as other code portions, although I don't think they are the problem.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Thu Sep 24, 2009 5:05 am

You might look at my start files for Wolf32X. That shows how to handle both the 68000 and both SH2s. Where each part of the start is located is VERY important, and I made comments about the offset for those important spots in the files. You'd want to check yours in a hex-editor to make sure you wind up on the proper boundaries.

Post Reply