Program behavior not the same on MegaCD
Moderator: Mask of Destiny
Program behavior not the same on MegaCD
Hello,
I want to code for the MegaCD, but didn't succeed in using the classic SGDK, so I started coding a little test program in 100% 68k asm
It works great as a megadrive rom, but when switching to MegaCD, it doesn't work anymore.
First I tried the cdboot example of Chilly Willy, I compiled the program with org $200000, skipping the cartridge header, making an APP.BIN, an iso image with this file in root directory, and replacing the first 32k of iso file with EU_BOOT.BIN
Test in emulator doesn't work, it keep reading the CD after the "sega sonic" animation. (can't find the file ?)
Then I tried this cd boot kit: http://gendev.spritesmind.net/files/mcd ... jectCD.zip
(see viewtopic.php?t=872 )
Now, I have the program loading and booting, but while transferring the Tile data to vram, it seems that the program stop working during the transfer and jump in random position (!?)
I can see in the debugger of the emulator that my palette is set correctly, and that a partial amount of tile have been transfered, but not the entire tile data.
The same code works perfectly on megadrive as a rom cartridge !
so, can anyone help me about this strange behavior ? Did I miss to do something specifically related to megacd ?
Thank you
I want to code for the MegaCD, but didn't succeed in using the classic SGDK, so I started coding a little test program in 100% 68k asm
It works great as a megadrive rom, but when switching to MegaCD, it doesn't work anymore.
First I tried the cdboot example of Chilly Willy, I compiled the program with org $200000, skipping the cartridge header, making an APP.BIN, an iso image with this file in root directory, and replacing the first 32k of iso file with EU_BOOT.BIN
Test in emulator doesn't work, it keep reading the CD after the "sega sonic" animation. (can't find the file ?)
Then I tried this cd boot kit: http://gendev.spritesmind.net/files/mcd ... jectCD.zip
(see viewtopic.php?t=872 )
Now, I have the program loading and booting, but while transferring the Tile data to vram, it seems that the program stop working during the transfer and jump in random position (!?)
I can see in the debugger of the emulator that my palette is set correctly, and that a partial amount of tile have been transfered, but not the entire tile data.
The same code works perfectly on megadrive as a rom cartridge !
so, can anyone help me about this strange behavior ? Did I miss to do something specifically related to megacd ?
Thank you
Retro game programming !
-
- Interested
- Posts: 24
- Joined: Wed Feb 03, 2010 12:53 am
- Location: Grimsby, England
yeah, sorry, that will be easier
Code: Select all
org $200000
jmp Continue ; Skip header (this is for cartridge rom only)
dc.l $00FFFE00 ; Stack
dc.l _Entry_Point
dc.l _Error_Exception
dc.l _Error_Exception
dc.l _Error_Exception
dc.l _Error_Exception
dc.l _Error_Exception
dc.l _Error_Exception
dc.l _Error_Exception
dc.l _Error_Exception
dc.l _Line_1010_Emulation
dc.l _Line_1111_Emulation
dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception
dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception
dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception
dc.l _Error_Exception, _INT, _EXTINT, _INT
dc.l _HINT
dc.l _INT
dc.l _VINT
dc.l _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
dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT
dc.b "SEGA MEGA DRIVE " ; Console Name
dc.b "<=- Orion_ =-> " ; Copyright
dc.b "SAMPLE PROGRAM " ; Game Name
dc.b "SAMPLE PROGRAM " ; Overseas Name
dc.b "GM 00000000-00" ; Serial
dc.w $0000 ; Checksum
dc.b "JD " ; IO Support
dc.l $00000000 ; Rom Start
dc.l $00010000 ; Rom End
dc.l $00FF0000 ; Backup RAM Start
dc.l $00FFFFFF ; Backup RAM End
dc.b " " ; "RA" for Backup RAM
dc.w $0000 ; $F820 for Backup RAM on odd bytes
dc.l $00200000 ; SRAM Start
dc.l $002001FF ; SRAM End
dc.b " " ; Modem
dc.b "DEMONSTRATION PROGRAM " ; Note
dc.b "JUE " ; Country
;---------------------------------------->
_Entry_Point:
move #$2700,sr
tst.l $a10008
bne.s SkipJoyDetect
tst.w $a1000c
SkipJoyDetect:
bne.s SkipSetup
Continue:
; Sega Security Code (SEGA)
move.b $A10001,d0
andi.b #$0f,d0
beq.s WrongVersion
move.l #$53454741,$A14000
WrongVersion:
move.w #$0100,d0
move.w d0,$A11100 ; Z80 Bus Request
move.w d0,$A11200 ; Z80 Request Reset
SkipSetup:
; Clear RAM
lea $ff0000,a0
moveq #0,d0
move.w #$3FFF,d1
ClearRam:
move.l d0,(a0)+
dbra d1,ClearRam
; Init VDP
lea VDPtable,a0
lea $C00004,a1
moveq #19-1,d0
move.w #$8000,d1
VDPiLoop:
move.b (a0)+,d1 ; Reg Value from Table
move.w d1,(a1) ; Send to VDP
add.w #$0100,d1 ; Reg++
dbra d0,VDPiLoop
;---------------------------------------->
; Main Code
VDP_DATA equ $C00000
VDP_CTRL equ $C00004
lea Image,a0
moveq #0,d0 ; Palette Address
moveq #(4*16)-1,d1 ; N Colors
bsr SetCramAddress
lea VDP_DATA,a1
PalLoop:
move.w (a0)+,(a1) ; Copy Color
dbra d1,PalLoop
move.w #$C000,d0 ; Map A VRAM address
bsr SetVramAddress
lea VDP_DATA,a1
moveq #28-1,d2
MapLoopY:
moveq #40-1,d1
MapLoopX:
move.w (a0)+,(a1) ; Copy Map Data
dbra d1,MapLoopX
moveq #(64-40)-1,d1
MapLoopX2:
move.w #0,(a1) ; Clear OffScreen
dbra d1,MapLoopX2
dbra d2,MapLoopY
; move.l a0,d0 ; From Address
; move.w #0,d1 ; To Address (VRAM)
; move.w #1120*32,d2 ; Lenght (n tiles * 32 bytes per tile)
; bsr TransferDMAtoVRAM
move.w #0,d0
bsr SetVramAddress
move.l a0,d0 ; From Address
move.w #((1120*32)/2)-1,d2 ; Lenght (n tiles * 32 bytes per tile)
lea VDP_DATA,a1
TileLoop:
move.w (a0)+,(a1) ; Copy Tile
dbra d2,TileLoop
;------>
moveq #0,d1
Loop:
lea VDP_CTRL,a0
.waitvbl1:
move.w (a0),d0
andi.w #8,d0
bne.s .waitvbl1
.waitvbl2:
move.w (a0),d0
andi.w #8,d0
beq.s .waitvbl2
moveq #2,d0 ; Palette Address
bsr SetCramAddress
move.w d1,VDP_DATA ; Color loop test dbug
addq.w #1,d1
jmp Loop
;---------------------------------------->
; Utils
SetVramAddress: ; d0 = Address
movem.l d1-d4,-(a7)
move.w #$4000,d3
move.b #$00,d4
bra.s iSetVDPAddress
SetVramAddressDMA: ; d0 = Address
movem.l d1-d4,-(a7)
move.w #$4000,d3
move.b #$80,d4
bra.s iSetVDPAddress
SetCramAddress: ; d0 = Address
movem.l d1-d4,-(a7)
move.w #$C000,d3
move.b #$00,d4
bra.s iSetVDPAddress
SetCramAddressDMA: ; d0 = Address
movem.l d1-d4,-(a7)
move.w #$C000,d3
move.b #$80,d4
iSetVDPAddress:
move.w d0,d2 ; Address
and.w #$3FFF,d2 ; Lower Bits
or.w d3,d2 ; Add VDP Command
swap d2
move.w d0,d1 ; Address
lsr.w #8,d1
lsr.w #14-8,d1 ; Upper Bits
move.w d1,d2
or.b d4,d2 ; Add VDP Command
move.l d2,VDP_CTRL
movem.l (a7)+,d1-d4
rts
;------>
TransferDMAtoVRAM:
movem.l d3/a0,-(a7)
lea VDP_CTRL,a0
lsr.w #1,d2 ; lenght in word
move.w #$9300,d3
move.b d2,d3 ; msb
move.w d3,(a0)
lsr.w #8,d2 ; lsb
or.w #$9400,d2
move.w d2,(a0)
lsr.w #1,d0 ; address in word
move.w #$9500,d3
move.b d0,d3
move.w d3,(a0)
lsr.w #8,d0
move.w #$9600,d3
move.b d0,d3
move.w d3,(a0)
lsr.w #8,d0
or.w #$9700,d0
move.w d0,(a0)
move.w d1,d0 ; Tile VRAM address
bsr SetVramAddressDMA
movem.l (a7)+,d3/a0
rts
;---------------------------------------->
; Interrupts
_Line_1010_Emulation:
_Line_1111_Emulation:
rte
_Error_Exception:
rte
_INT:
rte
_EXTINT:
rte
_HINT:
rte
_VINT:
rte
;---------------------------------------->
; Datas
; VDP Ram
;Tile Data $0000 44k
;Window $B000 2k Unused !
;HScroll $B800 1k
;Sprite $BC00 1k
;Map A $c000 8k
;Map B $e000 8k
VDPtable: dc.b $04,$74,$30,$2C,$07,$5E,$00,$00,$00,$00,$01,$00,$81,$2E,$00,$02,$11,$00,$FF
even
Image: incbin "title1.bin"
org $00010000
Retro game programming !
-
- Very interested
- Posts: 624
- Joined: Thu Nov 30, 2006 6:30 am
Re: Program behavior not the same on MegaCD
What exactly is in EU_BOOT.BIN? Is it just the european security code chunk? If so that won't work. You need a chunk of sub CPU code for reading the disc and and some main CPU code that coordinates with the sub CPU and jumps to the loaded code at $200000.Orion_ wrote:First I tried the cdboot example of Chilly Willy, I compiled the program with org $200000, skipping the cartridge header, making an APP.BIN, an iso image with this file in root directory, and replacing the first 32k of iso file with EU_BOOT.BIN
Test in emulator doesn't work, it keep reading the CD after the "sega sonic" animation. (can't find the file ?)
I would also completely remove the cartridge header. It serves no purpose here and just takes up space. You should probably also remove the standard "init" code as the Megadrive hardware is already initialized by the Mega CD bios (zero-ing RAM may be one exception, but don't zero the entirety of Word RAM as the BIOS uses part of it for interrupt handling).
DMA from Word RAM is kind of flaky though it should only be off by a single word from what I remember. You can compensate for this, but I don't remember the exact adjustment that needs to be made. Seems like your problem is a bit more than that though.Orion_ wrote:Now, I have the program loading and booting, but while transferring the Tile data to vram, it seems that the program stop working during the transfer and jump in random position (!?)
I can see in the debugger of the emulator that my palette is set correctly, and that a partial amount of tile have been transfered, but not the entire tile data.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
First, there were a couple errors in old versions of the boot loader. Make sure you use the latest:
http://www.mediafire.com/download/bh384 ... 0130331.7z
Second, make sure that whatever example you work from compiles and works for you before you try altering it for your own usage. Here's the libpcm and the latest cd mod player source:
http://www.mediafire.com/download/fwa2e ... 0130331.7z
http://www.mediafire.com/download/297a8 ... 0130411.7z
Finally, in the code you posted, you are still clearing ALL the MD ram... which causes a crash since you overwrote areas that the CD uses. You MUST leave 0xFF0000 to 0xFF0FFF and 0xFFFD00 to 0xFFFFFF alone. They are reserved for use by the CD - the first range holds the main 68K IPL, and the second holds the interrupt jump table and BIOS vars for the MD side. While you can probably get away with using the first range (if you know what you're doing), you CANNOT mess with the second range (other than replacing certain vectors, again, only if you know what you're doing).
http://www.mediafire.com/download/bh384 ... 0130331.7z
Second, make sure that whatever example you work from compiles and works for you before you try altering it for your own usage. Here's the libpcm and the latest cd mod player source:
http://www.mediafire.com/download/fwa2e ... 0130331.7z
http://www.mediafire.com/download/297a8 ... 0130411.7z
Finally, in the code you posted, you are still clearing ALL the MD ram... which causes a crash since you overwrote areas that the CD uses. You MUST leave 0xFF0000 to 0xFF0FFF and 0xFFFD00 to 0xFFFFFF alone. They are reserved for use by the CD - the first range holds the main 68K IPL, and the second holds the interrupt jump table and BIOS vars for the MD side. While you can probably get away with using the first range (if you know what you're doing), you CANNOT mess with the second range (other than replacing certain vectors, again, only if you know what you're doing).
-
- Very interested
- Posts: 624
- Joined: Thu Nov 30, 2006 6:30 am
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Not that I can see, so it's probably not an interrupt, but it could be an exception. Also, this is running for word ram, but we don't see any of the rest of the code, so we don't know if the code/data has been properly loaded and switched to the MD side, or that the MD side IPL is even calling it.Mask of Destiny wrote:I was thinking along the same lines, but the first thing his code does is mask all interrupts with move #2700, sr. Is he unmasking them somewhere that I've missed?
Also, since he isn't setting the Level 2 int bit to the CD as part of a vertical blank on the MD side, the CD is failing pretty quick, and who knows what the word ram does when the CD crashes.
The CD isn't like the MD - you just can't turn off ints and pretend nothing is going to happen. You have to have a lot of infrastructure for the program or it's going to fail in unexpected ways. Hence the reason I posted an entire working example.
Well, if you know what you're doing, you COULD pretend the CD isn't there, but you'd need to disable the CD, which also means not using the word ram. Basically, if you know enough to do that, you wouldn't be doing it anyway.
I used the latest, it's not working.Chilly Willy wrote:First, there were a couple errors in old versions of the boot loader. Make sure you use the latest:
http://www.mediafire.com/download/bh384 ... 0130331.7z
I did not used your example has a base, I just used your loader, and it seems there is a bug inside, because it can't find the "APP.BIN" file.Chilly Willy wrote: Second, make sure that whatever example you work from compiles and works for you before you try altering it for your own usage. Here's the libpcm and the latest cd mod player source:
I'm using mkisofs like this:
mkisofs -iso-level 1 -o filesystem.iso -pad rootdir
ok, that was the problem, now it works perfectly (with Luke_ProjectCD.zip boot loader), thank youChilly Willy wrote: Finally, in the code you posted, you are still clearing ALL the MD ram...
Retro game programming !
-
- Interested
- Posts: 24
- Joined: Wed Feb 03, 2010 12:53 am
- Location: Grimsby, England
Just so you know, my loader (Luke_ProjectCD) does still have some issues.
It's mostly okay for an application that will start and then never touch the CD Hardware again (I left Columns running for a few hours on a EU Mega CD Model 1 to test stability) however, as it doesn't trigger the correct interrupts, it does cause the Mega CD hardware to die after a short period of time.
It can quite easily be fixed, but I'm busy with other projects this moment in time.
It's mostly okay for an application that will start and then never touch the CD Hardware again (I left Columns running for a few hours on a EU Mega CD Model 1 to test stability) however, as it doesn't trigger the correct interrupts, it does cause the Mega CD hardware to die after a short period of time.
It can quite easily be fixed, but I'm busy with other projects this moment in time.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
My loader clearly DOES find "APP.BIN" as that's what I call the mod player in the example. One limitation on the loader is the app to load needs to be in the root directory of the CD, not a subdirectory. Other than that, it can be anywhere in the root with any name (you must match the name in the loader - so if you wish to use a different name, you would need to recompile the loader). Note also that ISO9660 names are all uppercase. Trying to load "app.bin" would fail.
Beyond that, my loader requires the loaded app to start at 0x8000 in the CD ram. If you look at the link script, you'd see that. Maybe you're not using the proper ld script for your app when trying to use my loader. Also note that my loader has a MD IPL that runs a loop looking for certain commands. You MUST use those commands the way they were written for or it doesn't work. Again, it's all in the example mod player.
Beyond that, my loader requires the loaded app to start at 0x8000 in the CD ram. If you look at the link script, you'd see that. Maybe you're not using the proper ld script for your app when trying to use my loader. Also note that my loader has a MD IPL that runs a loop looking for certain commands. You MUST use those commands the way they were written for or it doesn't work. Again, it's all in the example mod player.