;---------------------------------------
;
; Wav Player v1.0
;
; by drx [www.hacking-cult.org]
;        [www.bluehedgehog.org]
;
; Plays the sound.wav wav sound.
;
;---------------------------------------


Vectors:	dc.l $FFFE00,	Entrypoint,	Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l HBlank,	Error,		VBlank,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
		dc.l Error,	Error,		Error,	Error
Header:		dc.b \'SEGA MEGA DRIVE \' ; Console name
		dc.b \'(C) DRX 2004.NOV\' ; Copyright/Date
DomesticName:	dc.b \'Code template by drx - www.hacking-cult.org     \' ; Domestic Name
		dc.b \'Code template by drx - www.hacking-cult.org     \' ; International Name
		dc.b \'GM 00000000-00\'   ; Version
Checksum:	dc.w $1337
					; Checksum
		dc.b \'J               \' ; I/O Support
RomStartLoc:	dc.l 0			; ROM Start
RomEndLoc:	dc.l RomEnd
					; ROM End
RamStartLoc:	dc.l $FF0000		; RAM Start
RamEndLoc:	dc.l $FFFFFF		; RAM End

		dc.b $20,$20,$20,$20	; \'RA\',$F8,$20 if SRAM = on
		
SramStart:	dc.l $20202020		; $200000 if SRAM = on
SramEnd:	dc.l $20202020		; $20xxxx if SRAM = on
		
		dc.b \'                                              \' ; Notes
		dc.b \'      \'
		dc.b \'JUE             \' ; Country

;---------------------
; Code start
;---------------------
		
Entrypoint:

		tst.l	($A10008).l		;Test Port A control
		bne	PortA_Ok

		tst.w	($A1000C).l		;Test Port C control

PortA_Ok:
		bne	SkipSetup

		move.b	($A10001).l,d0		;version
		andi.b	#$F,d0
		beq	SkipSecurity		;if the smd/gen model is 1, skip the security
		move.l	#\'SEGA\',($A14000).l

SkipSecurity:   

		move.w	($C00004).l,d0		;test if VDP works

		moveq	#0,d0
		movea.l	d0,a6
		move	a6,usp			;set usp to $0
		
;---------------------
; Setup VDP registers
;---------------------
		lea	(VDPSetupArray),a0
		move.w	#(VDPSetupArrayEnd-VDPSetupArray)/2,d1	;$18 VDP registers
		
VDPSetupLoop:
		move.w	(a0)+,($C00004).l
		dbf	d1,VDPSetupLoop
		
		
		move.l	#$40000080,($C00004).l
		move.w	#0,($C00000).l		;clean the screen
	
	
;---------------------
; Init the Z80
;---------------------	

		move.w	#$100,($A11100).l	;Stop the Z80
		move.w	#$100,($A11200).l	;Reset the Z80
		
Waitforz80:
		btst	#0,($A11100).l
		bne	Waitforz80		;Wait for z80 to halt
		
		lea	(Z80Init),a0
		lea	($A00000).l,a1
		move.w	#Z80InitEnd-Z80Init,d1
		
InitZ80:
		move.b	(a0)+,(a1)+
		dbf	d1,InitZ80
		
		move.w	#0,($A11200).l
		move.w	#0,($A11100).l		;Start the Z80
		move.w	#$100,($A11200).l
		
	
;---------------------
; Reset the RAM
;---------------------	

		lea	($FFFF0000).l,a0
		move.w	#$3fff,d1
		
ClearRAM:
		move.l	#0,(a0)+
		dbf	d1,ClearRAM
		
		
;---------------------
; VDP again
;---------------------			
		
		move.w	#$8174,($C00004).l
		move.w	#$8F02,($C00004).l
		
		
;---------------------
; Clear the CRAM
;---------------------	

		move.l	#$C0000000,($C00004).l	;Set VDP ctrl to CRAM write
		move.w	#$3f,d1
		
ClearCRAM:
		move.w	#0,($C00000).l
		dbf	d1,ClearCRAM
		
			
;---------------------
; Clear the VDP stuff
;---------------------		

		move.l	#$40000010,($C00004).l
		move.w	#$13,d1
		
ClearStuff:
		move.l	#0,($C00000).l
		dbf	d1,ClearStuff
		

;---------------------
; Init the PSG
;---------------------	

		move.b	#$9F,($C00011).l
		move.b	#$BF,($C00011).l
		move.b	#$DF,($C00011).l
		move.b	#$FF,($C00011).l
		
		
		move.w	#0,($A11200).l
		
		
;---------------------
; Load the z80 driver
;---------------------

		move.w	#$100,($A11100).l	;Stop the Z80
		move.w	#$100,($A11200).l	;Reset the Z80
		
Waitforz80a:
		btst	#0,($A11100).l
		bne	Waitforz80a		;Wait for z80 to halt
		
		lea	(Z80Driver),a0
		lea	($A00000).l,a1
		move.W	#Z80DriverEnd-Z80Driver,d1
		
LoadZ80Driver:
		move.b	(a0)+,(a1)+
		dbf	d1,LoadZ80Driver
		
		move.w	#0,($A11100).l		;Start the Z80
	
;---------------------
; Clear the registers
; and set the SR
;---------------------	

		movem.l	($FF0000).l,d0-a6	
		lea	($FFFE00).l,a7
		move	#$2700,sr

SkipSetup:	

	
;-----------------------
; Here starts your code
;-----------------------
Main:

;
;ok, so we have to stop the z80 in order to set up the variables
;
		
		move.w	#$100,($A11100).l	;Stop the Z80
		
;		
; loops until z80 is halted
;		
Waitforz80b:
		btst	#0,($A11100).l
		bne	Waitforz80b		;Wait for z80 to halt
		

;
;in our sound driver, $39 is the on/off variable
;
		move.b	#1,($a00039).l		;turn the wav playing script on

;		
;we have to bitshift the wav address a bit, because Z80 is little endian, compared to 68k (big endian)
;
;data: 		$12345678
;big endian: 	$12345678
;little endian:	$78563412
;
		move.b	#((SoundStart&0xFF0000)>>16),($a0003c).l	;addr - $__xxxx
		move.b	#((SoundStart&0xFF00)>>8),($a0003b).l		;addr - $xx__xx
		move.b	#(SoundStart&0xFF),($a0003a).l			;addr - $xxxx__
		
;		
; set up the wav length (number of bytes played)
;		
		move.w	#SoundEnd-SoundStart,($a00043).l	;wav length

;
; now we can start te z80 after changing the variables
;
		move.w	#$0,($A11100).l		;Start the Z80
		
;		
; the infinite loop will occur now, and the z80 will work in the background (z80 and 68k work simultaneously [spelling... :P])
;
		dc.w	$60fe			;infinite loop (bra $-2)

		rts
		
		
;---------------------
; Error exceptions
;---------------------

Error:
		rte
		
;---------------------
; Horizontal Blank
;---------------------
HBlank:

		rte
				
;---------------------
; Vertical Blank
;---------------------
VBlank:

		rte

;---------------------
; VDP registers array
;---------------------

VDPSetupArray:
		dc.w	$8004	;9-bit palette = 1 (otherwise would be 3-bit), HBlank = 0
		dc.w	$8134	;Genesis display = 1, DMA = 1, VBlank = 1, display = 0
		dc.w	$8230	;Scroll A - $C000
		dc.w	$8338	;Window   - $E000
		dc.w	$8407	;Scroll B - $E000
		dc.w	$857c	;Sprites  - $F800
		dc.w	$8600	;Unused
		dc.w	$8700	;Backdrop color - $00
		dc.w	$8800	;Unused
		dc.w	$8900	;Unused
		dc.w	$8A00	;H Interrupt register
		dc.w	$8B00	;Full screen scroll, no external interrupts
		dc.w	$8C81	;40 cells display
		dc.w	$8D3F	;H Scroll - $FC00
		dc.w	$8E00	;Unused
		dc.w	$8F02	;VDP auto increment
		dc.w	$9001	;64 cells scroll
		dc.w	$9100	;Window H position
		dc.w	$9200	;Window V position
		dc.w	$93FF	;DMA stuff (off)
		dc.w	$94FF	;DMA stuff (off)
		dc.w	$9500	;DMA stuff (off)
		dc.w	$9600	;DMA stuff (off)
		dc.w	$9780	;DMA stuff (off)
VDPSetupArrayEnd:


;---------------------
; Z80 init code
;---------------------

Z80Init:
	dc.w	$af01, $d91f, $1127, $0021, $2600, $f977 
	dc.w    $edb0, $dde1, $fde1, $ed47, $ed4f, $d1e1                                   
	dc.w    $f108, $d9c1, $d1e1, $f1f9, $f3ed, $5636
	dc.w	$e9e9 
Z80InitEnd:

;---------------------
; Music driver (z80)
;---------------------		

Z80Driver:
		dc.b	$c3,$46,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
		dc.b	$00,$00,$00,$00,$00,$f3,$ed,$56,$31,$00,$20,$3a,$39,$00,$b7,$ca,$4c,$00,$21,$3a,$00,$11,$40,$00,$01,$06,$00,$ed,$b0,$3e,$00,$32,$39,$00,$3e,$b4,$32,$02,$40,$3e,$c0,$32,$03,$40,$3e,$2b,$32,$00,$40,$3e,$80,$32,$01,$40,$3a,$43,$00,$4f,$3a,$44,$00,$47,$3e,$06,$3d
		dc.b	$c2,$81,$00,$21,$00,$60,$3a,$41,$00,$07,$77,$3a,$42,$00,$77,$0f,$77,$0f,$77,$0f,$77,$0f,$77,$0f,$77,$0f,$77,$0f,$77,$3a,$40,$00,$6f,$3a,$41,$00,$f6,$80,$67,$3e,$2a,$32,$00,$40,$7e,$32,$01,$40,$21,$40,$00,$7e,$c6,$01,$77,$23,$7e,$ce,$00,$77,$23,$7e,$ce,$00,$77
		dc.b	$3a,$39,$00,$b7,$c2,$4c,$00,$0b,$78,$b1,$c2,$7f,$00,$3a,$45,$00,$b7,$ca,$4c,$00,$3d,$3a,$45,$00,$06,$ff,$0e,$ff,$c3,$7f,$00
Z80DriverEnd:


SoundStart:
		incbin	sound.wav
SoundEnd:

RomEnd: