Booting CD from Cart ?

Ask anything your want about Mega/SegaCD programming.

Moderator: Mask of Destiny

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

Post by Chilly Willy » Mon Jan 06, 2014 11:48 pm

If you're trying to use 2M mode (one block of 256KB of word ram), you need to request 2M mode from the CD side, then wait for the MD to set 2M mode on it's side, like this

CD side

Code: Select all

        andi.b  #0xE2,0x8003.w          /* Priority Mode = off, 2M mode */
        move.b  #'I,0x800F.w            /* send MD init handshake to MD */
MD side

Code: Select all

| wait for MD init handshake from CD
0:
        cmpi.b  #'I,0x200F(a5)
        bne.b   0b
        bset    #1,0x2003(a5)           /* give Sub-CPU Word RAM */

        move.b  #'B,0x200E(a5)          /* main comm port - do boot */
The CD side would wait for the B to appear to know the ram is now under Sub-CPU control.

If you're trying to use 1M mode (two blocks of 128KB of word ram), you may be using the wrong address.

Also, you need to set an extra register telling the BIOS how the data will be transferred. See page 26 of the CD hardware manual. But in general, if you are using the CPU for the CD data transfer (as opposed to DMA), you do this before reading

Code: Select all

        /* set CDC Mode destination device to Sub-CPU */
        andi.w  #0xF8FF,0x8004.w
        ori.w   #0x0300,0x8004.w
You have to do that every time through the loop right before CDCREAD. Look at my CD boot code for details on reading ISO9660 discs.

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

Post by Orion_ » Tue Jan 07, 2014 10:23 am

ok, after carefully reading the sega cd doc, I found that the WordRam can only be given to sub cpu by main cpu, and sub cpu can only return it to the main cpu.
I thought the wordram could be switched in both direction from both main & sub cpu.
so ... I did some synchronizing to give/get back the word ram between the main/sub cpu like you suggested, and I still got stuck reading info from the main cpu, but it's because in mode1 (booting from cart) the word ram (from main cpu) is also not mapped to $200000, but at $600000 instead ..
now it's fully working ! :)
I can now clean my code, and try to boot a real cd to check this :)
Retro game programming !

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

Post by Orion_ » Tue Jan 07, 2014 5:02 pm

I Just tried the code on a real mega cd and it's fully working, I'm glad \o/
I made a little trampoline code, so in my maincpu boot code, I load data from cd to word ram, then jump at the end of MD ram, copy the data from word ram to the start of md ram, and jump to the start of md ram, so then my final game program sits in MD ram and have the word ram free to load data from cd =)
I just got something strange:

This little code works perfectly on the megacd hardware, but not on Kega Fusion or Gens emulator

Code: Select all

.waitW:
	bset.b	#1,$A12003	; Wait for WordRam to be given to CD SubCPU
	bne.s	.waitW
For emulator I need to use this code instead:

Code: Select all

	lea	$A12003,a0
	ori.b	#2,(a0)
.waitW:
	move.b	(a0),d0
	andi.b	#2,d0
	beq.s	.waitW
I guess this could be a little emu protection code :D
Retro game programming !

l_oliveira
Very interested
Posts: 53
Joined: Mon Mar 07, 2011 12:58 am

Post by l_oliveira » Tue Jan 07, 2014 5:11 pm

Orion_ wrote:I guess this could be a little emu protection code :D
You're a little evil .... 8)

But now the trick is exposed ... :lol:

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

Post by Orion_ » Tue Jan 07, 2014 8:41 pm

I won't make another topic for this but, I have a little problem with the DMA transfer.

When I transfer the data from the wordram to vram using 68k, it works ok (left picture), but when I do DMA to VRAM, I get errors on tile (right picture)
Image

Have you experienced this already ?

My code is executing from the MD Ram, here is my DMA routine:

Code: Select all

TransferDMAtoVRAM:		; d0 = Data Address, d1 = Vram Address, d2 = Data Size
	movem.l	d3/a0,-(a7)

	lea	VDP_CTRL,a0

	lsr.w	#1,d2		; lenght in word
	move.w	#$9300,d3
	move.b	d2,d3		; low
	move.w	d3,(a0)

	lsr.w	#8,d2		; high
	or.w	#$9400,d2
	move.w	d2,(a0)

	lsr.l	#1,d0		; address in word
	move.w	#$9500,d3
	move.b	d0,d3		; low
	move.w	d3,(a0)

	lsr.w	#8,d0
	or.w	#$9600,d0	; mid
	move.w	d0,(a0)

	swap	d0
	or.w	#$9700,d0	; high
	move.w	d0,(a0)

	move.w	d1,d0		; Tile VRAM address
	bsr	SetVramAddressDMA

	movem.l	(a7)+,d3/a0
	rts


SetVramAddressDMA:	; d0 = Address
	movem.l	d1-d2,-(a7)
	move.l	#$804000,d1

	move.w	d0,d2		; Address
	and.w	#$3FFF,d2	; Lower Bits
	or.w	d1,d2		; Add VDP Command

	swap	d1
	swap	d2

	move.w	d0,d2		; Address
	lsr.w	#8,d2
	lsr.w	#14-8,d2	; Upper Bits
	or.b	d1,d2		; Add VDP Command

	move.l	d2,VDP_CTRL

	movem.l	(a7)+,d1-d2
	rts
Retro game programming !

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Tue Jan 07, 2014 9:53 pm

I'm sure I've read someone else here talk about that before. It seems that the wordram doesn't respond to reads fast enough to keep up with DMA access from the VDP. This results in a phenomenon where the wordram is actually returning data for a previous read when the VDP is attempting to latch data for a later read. It seems to be stable and repeatable from what I've heard, and apart from the returned data being "out of sync" with the DMA, the operation itself works. If you start the DMA operation from the target address in wordram, but write it to 1 word earlier in VRAM than you want it to appear, then let the DMA operation run for 1 word extra, you'll get the result you want, with the exception that you'll have one extra corrupted word transferred to VRAM before your data. You could do a VRAM read operation to retrieve this data, then re-write it from the 68k after your DMA operation completes, in which case, you'll get working DMA from word ram without having to worry about corrupting that single word of data before the target.

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

Post by Chilly Willy » Tue Jan 07, 2014 10:25 pm

Yes, I don't remember where that is in the docs offhand, but Sega recommends setting the SOURCE to one word past the start, doing a DMA of N words, then writing the FIRST word using the CPU. That avoids any corruption in the vram. They even provided a snippet of example code that did that. Now if I could just remember where that was...

l_oliveira
Very interested
Posts: 53
Joined: Mon Mar 07, 2011 12:58 am

Post by l_oliveira » Tue Jan 07, 2014 10:48 pm

Chilly Willy wrote:Yes, I don't remember where that is in the docs offhand, but Sega recommends setting the SOURCE to one word past the start, doing a DMA of N words, then writing the FIRST word using the CPU. That avoids any corruption in the vram. They even provided a snippet of example code that did that. Now if I could just remember where that was...
Page 61 of the hardware manual mentions that ... (and a few don't"s" to go along with it at page 62 ...)

Page 63 has source code with an example for a solution.

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

Post by Orion_ » Tue Jan 07, 2014 11:15 pm

I remembered a doc from the SVP about setting the DMA to 2 bytes after the start address like on the sega cd.
So I tried and set the DMA Source at Data Address + 2 and it's working !
I can't even see the missing first word of data (at least on emulator, because on my TV the left border is a bit hidden)
Retro game programming !

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

Post by Orion_ » Thu Jan 09, 2014 5:23 pm

I'm trying to play audio track now, I have strange behavior.
When playing the audio track straight from start, it works, but If I try to load data before and then play audio cd, it seems like the cd is reading but no sound output :/
now ... if I keep the lid of the megacd open while my init code is waiting for the cd to be ready, and then I close the lid, then everythings works fine, (load data, play audio, stop, load data, play audio again), that's so strange %)
Retro game programming !

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

Post by Chilly Willy » Thu Jan 09, 2014 8:45 pm

Are you calling CDCSETMODE when you switch from data to audio and back? You'll notice that my data code calls CDCSETMODE to allow the CD to read mode 1 data. My code for playing tracks doesn't set the mode, but it does init the drive, which leaves it in cdda mode by default on audio discs. For a data disc with cdda tracks, you probably need to explicitly set cdda mode before playing a track.

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

Post by Orion_ » Thu Jan 09, 2014 9:04 pm

I can't find a documentation on the CDCSETMODE call (nothing in the sega cd doc)
so I'm calling it with moveq #0,d1 before loading data, but I don't know how to call it for audio.

For Audio I'm doing:

Code: Select all

	move.w	#$0002,d0	; MSCSTOP
	jsr	CDBIOS.w

	lea	InitParam,a0
	move.w	#$0010,d0	; DRVINIT
	jsr	CDBIOS.w

	lea	BiosParams,a0
	move.w  #MSCPLAY1,d0
	jsr	CDBIOS.w
for data:

Code: Select all

	move.w	#$0089,d0	; CDCSTOP
	jsr	CDBIOS.w

	move.w	#0,d1		; Mode 1
	move.w	#$0096,d0	; CDCSETMODE
	jsr	CDBIOS.w

        ; Set CDC Mode destination device to SubCPU
	andi.w	#$F8FF,$FFFF8004.w
	ori.w	#$0300,$FFFF8004.w

	lea	BiosParams,a0
	move.w	#$0020,d0	; ROMREADN
	jsr	CDBIOS.w
etc...
Retro game programming !

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

Post by Orion_ » Fri Jan 10, 2014 10:29 am

Well, I just burnt a CD to test on the real hardware and it's working ... so I guess I'm ready for making a game now :)
Retro game programming !

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

Post by Chilly Willy » Fri Jan 10, 2014 8:18 pm

Code: Select all

;-----------------------------------------------------------------------
; BIOS_CDCSETMODE - Tells the BIOS which mode to read the CD in.  Accepts
; bit flags that allow selection of the three basic CD modes as follows:
;
;       Mode 0 (CD-DA)                              2
;       Mode 1 (CD-ROM with full error correction)  0
;       Mode 2 (CD-ROM with CRC only)               1
;
; input:
;   d1.w  FEDCBA9876543210
;                     ||||
;                     |||+--> CD Mode 2
;                     ||+---> CD-DA mode
;                     |+----> transfer error block with data
;                     +-----> re-read last data
;
; returns:
;   nothing
;-----------------------------------------------------------------------
BIOS_CDCSETMODE macro
      CDBIOS #CDCSETMODE
      endm
Setting the mode to CDDA should be much better than reseting the drive every time you play a track. :D

Do you plan on using the PCM chip in the SCD? If so, you might want to look at the pcm library I wrote for the SCD that I posted along with the MOD/Mikmod players. The existing examples of using the PCM chip are all wrong and don't work on real hardware - even Sega's PCM example doesn't work! It took a while for me to figure out how to get real hardware to work; it still works with emulators as well. All that went into the pcm library. It also allows you to use the SCD timer (used by the MOD/Mikmod players for the beat, as an example).

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

Post by Orion_ » Fri Jan 10, 2014 8:32 pm

Thank you, I will try this instead :)
about the pcm lib, I already downloaded it and put it in my "to watch" list, I will try it soon to use it for sfx :)
Thanks for your work on the megacd and for sharing your source, it was so much helpful !
Retro game programming !

Post Reply