Mega Drive to Mega CD?
Moderator: Mask of Destiny
Mega Drive to Mega CD?
Hi guys.
I'm created a Mega drive game (very buggy, at the moment =P), but I need convert to Mega CD. My problem is, I have no a minimal idea how to do this. I want convert it to Mega CD, and make use some MP3 songs.
Anyone can/want help me?
(This post MAY contain bad grammar)
I'm created a Mega drive game (very buggy, at the moment =P), but I need convert to Mega CD. My problem is, I have no a minimal idea how to do this. I want convert it to Mega CD, and make use some MP3 songs.
Anyone can/want help me?
(This post MAY contain bad grammar)
skype: hcktrox
-
- Interested
- Posts: 24
- Joined: Wed Feb 03, 2010 12:53 am
- Location: Grimsby, England
This is no easy task, there is very little addressable memory available.
It is possible though, you would need to split your game into 256kb modules that can be loaded into RAM from CD when needed, as well as adjust the memory map not to clash with the jump table for the bios. The details of the map can be found in the official documentation that should be floating around on the web.
Here, is an incomplete template for a Sega/MegaCD game. It currently stands as a bootloader, with programs for the main and sub cpu's.
It supports parsing the ISO filesystem, for loading files from CD, and executing them, so at this stage is very simple.
I included the CD Port of Columns, just as a test program for the bootloader. I did comment extensively though, so, I suggest giving it a read through.
A build script is included, which also calls a custom program to trim the output from MKISOFS and merge the generated filesystem with the boot code, making the compilation seamless.
Default region is JAP, but, all security sectors are included. You would need to edit IP.ASM to include the correct file for your target region
http://www.megaupload.com/?d=61UDIN52
I apologise for Megaupload, I do not have my own host at this point in time.
Warning: I am NOT an experienced coder, so things could probably be more optimised and be done in a better way, keep that in mind.
It is possible though, you would need to split your game into 256kb modules that can be loaded into RAM from CD when needed, as well as adjust the memory map not to clash with the jump table for the bios. The details of the map can be found in the official documentation that should be floating around on the web.
Here, is an incomplete template for a Sega/MegaCD game. It currently stands as a bootloader, with programs for the main and sub cpu's.
It supports parsing the ISO filesystem, for loading files from CD, and executing them, so at this stage is very simple.
I included the CD Port of Columns, just as a test program for the bootloader. I did comment extensively though, so, I suggest giving it a read through.
A build script is included, which also calls a custom program to trim the output from MKISOFS and merge the generated filesystem with the boot code, making the compilation seamless.
Default region is JAP, but, all security sectors are included. You would need to edit IP.ASM to include the correct file for your target region
http://www.megaupload.com/?d=61UDIN52
I apologise for Megaupload, I do not have my own host at this point in time.
Warning: I am NOT an experienced coder, so things could probably be more optimised and be done in a better way, keep that in mind.
WOW!
congratulations, you did exactly what I was about to start
very well done, and thanks for the comments
a must !
I mirrored it to http://gendev.spritesmind.net/files/mcd ... jectCD.zip
congratulations, you did exactly what I was about to start
very well done, and thanks for the comments
a must !
I mirrored it to http://gendev.spritesmind.net/files/mcd ... jectCD.zip
-
- Interested
- Posts: 24
- Joined: Wed Feb 03, 2010 12:53 am
- Location: Grimsby, England
In order to use Stef's devkit with this, you would first have to recompile the library and remove all unneccessary functions, since on the Sega CD you are limited to 256KB maximum program code loaded in RAM at once, also, the memory map is completely different.
Program code is mapped from $200000 to $23FFFF on the Megadrive side, and also the Vector table is relocated from $0 to $FFFD00-$FFFDFF in RAM, so edits are still possible, but this also means you lose this area of RAM.
The Sega CD official documents state not to use RAM about $FFFD00 for your own data storage for this reason, but, to my knowledge, using ram above the vector table shouldn't be an issue.
So, the following steps are needed to use Stef's devkit with the Sega CD:
1. Recompile the inclue library to only have essential functions, to minimise binary size
2. Prevent the Sega startup program from being linked in, it is no longer needed as the Sega CD BIOS handles this.
3. Split game program into 256KB chunks, these are your prg files, that can be loaded into RAM from CD when needed
4. Create your own md.ld file, using Stef's one as a template, altering the memory map to have your program code area defined as $200000, $23FFFF and your RAM to be at $FF0000 - $FFFD00
5. Create a new makefile to use this new information
Note: Because the game has to be in 256KB chunks but share the same ram-space, you can't rely on C's compiler to ensure the memory map matches between binarys, as they are seen as completely seperate programs. This means that you may have to just create pointers and map them directly to RAM addresses and create the memory map yourself, to ensure they are always at the same location.
That should work, however I have not yet tested this, I was thinking about doing this in the future, but at this point I have no need for it. Somebody with more experience in this area may be able to give more details, I know Fonzie has a Sega CD ld file on his site, as well as some downloadable Sega CD source code, but it's for the XGCC compiler, and not Stef's devkit.
Program code is mapped from $200000 to $23FFFF on the Megadrive side, and also the Vector table is relocated from $0 to $FFFD00-$FFFDFF in RAM, so edits are still possible, but this also means you lose this area of RAM.
The Sega CD official documents state not to use RAM about $FFFD00 for your own data storage for this reason, but, to my knowledge, using ram above the vector table shouldn't be an issue.
So, the following steps are needed to use Stef's devkit with the Sega CD:
1. Recompile the inclue library to only have essential functions, to minimise binary size
2. Prevent the Sega startup program from being linked in, it is no longer needed as the Sega CD BIOS handles this.
3. Split game program into 256KB chunks, these are your prg files, that can be loaded into RAM from CD when needed
4. Create your own md.ld file, using Stef's one as a template, altering the memory map to have your program code area defined as $200000, $23FFFF and your RAM to be at $FF0000 - $FFFD00
5. Create a new makefile to use this new information
Note: Because the game has to be in 256KB chunks but share the same ram-space, you can't rely on C's compiler to ensure the memory map matches between binarys, as they are seen as completely seperate programs. This means that you may have to just create pointers and map them directly to RAM addresses and create the memory map yourself, to ensure they are always at the same location.
That should work, however I have not yet tested this, I was thinking about doing this in the future, but at this point I have no need for it. Somebody with more experience in this area may be able to give more details, I know Fonzie has a Sega CD ld file on his site, as well as some downloadable Sega CD source code, but it's for the XGCC compiler, and not Stef's devkit.
Thanks for all the help, I am trying it and this is what I've gotten so far. I copied the md.ld and makefile and modified them to reflect the new memory map, and remove the sega.s file.
Here's what I changed to the best of my knowledge:
...
...
I did also removed some stuff I don't need but my ROM is way less than 128 KB for the time being, so it is not an issue yet.
I tested it, and it simply rebooted. I then went to dissassemble my code.. and figured that most probably the entry point is my issue here. I do need teh sega.s file to go to _start_entry and then jump to my main() function. So I went ahead and created a copy of sega.s and modified it...
I am getting some errors, I guess I need to understand it a bit better. So far I changed
.org 0x00000000 to .org 0x00200000
and modified the stack to 0x00fffcff, removed to the best of my knowledge the cartridge init routines... but I get a
0x41cc1e of out/romscd.out section .text is not within region rom..
I guessed that was because of the .org I changed, moved it back to 0.. but it is still rebooting. Will continue exploring this and post here if I get any positive results.
Here's what I changed to the best of my knowledge:
Code: Select all
MEMORY
{
rom : ORIGIN = 0x00200000, LENGTH = 0x0003ffff
ram : ORIGIN = 0x00ff0000, LENGTH = 0x0000fcff
}
/*
* allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0x00fffcff);
Code: Select all
SECTIONS
{
.text 0x00200000:
{
*(.text)
Code: Select all
.bss 0x00ff0000:
{
__bss_start = . ;
I tested it, and it simply rebooted. I then went to dissassemble my code.. and figured that most probably the entry point is my issue here. I do need teh sega.s file to go to _start_entry and then jump to my main() function. So I went ahead and created a copy of sega.s and modified it...
I am getting some errors, I guess I need to understand it a bit better. So far I changed
.org 0x00000000 to .org 0x00200000
and modified the stack to 0x00fffcff, removed to the best of my knowledge the cartridge init routines... but I get a
0x41cc1e of out/romscd.out section .text is not within region rom..
I guessed that was because of the .org I changed, moved it back to 0.. but it is still rebooting. Will continue exploring this and post here if I get any positive results.
Stack won't work at an odd address.
Try this instead:
Try this instead:
Code: Select all
PROVIDE (__stack = 0x00fffd00);
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
You want something like this:
Note that the word ram IS ram, so you could put the data and bss in word ram as well.
The
Links the code to run at 0x200000, but it's in the file at offset 0. If you don't set the load address to 0, you get 2MB of filler at the start of the file. Same for the
That puts initialized data right after the code, but linked to be in ram. You have to copy the data to ram as part of the crt0.s file, like this
Note that if you put the data into word ram instead of work ram, you don't have to copy the data - it would already be where it needed to be. You would still have to clear the bss region.
Code: Select all
OUTPUT_ARCH(m68k)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* The memory map look like this:
* +--------------------+ <- 0x00200000
* | .text |
* | _etext |
* | ctor list | the ctor and dtor lists are for
* | dtor list | C++ support
* +--------------------+ <- 0x00240000
* . .
* . .
* . .
* +--------------------+ <- 0x00FF0000
* | .data | initialized data goes here
* | _edata |
* +--------------------+
* | .bss |
* | __bss_start | start of bss, cleared by crt0
* | _end | start of heap, used by sbrk()
* +--------------------+
* . .
* . .
* . .
* | __stack | top of stack
* +--------------------+ <- 0x00FFFD00
*/
MEMORY
{
wram (wx) : ORIGIN = 0x00200000, LENGTH = 0x00040000
ram (wx) : ORIGIN = 0x00FF0000, LENGTH = 0x0000FD00
}
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0x00FFFD00);
SECTIONS
{
.text 0x00200000 :
AT ( 0x00000000 )
{
*(.text .text.*)
. = ALIGN(0x4);
__CTOR_LIST__ = .;
___CTOR_LIST__ = .;
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
*(.ctors)
LONG(0)
__CTOR_END__ = .;
__DTOR_LIST__ = .;
___DTOR_LIST__ = .;
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
*(.dtors)
LONG(0)
__DTOR_END__ = .;
*(.rodata .rodata.*)
*(.gcc_except_table)
. = ALIGN(0x2);
__INIT_SECTION__ = . ;
LONG (0x4E560000) /* linkw %fp,#0 */
*(.init)
SHORT (0x4E5E) /* unlk %fp */
SHORT (0x4E75) /* rts */
__FINI_SECTION__ = . ;
LONG (0x4E560000) /* linkw %fp,#0 */
*(.fini)
SHORT (0x4E5E) /* unlk %fp */
SHORT (0x4E75) /* rts */
_etext = .;
*(.lit)
} > wram
_stext = SIZEOF (.text);
.data 0x00FF0000 :
AT ( LOADADDR (.text) + SIZEOF (.text) )
{
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.*)
_edata = .;
} > ram
_sdata = SIZEOF (.data);
.bss 0x00FF0000 + SIZEOF (.data) :
{
. = ALIGN(0x4);
__bss_start = . ;
*(.shbss)
*(.bss .bss.*)
*(COMMON)
_end = ALIGN (0x8);
__end = _end;
end = _end;
} > ram
.stab 0 (NOLOAD) :
{
*(.stab)
}
.stabstr 0 (NOLOAD) :
{
*(.stabstr)
}
.eh_frame 0 (NOLOAD) :
{
*(.eh_frame)
}
}
The
Code: Select all
.text 0x00200000 :
AT ( 0x00000000 )
Code: Select all
.data 0x00FF0000 :
AT ( LOADADDR (.text) + SIZEOF (.text) )
Code: Select all
initialize:
move #0x2700,sr /* interrupts disabled */
lea __stack,a0
movea.l a0,sp /* set stack pointer to top of Work RAM */
| Clear Work RAM (0xFF0000 to 0xFFFCFF)
lea 0xFF0000,a0
moveq #0,d0
move.w #0x3F3F,d1
1:
move.l d0,(a0)+
dbra d1,1b
| Copy initialized variables from ROM to Work RAM
lea _stext,a0
adda.l #0x00200000,a0
lea 0xFF0000,a1
move.l #_sdata,d0
lsr.l #1,d0
subq.w #1,d0
2:
move.w (a0)+,(a1)+
dbra d0,2b
jsr main /* call main() */
jmp initialize.l
Still experimenting, thanks for all the information Chilly Willy, I still haven't managed to make it work with all your information. The sega.s file on the Mini SDK has several more things that might be needed I guess. I did try with your asm code, but it somehow managed to go to 0x0000000 and started executing form there.
-
- Interested
- Posts: 24
- Joined: Wed Feb 03, 2010 12:53 am
- Location: Grimsby, England
Thanks, I'll do just that. However I've gone through several versions and modifications, these are just my current tests. Here is the original one from the mini devkit:
Here's what my first attempt looked like:
And tried also just:
I must be honest, although I know some 8086 asm, I don't know 68000 and have just been guessing at it... I am interested on learning it later on.
I've used a modified md.ld and also the one posted above by Chilly Willy.
Code: Select all
.text
*-------------------------------------------------------
*
* Sega startup code for the GNU Assembler
* Translated from:
* Sega startup code for the Sozobon C compiler
* Written by Paul W. Lee
* Modified from Charles Coty's code
* Modified from Stephane Dallongeville's code
*
*-------------------------------------------------------
.org 0x00000000
_Start_Of_Rom:
_Vecteurs_68K:
dc.l 0x00FFFE00 /* Stack address */
dc.l _Entry_Point /* Program start address */
dc.l _Bus_Error
dc.l _Address_Error
dc.l _Illegal_Instruction
dc.l _Zero_Divide
dc.l _Chk_Instruction
dc.l _Trapv_Instruction
dc.l _Privilege_Violation
dc.l _Trace
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, _INT, _INT
dc.l _HBL
dc.l _INT
dc.l _VBL
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
_Console:
.ascii "SEGA MEGA DRIVE " /* Console Name (16) */
_Copyright:
.ascii "(C)FLEMTEAM 2011" /* Copyright Information (16) */
_Title_Local:
.ascii "SAMPLE PROGRAM " /* Domestic Name (48) */
_Title_Int:
.ascii "SAMPLE PROGRAM " /* Overseas Name (48) */
_Serial:
.ascii "GM 00000000-00" /* Serial Number (2, 14) */
_Checksum:
dc.w 0x0000 /* Checksum (2) */
.ascii "JD " /* I/O Support (16) */
_Rom_Start_Loc:
dc.l _Start_Of_Rom /* ROM Start Address (4) */
_Rom_End_Loc:
dc.l 0x00020000 /* ROM End Address (4) */
_Ram_Start_Loc:
dc.l 0x00FF0000 /* Start of Backup RAM (4) */
_Ram_End_Loc:
dc.l 0x00FFFFFF /* End of Backup RAM (4) */
.ascii " " /* Modem Support (12) */
_Notes:
.ascii "DEMONSTRATION PROGRAM " /* Memo (40) */
_Region:
.ascii "JUE " /* Country Support (16) */
_Entry_Point:
tst.l 0xa10008
bne.s SkipJoyDetect
tst.w 0xa1000c
SkipJoyDetect:
bne.s SkipSetup
move #0x2700,%sr
lea Table,%a5
movem.w (%a5)+,%d5-%d7
movem.l (%a5)+,%a0-%a4
* Check Version Number
move.b -0x10ff(%a1),%d0
andi.b #0x0f,%d0
beq.s WrongVersion
* Sega Security Code (SEGA)
move.l #0x53454741,0x2f00(%a1)
WrongVersion:
move.w (%a4),%d0
moveq #0x00,%d0
movea.l %d0,%a6
move %a6,%usp
jmp Continue
Table:
dc.w 0x8000,0x3fff,0x0100
dc.l 0xA00000,0xA11100,0xA11200,0xC00000,0xC00004
SkipSetup:
move.w #0,%a7
move.w #0x2300,%sr
jmp _reset_entry
Continue:
* clear Genesis RAM
lea 0xff0000,%a0
moveq #0,%d0
move.w #0x3FFF,%d1
clrram:
move.l %d0,(%a0)+
dbra %d1,clrram
move.w #0,%a7
move.w #0x2300,%sr
* Jump to initialisation process...
jmp _start_entry
*------------------------------------------------
*
* interrupt functions
*
*------------------------------------------------
.text
_Bus_Error:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _buserror_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Address_Error:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _addresserror_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Illegal_Instruction:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _illegalinst_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Zero_Divide:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _zerodivide_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Chk_Instruction:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _chkinst_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Trapv_Instruction:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _trapvinst_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Privilege_Violation:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _privilegeviolation_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Trace:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _trace_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Line_1010_Emulation:
_Line_1111_Emulation:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _line1x1x_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_Error_Exception:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _errorexception_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_INT:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _int_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_HBL:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _hblank_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
_VBL:
movem.l %d0-%d1/%a0-%a1,-(%sp)
jsr _vblank_callback
movem.l (%sp)+,%d0-%d1/%a0-%a1
rte
*------------------------------------------------
*
* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to redistribute it freely, with the
* following restrictions:
* 1) No charge may be made other than reasonable charges for reproduction.
* 2) Modified versions must be clearly marked as such.
* 3) The authors are not responsible for any harmful consequences
* of using this software, even if they result from defects in it.
*
*------------------------------------------------
ldiv:
move.l 4(%a7),%d0
bpl ld1
neg.l %d0
ld1:
move.l 8(%a7),%d1
bpl ld2
neg.l %d1
eor.b #0x80,4(%a7)
ld2:
bsr i_ldiv /* d0 = d0/d1 */
tst.b 4(%a7)
bpl ld3
neg.l %d0
ld3:
rts
lmul:
move.l 4(%a7),%d0
bpl lm1
neg.l %d0
lm1:
move.l 8(%a7),%d1
bpl lm2
neg.l %d1
eor.b #0x80,4(%a7)
lm2:
bsr i_lmul /* d0 = d0*d1 */
tst.b 4(%a7)
bpl lm3
neg.l %d0
lm3:
rts
lrem:
move.l 4(%a7),%d0
bpl lr1
neg.l %d0
lr1:
move.l 8(%a7),%d1
bpl lr2
neg.l %d1
lr2:
bsr i_ldiv /* d1 = d0%d1 */
move.l %d1,%d0
tst.b 4(%a7)
bpl lr3
neg.l %d0
lr3:
rts
ldivu:
move.l 4(%a7),%d0
move.l 8(%a7),%d1
bsr i_ldiv
rts
lmulu:
move.l 4(%a7),%d0
move.l 8(%a7),%d1
bsr i_lmul
rts
lremu:
move.l 4(%a7),%d0
move.l 8(%a7),%d1
bsr i_ldiv
move.l %d1,%d0
rts
*
* A in d0, B in d1, return A*B in d0
*
i_lmul:
move.l %d3,%a2 /* save d3 */
move.w %d1,%d2
mulu %d0,%d2 /* d2 = Al * Bl */
move.l %d1,%d3
swap %d3
mulu %d0,%d3 /* d3 = Al * Bh */
swap %d0
mulu %d1,%d0 /* d0 = Ah * Bl */
add.l %d3,%d0 /* d0 = (Ah*Bl + Al*Bh) */
swap %d0
clr.w %d0 /* d0 = (Ah*Bl + Al*Bh) << 16 */
add.l %d2,%d0 /* d0 = A*B */
move.l %a2,%d3 /* restore d3 */
rts
*
*A in d0, B in d1, return A/B in d0, A%B in d1
*
i_ldiv:
tst.l %d1
bne nz1
* divide by zero
* divu #0,%d0 /* cause trap */
move.l #0x80000000,%d0
move.l %d0,%d1
rts
nz1:
move.l %d3,%a2 /* save d3 */
cmp.l %d1,%d0
bhi norm
beq is1
* A<B, so ret 0, rem A
move.l %d0,%d1
clr.l %d0
move.l %a2,%d3 /* restore d3 */
rts
* A==B, so ret 1, rem 0
is1:
moveq.l #1,%d0
clr.l %d1
move.l %a2,%d3 /* restore d3 */
rts
* A>B and B is not 0
norm:
cmp.l #1,%d1
bne not1
* B==1, so ret A, rem 0
clr.l %d1
move.l %a2,%d3 /* restore d3 */
rts
* check for A short (implies B short also)
not1:
cmp.l #0xffff,%d0
bhi slow
* A short and B short -- use 'divu'
divu %d1,%d0 /* d0 = REM:ANS */
swap %d0 /* d0 = ANS:REM */
clr.l %d1
move.w %d0,%d1 /* d1 = REM */
clr.w %d0
swap %d0
move.l %a2,%d3 /* restore d3 */
rts
* check for B short
slow:
cmp.l #0xffff,%d1
bhi slower
* A long and B short -- use special stuff from gnu
move.l %d0,%d2
clr.w %d2
swap %d2
divu %d1,%d2 /* d2 = REM:ANS of Ahi/B */
clr.l %d3
move.w %d2,%d3 /* d3 = Ahi/B */
swap %d3
move.w %d0,%d2 /* d2 = REM << 16 + Alo */
divu %d1,%d2 /* d2 = REM:ANS of stuff/B */
move.l %d2,%d1
clr.w %d1
swap %d1 /* d1 = REM */
clr.l %d0
move.w %d2,%d0
add.l %d3,%d0 /* d0 = ANS */
move.l %a2,%d3 /* restore d3 */
rts
* A>B, B > 1
slower:
move.l #1,%d2
clr.l %d3
moreadj:
cmp.l %d0,%d1
bhs adj
add.l %d2,%d2
add.l %d1,%d1
bpl moreadj
* we shifted B until its >A or sign bit set
* we shifted #1 (d2) along with it
adj:
cmp.l %d0,%d1
bhi ltuns
or.l %d2,%d3
sub.l %d1,%d0
ltuns:
lsr.l #1,%d1
lsr.l #1,%d2
bne adj
* d3=answer, d0=rem
move.l %d0,%d1
move.l %d3,%d0
move.l %a2,%d3 /* restore d3 */
rts
Code: Select all
.text
*-------------------------------------------------------
*
* Sega startup code for the GNU Assembler
* Translated from:
* Sega startup code for the Sozobon C compiler
* Written by Paul W. Lee
* Modified from Charles Coty's code
* Modified from Stephane Dallongeville's code
*
*-------------------------------------------------------
.org 0x00000000
_Start_Of_Rom:
_Vecteurs_68K:
dc.l 0x00FFFE00 /* Stack address */
dc.l _Entry_Point /* Program start address */
dc.l _Bus_Error
dc.l _Address_Error
dc.l _Illegal_Instruction
dc.l _Zero_Divide
dc.l _Chk_Instruction
dc.l _Trapv_Instruction
dc.l _Privilege_Violation
dc.l _Trace
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, _INT, _INT
dc.l _HBL
dc.l _INT
dc.l _VBL
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
_Entry_Point:
tst.l 0xa10008
bne.s SkipJoyDetect
tst.w 0xa1000c
SkipJoyDetect:
bne.s SkipSetup
move #0x2700,%sr
lea Table,%a5
movem.w (%a5)+,%d5-%d7
movem.l (%a5)+,%a0-%a4
jmp Continue
Table:
dc.w 0x8000,0x3fff,0x0100
dc.l 0xA00000,0xA11100,0xA11200,0xC00000,0xC00004
SkipSetup:
move.w #0,%a7
move.w #0x2300,%sr
jmp _reset_entry
Continue:
* clear Genesis RAM
lea 0xff0000,%a0
moveq #0,%d0
move.w #0x3F3F,%d1
clrram:
move.l %d0,(%a0)+
dbra %d1,clrram
move.w #0,%a7
move.w #0x2300,%sr
* Jump to initialisation process...
jmp _start_entry
(I left the next lines unmodifided)
Code: Select all
.text
*-------------------------------------------------------
*
* Sega startup code for the GNU Assembler
* Translated from:
* Sega startup code for the Sozobon C compiler
* Written by Paul W. Lee
* Modified from Charles Coty's code
* Modified from Stephane Dallongeville's code
*
*-------------------------------------------------------
.org 0x00000000
_Start_Of_Rom:
_Vecteurs_68K:
dc.l 0x00FFFE00 /* Stack address */
dc.l _Entry_Point /* Program start address */
dc.l _Bus_Error
dc.l _Address_Error
dc.l _Illegal_Instruction
dc.l _Zero_Divide
dc.l _Chk_Instruction
dc.l _Trapv_Instruction
dc.l _Privilege_Violation
dc.l _Trace
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, _INT, _INT
dc.l _HBL
dc.l _INT
dc.l _VBL
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
_Entry_Point:
move #0x2700,%sr /* interrupts disabled */
lea __stack,%a0
movea.l %a0,%sp /* set stack pointer to top of Work RAM */
* Clear Work RAM (0xFF0000 to 0xFFFCFF)
lea 0xFF0000,%a0
moveq #0,%d0
move.w #0x3F3F,%d1
cram:
move.l %d0,(%a0)+
dbra %d1,cram
* Copy initialized variables from ROM to Work RAM
lea _stext,%a0
adda.l #0x00200000,%a0
lea 0xFF0000,%a1
move.l #_sdata,%d0
lsr.l #1,%d0
subq.w #1,%d0
exec:
move.w (%a0)+,(%a1)+
dbra %d0,exec
jsr _start_entry /* call main() */
jmp _Entry_Point
(with the rest of the file from then on)
I've used a modified md.ld and also the one posted above by Chilly Willy.
And the mcd.ld I derived from the original md.ld included on the devkit.
Code: Select all
OUTPUT_ARCH(m68k)
SEARCH_DIR(.)
/*GROUP(-lbcc -lc -lgcc)*/
__DYNAMIC = 0;
/*
* Setup the memory map of the SEGA Genesis.
* stack grows down from high memory.
*
* The memory map look like this:
* +--------------------+ <- low memory
* | .text |
* | _etext |
* | ctor list | the ctor and dtor lists are for
* | dtor list | C++ support
* +--------------------+
* | .data | initialized data goes here
* | _data |
* | _edata |
* +--------------------+
* | .bss |
* | _bstart | start of bss, cleared by crt0
* | _bend | start of heap, used by sbrk()
* | __bss_start | start of bss, cleared by crt0
* | _end | start of heap, used by sbrk()
* +--------------------+
* . .
* . .
* . .
* | __stack | top of stack
* +--------------------+
*/
MEMORY
{
rom : ORIGIN = 0x00200000, LENGTH = 0x0003FFFF
ram : ORIGIN = 0x00ff0000, LENGTH = 0x0000FE00
}
/*
* allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0x00fffe00);
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we cover a.out (which prepends
* an underscore) and coff object file formats.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (_hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
PROVIDE (_software_init_hook = 0);
SECTIONS
{
.text 0x00200000:
{
*(.text)
. = ALIGN(0x4);
__CTOR_LIST__ = .;
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
*(.ctors)
LONG(0)
__CTOR_END__ = .;
__DTOR_LIST__ = .;
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
*(.dtors)
LONG(0)
__DTOR_END__ = .;
*(.rodata*)
*(.gcc_except_table)
__INIT_SECTION__ = . ;
*(.init)
SHORT (0x4e75) /* rts */
__FINI_SECTION__ = . ;
*(.fini)
SHORT (0x4e75) /* rts */
_etext = .;
*(.lit)
} > rom
_stext = SIZEOF (.text);
.data BLOCK (0x4) :
{
*(.shdata)
*(.data)
_edata = .;
} > ram
_sdata = SIZEOF (.data);
.bss 0xff0000 :
{
__bss_start = . ;
*(.shbss)
*(.bss)
*(COMMON)
*(.eh_fram)
*(.eh_frame)
_end = ALIGN (0x8);
__end = _end;
} > ram
.stab 0 (NOLOAD) :
{
*(.stab)
}
.stabstr 0 (NOLOAD) :
{
*(.stabstr)
}
}
-
- Interested
- Posts: 24
- Joined: Wed Feb 03, 2010 12:53 am
- Location: Grimsby, England
You will want to remove the entire vectors section from your modified Sega.s so that the code simply starts at entry_point.
Otherwise it would try to execute that data as code.
The vector table is now located at $FFFD00 in RAM, so, directly after the _Entry_Point: line, you would have to write code to load the address of your HBL and VBL routines to this table, I can't remember the exact format, so you would have to look this up in the official Sega CD documentation.
The code will also have to be ".org"'d to 0x00200000
Otherwise it would try to execute that data as code.
The vector table is now located at $FFFD00 in RAM, so, directly after the _Entry_Point: line, you would have to write code to load the address of your HBL and VBL routines to this table, I can't remember the exact format, so you would have to look this up in the official Sega CD documentation.
The code will also have to be ".org"'d to 0x00200000
OK... I just removed the vector table, and ran it.. it is loading.. but I do need to load the HBL and VBL.. will figure that out then next. What i do know now is that it is executing from the correct address.
It is now loading the font and palettes, but that's all for now. Great advance anyway =)
If I moved org to 0x00200000, I was getting out of rom range again.. I assume since it is inside .text it works alright.
Thanks for the help!
EDIT:
Just checked the VDP RAM on Gens, and the font is being loaded incorrectly... If I look at the CD Word RAM the tiles are there correctly, but not on the VDP:
Uploaded with ImageShack.us[/img]
It is now loading the font and palettes, but that's all for now. Great advance anyway =)
If I moved org to 0x00200000, I was getting out of rom range again.. I assume since it is inside .text it works alright.
Thanks for the help!
EDIT:
Just checked the VDP RAM on Gens, and the font is being loaded incorrectly... If I look at the CD Word RAM the tiles are there correctly, but not on the VDP:
Uploaded with ImageShack.us[/img]