32x Porting Issue
Posted: 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.
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.
...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
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.