Mega Drive to Mega CD?

Ask anything your want about Mega/SegaCD programming.

Moderator: Mask of Destiny

Artemio
Interested
Posts: 22
Joined: Fri Jan 07, 2011 7:04 pm
Location: Mexico
Contact:

Post by Artemio » Sun Mar 13, 2011 10:13 am

OK, it is still not working. I've learned a lot more about 68asm today, and played a bit more with it, however it is still crashing hard. I now know my code is being loaded and executed, however tiles are somehow misaligned on VRAM as posted above.

Here's my segacd.s code, which is loaded at 0x0200000:

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

_Entry_Point:        
        move    #0x2700,%sr              /* interrupts disabled */    

        lea     __stack,%a0
        movea.l %a0,%sp                   /* set stack pointer to top of Work RAM */

* 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

* Clear Work RAM (0xFF0000 to 0xFFFCFF)
        lea     0xFF0000,%a0
        moveq   #0,%d0
        move.w  #0x3F3F,%d1
cram:
        move.l  %d0,(%a0)+
        dbra    %d1,cram       

* Init z80 ?
        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

continue:

* copy interrupt vector (?)
        move.l  #0xFFFD00, %a1
        lea     _Bus_Error, %a2
        move.l  %a2,(%a1)+
        lea     _Address_Error, %a2
        move.l  %a2,(%a1)+
        lea     _Illegal_Instruction, %a2
        move.l  %a2,(%a1)+
        lea     _Zero_Divide, %a2
        move.l  %a2,(%a1)+
        lea     _Chk_Instruction, %a2
        move.l  %a2,(%a1)+
        lea     _Trapv_Instruction, %a2
        move.l  %a2,(%a1)+
        lea     _Privilege_Violation, %a2
        move.l  %a2,(%a1)+
        lea     _Trace, %a2
        move.l  %a2,(%a1)+
        lea     _Line_1010_Emulation, %a2
        move.l  %a2,(%a1)+
        lea     _Line_1111_Emulation, %a2
        move.l  %a2,(%a1)+

        lea     _Error_Exception, %a2
        move.w  #0x0c,%d1     /* x 13 */
copyee:
        move.l  %a2,(%a1)+        
        dbra    %d1,copyee        

        lea     _INT, %a2   
        move.w  #0x02,%d1     /* x 3 */
copyint:
        move.l  %a2,(%a1)+
        dbra    %d1,copyint

        lea     _HBL, %a2
        move.l  %a2,(%a1)+
        lea     _INT, %a2
        move.l  %a2,(%a1)+
        lea     _VBL, %a2
        move.l  %a2,(%a1)+
        lea     _INT, %a2
        move.w  #0x20,%d1     /* x 33 */        
copyint2:
        move.l  %a2,(%a1)+
        dbra    %d1,copyint2

*If we restore interrupt state or move it to 0x2300 the whole thing crashes

        jmp     _start_entry                    /* call start entry which calls main() */        

(original interrupt code follows)
It is hanging later on the code, on the function at address 0x002169ba (I know which function it is, but it obviously is because of other factors since it runs correctly when loaded via a cartridge).

As you can see I tried loading the vector table to the best of my knowledge to address 0xFFFD00, which is supposedly the area it should be loaded to. This of course was just an assumption and my n00bish attempt at doing so. I have dumped the RAM with Gens without doing it and doing it, and if I don't it is simply filled with zeroes.

It makes no difference if I load that, it crashes exactly in the same way. I have not found any solid information on this, or haven't been able to interpret it correctly.

I've also tried loading the stack pointer and the Entry point in there, to make a nice block in RAM from FD00 to FE00 (like that would help).

Here is a screenshot that shows two areas from the VDP RAM, the right side is when the code is compiled and running from the cart and the left part is when using this code.

Image

Uploaded with ImageShack.us

Any help is more than welcome.

As documented in the code above, if I try to store 0x2300 to the SR it crashes, and won't run the rest of the code (as the original sega.s did).

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

Post by Chilly Willy » Sun Mar 13, 2011 6:53 pm

You need to clear the work ram BEFORE you move the data. Clearing the work ram AFTER just erases the data you just moved.

EDIT: A question - are you DMAing the data to the vram, or using the CPU?

Artemio
Interested
Posts: 22
Joined: Fri Jan 07, 2011 7:04 pm
Location: Mexico
Contact:

Post by Artemio » Mon Mar 14, 2011 12:51 am

Changed the code to clear the RAM before, no difference there.

I am using DMA in my original Genesis code, from your question I take I shouldn't do that.

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

Post by Chilly Willy » Mon Mar 14, 2011 1:35 am

Well, you just need to watch out for little things... look at the Frog Feast DMA code:

Code: Select all

* D3 - Dest address  D4 - Size of data	D5 - Source address

DMAVRAM:

	movem.l d0-d7/a0-a4, -(a7)



	move.w	#0x0100, Z80Halt



	move.w	#0x8174, GfxReg

	move.w	#0x8F02, GfxReg



	* Set lower byte of length

	move.w	#0x9300, d0

	lsr.w	#1, d4

	or.b	d4, d0

	move.w	d0, GfxReg



	* Set upper byte of length

	move.w	#0x9400, d0

	lsr.w	#8, d4

	or.b	d4, d0

	move.w	d0, GfxReg



	* Set lower byte of source address ( >> 1)

	move.w	#0x9500, d0

	lsr.l	#1, d5

	or.b	d5, d0

	move.w	d0, GfxReg



	* Set mid byte of source address

	move.w	#0x9600, d0

	lsr.l	#8, d5

	or.b	d5, d0

	move.w	d0, GfxReg



	* Set upper byte of source address

	move.w	#0x9700, d0

	lsr.l	#8, d5

	or.b	d5, d0

	move.w	d0, GfxReg



	and.l	#0xFFFF, d3

	move.w	d3, d1

	and.w	#0x3FFF, d1

	or.w	#0x4000, d1

	asl.l	#8, d1

	asl.l	#8, d1



	lsr.w	#8, d3

	lsr.w	#6, d3

	and.w	#0x03, d3

	or.w	#0x80, d3

	or.l	d1, d3



	move.l	d3, TempValue

	* Set last of VRAM address. (Value from ram.)

	move.l	TempValue, GfxReg



	* Wait until dma finishes

	jsr		WaitDMA



	clr.w	Z80Halt



	movem.l (a7)+, d0-d7/a0-a4



	rts
See where it starts the DMA?

Code: Select all

	move.l	TempValue, GfxReg
You HAVE to move from RAM to the VDP to start the DMA. You can't just store to it directly from a register. There's little things like that you need to be aware of. You really should read the various SCD bulletins.

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

Post by TascoDLX » Mon Mar 14, 2011 11:05 am

Artemio wrote:As you can see I tried loading the vector table to the best of my knowledge to address 0xFFFD00, which is supposedly the area it should be loaded to. This of course was just an assumption and my n00bish attempt at doing so. I have dumped the RAM with Gens without doing it and doing it, and if I don't it is simply filled with zeroes.
It's not the vector table, it's a jump table, and you're better off not touching it at all. If you want to setup the VBlank routine, you can do this:

Code: Select all

lea     _VBL, %a1
jsr     0x0368

Artemio
Interested
Posts: 22
Joined: Fri Jan 07, 2011 7:04 pm
Location: Mexico
Contact:

Post by Artemio » Mon Mar 14, 2011 3:22 pm

Thanks for teh help, tiles are now being loaded correctly. However it is still crashing. I need to remove the jump table code I made, and add the VBLANK code described above. How could I set _HBL TascoDLX? I did find that bit of code at http://www.retrodev.com/segacdb.asm but it only had that and I couldn't find any info on it... Where can I read about that?

I also found this code:
http://devster.monkeeh.com/sega/basiegaxorz/src.html

Which sets teh jump table, I was playing around with it and adapting it... would that be ok?

Again, thanks for all the help.

Artemio
Interested
Posts: 22
Joined: Fri Jan 07, 2011 7:04 pm
Location: Mexico
Contact:

Post by Artemio » Tue Mar 15, 2011 4:00 am

Everything is working now, it seems that the problem was the DMA copy all along.. complicated by variations on the segacd.s code. Here's the final files that do work:

Code: Select all

.text

*-------------------------------------------------------
*
*       Sega CD startup code for the GNU Assembler
*
*-------------------------------------------------------

        .org    0x00000000

_Entry_Point:            
        move    #0x2700, %sr        /* interrupts */

* Clear Work RAM (0xFF0000 to 0xFFFCFF)
        lea     0xFF0000,%a0
        moveq   #0,%d0
        move.w  #0x3F3F,%d1
cram:
        move.l  %d0,(%a0)+
        dbra    %d1,cram        

* Enable VBlank
        lea     _VBL, %a1
        jsr     0x0368

        lea     Table,%a5
        movem.w (%a5)+,%d5-%d7
        movem.l (%a5)+,%a0-%a4    	      
        
        jmp     continue

Table:
        dc.w    0x8000, 0x3fff, 0x0100, 0x00a0, 0x0000, 0x00a1, 0x1100, 0x00a1
        dc.w    0x1200, 0x00c0, 0x0000, 0x00c0, 0x0004   

continue:                        
        lea     __stack,%a0
        movea.l %a0,%sp                   /* set stack pointer to top of Work RAM */

* restore interrupts
        and.w	  #0xF8FF, %sr
        jmp     _start_entry                    /* call main() */        

*------------------------------------------------
*
*       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
LD:

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  

  .data 0x00FF0000 :
  AT ( LOADADDR (.text) + SIZEOF (.text) )
  {
    *(.got.plt) *(.got)
    *(.shdata)
    *(.data .data.*)
    _edata = .;
  } > ram  

  .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)
  }
} 

I also copied and modified the dev kit makefile, so that I run different make commands for each. It integrates the build.bat file process:

Code: Select all

BIN= $(GDK)/bin
LIB= $(GDK)/lib

LIBSRC= $(GDK)/src
LIBINCLUDE= $(GDK)/include

ROM = romscd
SRC= src
RES= res
INCLUDE= include

TRIMFSIMG = $(SCD_LOADER)/trimfsimage
MKISOFS = $(SCD_LOADER)/mkisofs
ASM68K = $(SCD_LOADER)/ASM68K

SHELL=$(BIN)/sh
AR= $(BIN)/ar
CC= $(BIN)/gcc
OBJCPY= $(BIN)/objcopy
ASMZ80= $(BIN)/sjasm
MACCER= $(BIN)/mac68k
SIZEBND= $(BIN)/sizebnd
BINTOC= $(BIN)/bintoc
BINTOS= $(BIN)/bintos
WAVTORAW= $(BIN)/wavtoraw
GENRES= $(BIN)/genres
TFMCOM= $(BIN)/tfmcom
NM= $(BIN)/nm
RM= $(BIN)/rm
MKDIR= $(BIN)/mkdir
NM2WCH= $(BIN)/nm2wch


OPTION= -DSEGACD

SRC_C= $(wildcard *.c)
SRC_C+= $(wildcard $(SRC)/*.c)
SRC_S= $(wildcard *.s)
SRC_S+= $(wildcard $(SRC)/*.s)
SRC_SZ80= $(wildcard *.s80)
SRC_SZ80+= $(wildcard $(SRC)/*.s80)
RES_S= $(wildcard $(RES)/*.s)
RES_BMP= $(wildcard *.bmp)
RES_BMP+= $(wildcard $(RES)/*.bmp)
RES_RAW= $(wildcard *.raw)
RES_RAW+= $(wildcard $(RES)/*.raw)
RES_PCM= $(wildcard *.pcm)
RES_PCM+= $(wildcard $(RES)/*.pcm)
RES_TFD= $(wildcard *.tfd)
RES_TFD+= $(wildcard $(RES)/*.tfd)
RES_TFC= $(wildcard *.tfc)
RES_TFC+= $(wildcard $(RES)/*.tfc)
RES_WAV= $(wildcard *.wav)
RES_WAV+= $(wildcard $(RES)/*.wav)
RES_RC= $(wildcard *.rc)
RES_RC+= $(wildcard $(RES)/*.rc)
RES_ASM= $(wildcard *.asm)
RES_ASM+= $(wildcard $(RES)/*.asm)

OBJ= $(RES_BMP:.bmp=.o)
OBJ+= $(RES_WAV:.wav=.o)
OBJ+= $(RES_RC:.rc=.o)
OBJ+= $(RES_ASM:.asm=.o)
OBJ+= $(RES_RAW:.raw=.o)
OBJ+= $(RES_PCM:.pcm=.o)
OBJ+= $(RES_TFD:.tfd=.o)
OBJ+= $(RES_TFC:.tfc=.o)
OBJ+= $(RES_S:.s=.o)
OBJ+= $(SRC_SZ80:.s80=.o)
OBJ+= $(SRC_S:.s=.o)
OBJ+= $(SRC_C:.c=.o)

INCS= -I$(LIBINCLUDE) -I$(INCLUDE) -I$(RES)
FLAGS= $(OPTION) -m68000 -Wall -O1 -fomit-frame-pointer -fno-builtin-memset -fno-builtin-memcpy $(INCS)
FLAGSZ80= -i$(LIBSRC) -i$(LIBINCLUDE) -i$(SRC) -i$(INCLUDE) -i$(RES)

all: out/$(ROM).bin

default: all

.PHONY: clean

clean:
	$(RM) -f $(OBJ) out.lst out/$(ROM).nm out/$(ROM).wch out/$(ROM).out out/$(ROM).out

cleanobj:
	$(RM) -f $(OBJ) out.lst out/$(ROM).nm out/$(ROM).out

out/$(ROM).bin: out/$(ROM).out
	$(NM) -n -S -t x out/$(ROM).out >out/$(ROM).nm
	$(NM2WCH) out/$(ROM).nm out/$(ROM).wch
	$(OBJCPY) -O binary out/$(ROM).out out/$(ROM).bin
	$(SIZEBND) out/$(ROM).bin -sizealign 131072   
	$(OBJCPY) -O binary out/$(ROM).out $(SCD_LOADER)/_filesystem/M_INIT.PRG
	$(SIZEBND) $(SCD_LOADER)/_filesystem/M_INIT.PRG -sizealign 131072    
	$(MKISOFS) -iso-level 1 -o $(SCD_LOADER)/filesystem.img -pad $(SCD_LOADER)/_filesystem
	$(TRIMFSIMG) $(SCD_LOADER)/filesystem.img $(SCD_LOADER)/filesystem.bin
	$(RM) -f $(SCD_LOADER)/filesystem.img
	$(ASM68K) /p /j $(SCD_LOADER)/_boot $(SCD_LOADER)/_boot/ip.asm, $(SCD_LOADER)/_boot/ip.bin
	$(ASM68K) /p /j $(SCD_LOADER)/_boot $(SCD_LOADER)/_boot/sp.asm, $(SCD_LOADER)/_boot/sp.bin
	$(ASM68K) /p /j $(SCD_LOADER)/ $(SCD_LOADER)/main.asm, $(SCD_LOADER)/out.iso
	$(RM) -f $(SCD_LOADER)/filesystem.bin

out/$(ROM).out: $(LIB)/segacd.o $(OBJ) $(LIB)/libgendev.a
	$(MKDIR) -p out
	$(CC) -T $(GDK)/mdcd.ld -nostdlib $(LIB)/segacd.o $(OBJ) $(LIB)/libgendev.a $(LIB)/libgcc.a -o out/$(ROM).out    

%.asm: %.rc
	$(GENRES) $< $@

%.s: %.asm
	$(MACCER) -o $@ $<

%.s: %.bmp
	$(BINTOS) -bmp $<

%.raw: %.wav
	$(WAVTORAW) $<

%.tfc: %.tfd
	$(TFMCOM) $<

%.s: %.tfc
	$(BINTOS) -align 32768 $<

%.s: %.raw
	$(BINTOS) -align 256 -sizealign 256 $<

%.s: %.pcm
	$(BINTOS) -align 256 -sizealign 256 $<

%.o80: %.s80
	$(ASMZ80) $(FLAGSZ80) $< $@ out.lst

%.c: %.o80
	$(BINTOC) $<

%.o: %.c
	$(CC) $(FLAGS) -c $< -o $@

%.o: %.s
	$(CC) $(FLAGS) -c $< -o $@

I still need to check if I can make all the other Interrupt functions work... I will test in real hardware in a few hours.

Thank all of you for your kind patience and help, of course you are on the credits of my humble project now.
Last edited by Artemio on Sat Mar 19, 2011 3:34 am, edited 1 time in total.

Artemio
Interested
Posts: 22
Joined: Fri Jan 07, 2011 7:04 pm
Location: Mexico
Contact:

Post by Artemio » Tue Mar 15, 2011 6:54 am

Tested and released for the Sega CD/Mega CD, binaries and source code at:

http://code.google.com/p/240p-test-suite/

Thanks a lot guys =)

SoullessSentinel
Interested
Posts: 24
Joined: Wed Feb 03, 2010 12:53 am
Location: Grimsby, England

Post by SoullessSentinel » Tue Mar 15, 2011 11:28 am

Glad you got everything working.

In the .asm files from my original Sega CD Project files, could you add a header to state that I was the original auther, mark me down as "Luke Usher/SoullessSentinel", as I see your project is under the GPL, and I would like to be able to use my own code in non-GPL projects, as I am releasing it under a non-GPL compatibile licence in the future, within a game project it's just to avoid a possible licence violation, you can state that I gave you permission to use it in a GPL Style licence?

Thankyou for the credit within the Wiki though (:

Artemio
Interested
Posts: 22
Joined: Fri Jan 07, 2011 7:04 pm
Location: Mexico
Contact:

Post by Artemio » Tue Mar 15, 2011 3:16 pm

Of course Luke, I did add a small note on top of them, and never added any licence or claimed autorship of them. I am also not linking against them so they wouldn't be affected anyway.

Adding the extra notes now.

; =======================================================================================
; Sega CD Boot loader by Luke Usher/SoullessSentinel (c) 2010
; Used with permission. This code is not released under the GPL.
; =======================================================================================

If you prefer I can simply link to this thread instead, I added the files for my own convenience only.

I also updated the wiki to reflect such changes.

SoullessSentinel
Interested
Posts: 24
Joined: Wed Feb 03, 2010 12:53 am
Location: Grimsby, England

Post by SoullessSentinel » Tue Mar 15, 2011 5:05 pm

I have no problem with the code being available there, I just wanted it making clear that it was seperate in licence and author from your main application code. Thanks for this, and I'm happy you found this helpful, I believe it is the first time my code has been used outside of my own work.

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

Post by TascoDLX » Fri Mar 18, 2011 1:37 pm

Oops, I lost track of the thread. Nicely done, Artemio!
Artemio wrote:How could I set _HBL TascoDLX? I did find that bit of code at http://www.retrodev.com/segacdb.asm but it only had that and I couldn't find any info on it... Where can I read about that?

I also found this code:
http://devster.monkeeh.com/sega/basiegaxorz/src.html

Which sets teh jump table, I was playing around with it and adapting it... would that be ok?
You can write your routine's address straight into the jump table; no need to rewrite the entire table. Just make sure you write it to the correct address: _VBL to 0xFFFD08, _HBL to 0xFFFD0E. Generally I wouldn't bother changing any others unless you absolutely need them.

HCKTROX
Interested
Posts: 27
Joined: Wed Mar 24, 2010 1:15 am
Location: Chile

Post by HCKTROX » Fri Mar 18, 2011 7:03 pm

Argh, while I don't know how to program in C (I just know ASM, vb and Delphi) and I don't know how the Mega CD works, of course I'll try something of the info. explained here.

Thanks!
skype: hcktrox

Artemio
Interested
Posts: 22
Joined: Fri Jan 07, 2011 7:04 pm
Location: Mexico
Contact:

Post by Artemio » Sat Mar 19, 2011 8:22 am

Thanks TascoDLX, here's the updated code with the ones I could figure out:

Code: Select all

.text

*-------------------------------------------------------
*
*       Sega CD startup code for the GNU Assembler
*
*-------------------------------------------------------

        .org    0x00000000

_Entry_Point:            
        move    #0x2700, %sr        /* interrupts */

* Clear Work RAM (0xFF0000 to 0xFFFCFF)
        lea     0xFF0000,%a0
        moveq   #0,%d0
        move.w  #0x3F3F,%d1
cram:
        move.l  %d0,(%a0)+
        dbra    %d1,cram        

* Enable VBlank
        lea     _VBL, %a1
        jsr     0x0368

        lea     Table,%a5
        movem.w (%a5)+,%d5-%d7
        movem.l (%a5)+,%a0-%a4    	      
        
        jmp     continue

Table:
        dc.w    0x8000, 0x3fff, 0x0100, 0x00a0, 0x0000, 0x00a1, 0x1100, 0x00a1
        dc.w    0x1200, 0x00c0, 0x0000, 0x00c0, 0x0004   

continue:                        
        lea     __stack,%a0
        movea.l %a0,%sp                   /* set stack pointer to top of Work RAM */        

* Define known Jump Table, DMA is used to copy font (corrupted font)               
	    move.l	(_HBL),(0xFFFD0E)        
	    move.l	(_Chk_Instruction),(0xFFFD7A)        
	    move.l	(_Address_Error),(0xFFFD80)           
	    move.l	(_Zero_Divide),(0xFFFD86)           
	    move.l	(_Trapv_Instruction),(0xFFFD8C)           
	    move.l	(_Line_1010_Emulation),(0xFFFD92)        
	    move.l	(_Line_1111_Emulation),(0xFFFD98)           
	    move.l	(_Privilege_Violation),(0xFFFD9E)           
	    move.l	(_Trace),(0xFFFDA4)

        and.w	#0xF8FF, %sr
        jmp     _start_entry                    /* call main() */        
As commented above, since the Mini SDK copies the font to VRAM with DMA, it ends up corrupted.. but the (warped) message is shown when they happen.

Orion_
Very interested
Posts: 52
Joined: Mon May 02, 2011 2:26 pm
Location: France
Contact:

Post by Orion_ » Mon May 02, 2011 2:36 pm

lukeusher123 > I was searching info on sega cd dev, and couldn't find a lot's of infos apart retrodev.com sources, and then I saw your dev kit, very understandable with lots of comments and working perfect, thanks a lot for your work on this !

Post Reply