; ===========================================================================
; ---------------------------------------------------------------------------
; Sonic hacking contest splash screen
; ---------------------------------------------------------------------------
OffsetROM := $
; ---------------------------------------------------------------------------
VSH_LogoArt	=	00020h
VSH_Store	=	037A0h
VSH_Plane	=	03800h
VSH_Sprite	=	03F00h
; ---------------------------------------------------------------------------
		phase	0E000h
R_RAM:		ds	0

R_Palette:	ds	010h						; palette buffer for line 1 only
R_PalCur:	ds	2						; QQ.FF current palette fade amount
R_PalFade:	ds	1						; QQ fade destination
R_LastPal:	ds	2						; load palette (so it knows when to update)
R_Flicker:	ds	2						; flicker timer
R_Random:	ds	2						; random number storage
R_UniqueLoad:	ds	1						; unique mappings loading (frames 0 to 2)
R_UniquePrev:	ds	1						; previous mappings already loaded

R_RAM_END:	ds	0
		dephase
; ---------------------------------------------------------------------------

	; --- relative call ---

callx		macro	Address
		exx							; load address registers
		ld	hl,+						; load return address
		add	hl,de						; ''
		push	hl						; store return address
		ld	hl,Address					; load call address
		add	hl,de						; ''
		push	hl						; store call address
		exx							; reload standard registers
		ret							; jump to call address
+
		endm

	; --- relative jp ---

jpx		macro	Address
		exx							; load address registers
		ld	hl,Address					; load jump address
		add	hl,de						; ''
		push	hl						; store jump address
		exx							; reload standard registers
		ret							; jump to address
		endm

	; --- loading interrupt status ---

li		macro
		callx	Checki						; call subroutine to load interrupt status
		endm

	; --- relative ld  hl,Address ---

ldx		macro	Reg,Address
		exx							; load address registers
		ld	hl,Address					; load address
		add	hl,de						; ''
		push	hl						; store address
		exx							; reload standard registers
		pop	Reg						; reload address
		endm

; ---------------------------------------------------------------------------
; Screen itself
; ---------------------------------------------------------------------------
; Because the screen can be included anywhere in the ROM in binary, all
; addresses must be relative, the macros above deal with handling absolute
; addresses and calculating the actual address.  The below instructions read
; the return address and collect the call instruction's address so we know
; where this screen's code starts.
; ---------------------------------------------------------------------------
		!org	OffsetROM					; Reset the program counter
; ---------------------------------------------------------------------------

		jr	.NoDebug

	; --- Debug code ---
	; This floods CRAM with green and loops, so that
	; a savestate can be made and the VDP registers can
	; be ripped
	; ------------------

		di							; disable interrupts
		ld	bc,020BFh					; prepare VDP control port (and number of colours to transfer)
		ld	de,0C000h					; set VDP to CRAM write address 00
		out	(c),e						; ''
		nop							; '' (delay)
		out	(c),d						; '' (set VDP CRAM write)
		dec	c						; prepare VDP data port
		ld	a,00Ch						; prepare green

	.DebugColours:
		out	(c),a						; send green to CRAM
		djnz	.DebugColours					; repeat for all colours

		jr	$						; trap/loop

; ---------------------------------------------------------------------------
; The screen itself
; ---------------------------------------------------------------------------

	.NoDebug:
		pop	hl						; get return address
		push	hl						; keep it in the stack
		dec	hl						; get high byte of address
		ld	d,(hl)						; ''
		dec	hl						; get low byte of address
		ld	e,(hl)						; ''
		exx							; store address registers

		li							; load interrupt status
		push	af						; store interrupt status
		di							; disable interrupts

		callx	ClearVDP					; clear VDP (VRAM/CRAM)

	; --- Storing ---

		ld	c,0BFh						; set VDP regiser address
		ld	de,VSH_Store|04000h				; set VDP to VRAM write address 00
		out	(c),e						; ''
		ld	hl,R_RAM					; set RAM address to store
		out	(c),d						; '' (set VDP VRAM write)
		dec	c						; prepare VDP data port
		ld	b,R_RAM_END-R_RAM				; size to transfer

	.StoreRAM:
		ld	a,(hl)						; copy byte to VRAM
		out	(c),a						; ''
		xor	a						; clear RAM
		ld	(hl),a						; ''
		inc	hl						; advance to next byte
		djnz	.StoreRAM					; repeat until RAM is stored

	; --- Setting up ---

		ldx	hl,RegVDP					; load register data list
		callx	SetupVDP					; setup VDP registers

		ldx	hl,LogoArt					; compressed art address
		ld	de,VSH_LogoArt					; VRAM address to decompress to
		callx	KosSpeDec					; decompress and dump

		ldx	hl,LogoMap
		ld	de,VSH_Plane					; VRAM address to decompress to
		callx	KosSpeDec					; decompress and dump

		ld	a,004h						; set to fade palette in maximum
		ld	(R_PalFade),a					; ''

		ld	a,0FFh						; set previous frame's unique map loading to something invalid (forcing an update)
		ld	(R_UniquePrev),a				; ''

	; --- Finalisation ---

		ld	a,11100000b				; 81	; 1DI000S0 | Display (0 Off | 1 On), Interrupt IE, Sprite Size (0 = 8 | 1 = 16)
		out	(0BFh),a					; enable display
	nop
		ld	a,081h						; set register
		out	(0BFh),a					; ''

; ---------------------------------------------------------------------------
; Splash screen main loop
; ---------------------------------------------------------------------------

MainLoop:
		callx	VBlank						; wait for and run V-blank

		callx	GetPalette					; get correct flicker palette
		callx	FadePal						; control palette fading

		ld	a,(R_PalFade)					; is the palette fading?
		or	a						; ''
		jr	nz,.NoFade					; if not, branch
		ld	b,a						; store current fade
		ld	a,(R_PalCur+1)					; load current palette fade amount
		cp	a,b						; has the fading finished?
		jr	nz,.NoFade					; if not, continue
		jpx	Finish						; finish the splash screen and return

	.NoFade:
		exx							; load controls
		ld	a,b						; ''
		exx							; ''
		and	00100000b					; has "2" been pressed?
		jr	z,MainLoop					; if not, branch
		xor	a						; set to fade palette in minimum
		ld	(R_PalFade),a					; ''
		jr	MainLoop					; loop

; ===========================================================================
; ---------------------------------------------------------------------------
; Subroutine to load the correct flicker palette
; ---------------------------------------------------------------------------

GetPalette:
		ldx	de,LogoPal_Hi					; load palette to fade to
		xor	a						; set to use "hi" mappings
		ld	(R_UniqueLoad),a				; ''
		ld	hl,(R_Flicker)					; load flicker timer
		inc	hl						; increase timer
		ld	(R_Flicker),hl					; ''
		ld	a,l						; get flicker mode
		add	a,a						; is it time to flicker?
		jr	nc,.NoFlicker					; if not, branch

		ld	a,h						; have we reached the last flicker?
		cp	3						; ''
		jr	c,.ContFlicker					; if not, branch
		xor	a						; set to fade palette in minimum
		ld	(R_PalFade),a					; ''
		jr	.FinishFlicker					; continue to fade the palette normally

	.ContFlicker:
		ld	a,(R_Random+1)					; load random number
		and	030h						; keep within range
		sub	010h						; has it gone out of range?
		jr	nc,.NoCapFlicker				; if not, branch
		xor	a						; keep at highest

	.NoCapFlicker:
		ld	(R_UniqueLoad),a				; set to load the correct mappings in V-blank later
		add	a,e						; advance to correct fade slot
		ld	e,a						; ''
		ld	a,000h						; ''
		adc	a,d						; ''
		ld	d,a						; ''
		jr	.YesFlicker					; continue

	.NoFlicker:
		ld	a,h						; get solid type
		dec	a						; get such that it's; off, on, on, off
		and	3						; ''
		sub	002h						; ''
		jr	c,.YesFlicker					; if it's on, branch

	.FinishFlicker:
		ldx	de,LogoPal_Low					; load palette to fade to
		ld	a,020h						; set to use "Low" mappings
		ld	(R_UniqueLoad),a				; ''

	.YesFlicker:
		ret							; return

; ===========================================================================
; ---------------------------------------------------------------------------
; Subroutine to control palette fading
; ---------------------------------------------------------------------------

FadePal:
		ld	hl,(R_PalCur)					; load current fade amount
		ld	a,(R_PalFade)					; load fade amount
		sub	a,h						; are we at the amount?
		jr	nz,.FadeRun					; if not, branch

		ld	a,(R_LastPal)					; has the palette changed?
		cp	a,e						; ''
		jr	nz,.YesFadeUpdate				; if so, branch
		ld	a,(R_LastPal+1)					; has the palette changed?
		cp	a,d						; ''
		jr	z,.NoFadeUpdate					; if not, branch

	.YesFadeUpdate:
		ld	a,(R_PalCur+1)					; load fade amount to b
		ld	b,a						; ''
		jr	.RunFade					; continue

	.NoFadeUpdate:
		ret							; return

	.FadeRun:
		sbc	a,a						; get direction (FF or 00 depending on direction)
		ld	b,a						; set direction speed to be FFC0 or 0040
		and	080h						; ''
		or	040h						; ''
		ld	c,a						; ''
		add	hl,bc						; move fade towards destination
		ld	(R_PalCur),hl					; update current palette fade
		ld	b,h						; load quotient fade amount

	.RunFade:
		ld	(R_LastPal),de					; update last palette to fade
		ld	c,010h						; number of colours to do
		ld	hl,R_Palette					; load buffer

	.NextCol:
		push	hl						; store buffer

		ld	a,(de)						; load colour
		and	00110000b					; get only blue
		callx	.DoFade						; perform the fade
		and	00110000b					; get only blue
		ld	l,a						; store blue

		ld	a,(de)						; load colour
		and	00001100b					; get only green
		callx	.DoFade						; perform the fade
		and	00001100b					; get only green
		ld	h,a						; store green

		ld	a,(de)						; load colour
		and	00000011b					; get only red
		callx	.DoFade						; perform the fade
		and	00000011b					; get only red

		or	h						; fuse green with red
		or	l						; fuse blue with green and red
		pop	hl						; restore buffer
		ld	(hl),a						; save to palette buffer
		inc	de						; increase palette address
		inc	l						; increase buffer address
		dec	c						; decrease palette count
		jr	nz,.NextCol					; repeat until finished
		ret							; return

	.DoFade:
		push	bc						; store counters
		ld	c,a						; get colour
		ld	a,b						; load counter
		or	a						; is the fade amount 0?
		jr	z,.Black					; if so, branch
		xor	a						; clear result
	-:	add	a,c						; multiply colour by counter
		djnz	-						; ''
		rrca							; divide by 4 (convertion)
		rrca							; ''
		pop	bc						; restore counters
		ret							; return

	.Black:
		xor	a						; set to use black
		pop	bc						; restore counters
		ret							; return

; ===========================================================================
; ---------------------------------------------------------------------------
; V-blank
; ---------------------------------------------------------------------------

VBlank:
		in	a,(0BFh)					; load status
		and	a,080h						; get only interrupt status
		jr	nz,VBlank					; if V-blank interrupt is on, wait for it to be off...
	.Wait:	in	a,(0BFh)					; load status
		and	a,080h						; get only interrupt status
		jr	z,.Wait						; wait for V-blank to trigger again

		ld	hl,(R_UniqueLoad)				; load unique frame ID
		ld	a,l						; load new ID
		cp	h						; has it changed from previously?
		jr	z,.NoMappings					; if not, branch
		ld	(R_UniqueLoad),a				; update new ID

		ldx	hl,LogoMap_Unique				; load mappings list
	; The value is multiples of 10 (to make it easier for palette data access)
	; so we need to shift down instead of up
	;	add	a,a						; multiply ID by size of word
		rrca							; get to a size of word
		rrca							; ''
		rrca							; ''
		and	003h<<1						; ''
	; -------------------------------------
		ld	c,a						; load ID as word
		ld	b,000h						; ''
		add	hl,bc						; advance to correct mappings list entry
		ld	a,(hl)						; load correct entry
		inc	hl						; ''
		ld	h,(hl)						; ''
		ld	l,a						; ''
		ldx	de,0h						; add absolute address =3
		add	hl,de						; ''
		ldx	de,LogoLog					; load log
		ld	a,(de)						; load size

	.TransUnique:
		ld	b,a						; save size to b
		inc	de						; advance to next byte
		ld	a,(de)						; load lower byte of VRAM address
		inc	de						; advance to next byte
		push	de						; store log address
		ex	de,hl						; load upper byte of VRAM address
		ld	h,(hl)						; ''
		ld	l,a						; fuse lower with it
		ld	a,b						; store counter
		ld	bc,VSH_Plane|04000h				; add VRAM write mode plane address
		add	hl,bc						; ''
		ld	b,a						; restore counter
		ex	de,hl						; resort registers

	; hl = mappings
	; de = VRAM address
	; b = bytes to copy

		ld	c,0BFh						; prepare VDP control port
		out	(c),e						; set VDP to VRAM write mode
		nop							; ''
		out	(c),d						; ''
		dec	c						; get VDP data port
		otir							; transfer mappings

		pop	de						; reload log address
		inc	de						; advance to next byte
		ld	a,(de)						; load size
		or	a						; is there an entry?
		jr	nz,.TransUnique					; if so, branch

		jr	.YesMappings					; continue (avoid CRAM delay)

	; --- Delaying to avoid CRAM dots ---

	.NoMappings:
		ld	bc,08002h					; delay V-blank to ensure the beam is definitely off-screen..
	-:	djnz	$						; ..to avoid CRAM dots
		dec	c						; ''
		jr	nz,-						; ''

	.YesMappings:

	; --- Palette transfer ---

		ld	c,0BFh						; prepare VDP control port
		ld	de,0C000h					; set VDP to CRAM write address 00
		out	(c),e						; ''
		ld	hl,R_Palette					; load palette address
		out	(c),d						; '' (set VDP CRAM write)
		dec	c						; prepare VDP data port
		ld	b,010h						; number of colours to transfer

	.CopyPal:
		outi							; transfer palette
		jr	nz,.CopyPal					; repeat until palette is done

	; --- Frame calls ---

		callx	RandomNumber					; generate random number

; ---------------------------------------------------------------------------
; Subroutine to read the controls
; ---------------------------------------------------------------------------

ReadControls:
		exx							; get address registers
		in	a,(0DCh)					; load buttons
		or	11000000b					; disable player 2's buttons from player 1's byte
		cpl	a						; reverse button states (for XOR below)
		ld	h,a						; store in h
		ld	a,b						; load current held buttons
		xor	h						; disable buttons that are already held
		ld	b,h						; save all new held buttons
		and	h						; get only the newly pressed buttons
		ld	c,a						; save all pressed buttons
		exx							; restore standard registers
		ret							; return

; ===========================================================================
; ---------------------------------------------------------------------------
; Subroutine to generate a random number
; ---------------------------------------------------------------------------

RandomNumber:
		ld	hl,(R_Random)					; load random number
		ld	a,h						; has it started yet?
		or	l						; ''
		jr	nz,.RunRandom					; if so, branch
		ld	hl,0365Ah					; set seed

	.RunRandom:
		ld	d,h						; copy random number
		ld	e,l						; ''
		ld	a,l						; rotate each byte left twice
		rlca							; ''
		rlca							; ''
		ld	b,a						; ''
		ld	a,h						; ''
		ld	h,b						; swap bytes
		rlca							; rotate twice
		rlca							; ''
		ld	l,a						; ''
		add	hl,de						; add copy
		ld	a,h						; swap bytes again
		ld	h,l						; ''
		ld	l,a						; ''
		ld	(R_Random),hl					; update random number
		ret							; return

; ===========================================================================
; ---------------------------------------------------------------------------
; VDP Register setup
; ---------------------------------------------------------------------------

RegVDP:		db	0FFh					; 8A	; H-interrupt line (00 - BF = Interrupt line | C0 - FF = Disabled/No interrupt)
		db	000h					; 89	; V-Scroll position
		db	000h					; 88	; H-Scroll position
		db	11110000b				; 87	; 1111CCCC | Backdrop colour (second palette line only; Colour 0 - F)
		db	11111011b				; 86	; 11111S11 | VRAM section sprites can use for tiles (0 = VRAM 0000 - 1FFF | 1 = 2000 - 3FFF)
		db	((VSH_Sprite>>7)&07Eh)|081h		; 85	; 1DCBA981 | DCBA98 = Sprite address (Multiples of 100 (0000 - 3F00))
		db	0FFh					; 84	; Unknown/Unused (keep at FF)
		db	0FFh					; 83	; Unknown/Unused (keep at FF)
		db	((VSH_Plane>>10)&00Eh)|0F1h		; 82	; 1111DCB1 | DCB = Map address (Multiples of 800 (0000 - 3800))
		db	10000000b				; 81	; 1DI000S0 | Display (0 Off | 1 On), Interrupt IE, Sprite Size (0 = 8 | 1 = 16)
		db	00010110b				; 80	; VHLIS11E | V-Scroll Right (0 Yes | 1 No), H-Scroll Top (0 Yes | 1 No), Left Column (0 No | 1 Yes), Interrupt IE1, Sprite Shift (0 Off | 1 On), External Sync

; ===========================================================================
; ---------------------------------------------------------------------------
; Subroutine to check the interrupt status safely
; ---------------------------------------------------------------------------
; The problem with loading i to a is if an interrupt occurs at that very
; moment, then result with be po (odd), not pe (even), which is the reverse
; ---------------------------------------------------------------------------

Checki:
		xor	a						; clear interrupt address in stack
		push	af						; ''
		pop	af						; ''
		ld	a,i						; load interrupt status
		ret	pe						; if interrupts are enabled, return
		dec	sp						; move back to to acquire interrupt address
		dec	sp 						; ''
		pop	af						; ''
		sub	1						; if it's still 0, then no interrupts occurred while "ld  a,i" was processing
		sbc	a,a						; ...otherwise it'd be non-0.  Thus a carry would set if non-interrupt
		and	1						; keep only interrupt on/off
		ret							; return

; ===========================================================================
; ---------------------------------------------------------------------------
; Kosinski (Special) decompression algorithm
; --- input -----------------------------------------------------------------
; hl = compressed art address
; de = VRAM address to write to
; ---------------------------------------------------------------------------
jf		macro	Cond,Address
		jr	Cond,Address					; if uncompressed, branch
		jr	nz,+						; if bitfield is still full, branch
		ld	a,(hl)						; load new bitfield
		inc	hl						; ''
		adc	a,a						; get next bit (and tack on end marker)
		jr	Cond,Address					; if uncompressed, branch
+
		endm
; ---------------------------------------------------------------------------

KosSpeDec:
		ld	c,0BFh						; prepare VDP control port
		ld	a,040h						; load upper byte of VRAM as write mode
		out	(c),e						; set VRAM address
		add	a,d						; ''
		out	(c),a						; '' (set VDP VRAM write)
		ld	d,a						; update a (with write bit on)
		dec	c						; load VDP data port
		ld	a,080h						; set to load flags
		jr	.Start						; jump into the loop

	.UNC:
		outi							; dump a byte
		inc	de						; advance VRAM address
	.Start:	add	a,a						; get next bit
		jf	nc,.UNC						; if uncompressed, branch
		add	a,a						; get next bit
		jf	nc,.LZRD					; if LZ type is RD, branch

	; --- LZCC ---

	.LZCC:
		ld	b,002h						; prepare CC count
		add	a,a						; get next bit
		jf	nc,.CC01					; if 01 is clear, branch
		inc	b						; increase count by 2
		inc	b						; ''

	.CC01:
		add	a,a						; get next bit
		jf	nc,.CC10					; if 10 is clear, branch
		inc	b						; increase count

	.CC10:
		push	hl						; store compressed data address
		ld	l,(hl)						; load retrace address
		ld	h,0BFh						; '' (BF##) the B is to remove the VDP write bit
		add	hl,de						; advance to correct VRAM address to read from
		ex	af,af'						; store bitfield

	; --- LZSS Main Loop ---
	; b = number of bytes
	; c = VDP data port
	; de = write address
	; hl = read address
	; ----------------------

	.LZSS:
		inc	c						; get VDP control port
		out	(c),l						; set VRAM read
		nop							; '' (delay)
		out	(c),h						; ''
		inc	hl						; ''
		dec	c						; get VDP data port
		in	a,(c)						; load byte
		inc	c						; get VDP control port
		out	(c),e						; set VRAM write
		nop							; '' delay
		out	(c),d						; ''
		inc	de						; ''
		dec	c						; get VDP data port
		out	(c),a						; save byte

		djnz	.LZSS						; repeat until done

		pop	hl						; restore compressed art address
		inc	hl						; advance to next byte
		ex	af,af'						; restore bitfield

		jr	.Start						; loop

	; --- LZRD ---

	.LZRD:
		ex	af,af'						; store bitfield
		ld	a,(hl)						; load retrace
		inc	hl						; advance to next byte
		push	hl						; store compressed data
		ld	h,(hl)						; load retrace and copy
		ld	l,a						; ''
		ld	a,h						; get only the copy
		and	00000111b					; ''
		jr	nz,.Cont					; if not 0, branch
		ex	(sp),hl						; reload compressed data
		inc	hl						; advance to next byte
		ld	a,(hl)						; load additional copy
		ex	(sp),hl						; restore retrace data
		or	a						; is there additional copy?
		jr	nz,.LZRDCC					; if so, branch (not finished decompressing yet)
		pop	hl						; restore stack
		ret							; return

	.LZRDCC:
		dec	a						; counter the add below...

	.Cont:
		add	a,002h						; adjust for CC
		ld	b,a						; ''
		ld	a,h						; get only the retrace
		or	00000111b					; ''
		rrca							; align
		rrca							; ''
		rrca							; ''
		and	0BFh						; set to clear the write bit
		ld	h,a						; put with other retrace bits
		add	hl,de						; move back to correct VRAM address

		jr	.LZSS						; jump to LZSS copy routine

; ===========================================================================
; ---------------------------------------------------------------------------
; Subroutine to write a series of VDP registers to the VDP control port
; ---------------------------------------------------------------------------

SetupVDP:
		ld	bc,(00Bh<<8)|0BFh				; prepare register count and VDP control port
		jr	.Write						; jump into the loop

	.Loop:
		add	a,b						; advance to correct register
		out	(c),a						; dump register ID
	.Write:	ld	a,080h						; prepare register bit
		outi							; dump register value
		jr	nz,.Loop					; if we haven't reached the last register, branch
		add	a,b						; advance to correct register
		out	(c),a						; dump register ID
		ret							; return

; ===========================================================================
; ---------------------------------------------------------------------------
; Clearing VRAM/CRAM
; ---------------------------------------------------------------------------

ClearVDP:

	; --- Clear CRAM ---

		ld	c,0BFh						; prepare VDP register
		ld	hl,0C000h					; set VDP to CRAM write address 00
		out	(c),l						; ''
		xor	a						; '' (clear a and delay)
		out	(c),h						; '' (set VDP CRAM write)
		ld	b,020h						; set size of CRAM clear (2 palette lines)

	.ClearCRAM:
		out	(0BEh),a					; clear CRAM
		djnz	.ClearCRAM					; repeat until it's all clear

	; --- Clear VRAM ---

		ld	hl,04000h					; set VDP to VRAM write address 0000
		out	(c),l						; ''
		nop							; delay
		out	(c),h						; '' (set VDP VRAM write)
		ld	bc,00040h+1					; set size of VRAM clear (0000 - 3FFF)

	.ClearVRAM:
		out	(0BEh),a					; clear VRAM
		djnz	.ClearVRAM					; repeat for VRAM clear
		dec	c						; decrease counter
		jr	nz,.ClearVRAM					; if it's still counting, branch

		ret							; return

; ===========================================================================
; ---------------------------------------------------------------------------
; Finish routine
; ---------------------------------------------------------------------------

Finish:

	; --- Restoring ---

		ld	c,0BFh						; set VDP regiser address
		ld	de,VSH_Store					; set VDP to VRAM read address 00
		out	(c),e						; ''
		ld	hl,R_RAM					; set RAM address to store
		out	(c),d						; '' (set VDP VRAM read)
		dec	c						; prepare VDP data port
		ld	b,R_RAM_END-R_RAM				; size to transfer

	.RestoreRAM:
		ini							; transfer RAM
		jr	nz,.RestoreRAM					; repeat until RAM is restored

	; --- Clearing ---

		callx	ClearVDP					; clear VDP (VRAM/CRAM)
		ldx	hl,RestoreVDP					; load VDP register list
		callx	SetupVDP					; restore VDP registers

	; --- Restore interrupt status and return ---

		exx							; restore address registers
		pop	af						; reload interupt status
		ret	po						; return (if interrupts were disabled)
		ei							; enable interrupts again
		ret							; return

; ===========================================================================
; ---------------------------------------------------------------------------
; included data
; ---------------------------------------------------------------------------

LogoPal_Hi:	db	000h,010h,020h,034h,038h,03Dh,03Fh, 03Fh,03Dh,038h,034h,020h,010h,000h,000h,000h
LogoPal_Mid:	db	000h,010h,020h,034h,038h,03Dh,03Fh, 038h,034h,020h,010h,000h,000h,000h,000h,000h
LogoPal_Low:	db	000h,010h,020h,034h,038h,03Dh,03Fh, 000h,000h,000h,000h,000h,000h,000h,000h,000h
LogoArt:	binclude "Contest Logo/Logo Art.ksp"
LogoMap:	binclude "Contest Logo/Logo Map.ksp"

; ---------------------------------------------------------------------------
; Unique mappings data (because the logo has a few tiles different in spots)
; ---------------------------------------------------------------------------

LogoMap_Unique:	dw	LogoMap_1
		dw	LogoMap_2
		dw	LogoMap_3

LogoLog:	binclude "Contest Logo/Logo Map.log"			; relative VRAM plane address and size for copying unique uncompressed mappings
LogoMap_1:	binclude "Contest Logo/Logo Map 1.map"			; unique uncompressed mappings for "hi" frame
LogoMap_2:	binclude "Contest Logo/Logo Map 2.map"			; unique uncompressed mappings for "mid" frame
LogoMap_3:	binclude "Contest Logo/Logo Map 3.map"			; unique uncompressed mappings for "low" frame

; ===========================================================================
; ---------------------------------------------------------------------------
; VDP registers to restore
; ---------------------------------------------------------------------------

RestoreVDP:
