
VdpIn_Status equ &99
VdpOut_Control equ &99
VdpOut_Indirect equ &9B
Vdp_SendByteData equ &9B	

;For Cartridge	
	org &4000				;Base Cart Address
	db "AB"					;Fixed Header
	dw ProgramStart 		;Pointer to start of program
	db 00,00,00,00,00,00	;Unused

	;;;Effectively Code starts at address &400A

ProgramStart:			;Program Code Starts Here
	
	;Initialize screen
	ld c,VdpOut_Control	
	ld b,VDPScreenInitData_End-VDPScreenInitData
	ld hl,VDPScreenInitData
	otir
	
	;di
	;halt
	
	;Send Sprite data from CPU to VRAM
	ld hl,sprite
	ld a,(hl)		;First byte of sprite data
	inc hl
	push hl
		ld ix,50	;Xpos
		ld iy,50	;Ypos
		ld hl,48	;Width
		ld de,48	;Height
		call VDP_HMMC_Generated_ViaStack
	pop hl
	
	ld bc,SpriteEnd-Sprite-1	;Length of prite	
NextByte:
	ld a,(hl)					;Read next byte of sprite
	out (Vdp_SendByteData),a	;Send next byte to vdp
	dec bc
	inc hl
	ld a,b
	or c
	jr nz,NextByte
	
	
	
	;Fast Copy The sprite
	ld ix,50		;XSource
	ld iy,50		;YSource
	ld hl,48		;Width
	ld de,48		;Height
	exx
		ld hl,100	;Xdest
		ld de,100	;YDest
	exx
	call VDP_HMMM_ViaStack		;Fast Copy Vram->Vram
	
	
	;Fast Copy The sprite
	ld ix,50		;XSource
	ld iy,50		;YSource
	ld hl,48		;Width
	ld de,48		;Height
	exx
		ld hl,100	;Xdest
		ld de,256	;YDest
	exx
	call VDP_HMMM_ViaStack		;Fast Copy Vram->Vram
	;Fast Copy The sprite
	ld ix,50		;XSource
	ld iy,50		;YSource
	ld hl,48		;Width
	ld de,48		;Height
	exx
		ld hl,100		;Xdest
		ld de,256+192-48 ;YDest
	exx
	call VDP_HMMM_ViaStack		;Fast Copy Vram->Vram
	
	
	ld de,0
		
;MSX2+ only
	;ld a,%00000000				;Mask
	;ld a,%00000010				;NoMask
	ld a,%00000011				;2pages
	
	out (VdpOut_Control), a
	ld a,128+25					;Hscroll
	out (VdpOut_Control), a
;Show page 1	
	ld a,%00111111
	out (VdpOut_Control), a
	ld a,128+2					;Page Select
	out (VdpOut_Control), a	

ScrollAgain:
	
PauseAgain:
	dec bc
	ld a,b
	or c
	jr nz,PauseAgain
	
;MSX2 HVShift	
	; ld a,e	
	; ;;   YYYYXXXX
	; add %00000001				;Xoffset
	; ;add %00010000				;Yoffset
	; ;sub %00000001				;Xoffset
	; ;sub %00010000				;Yoffset
	; ld e,a
	; out (VdpOut_Control), a
	; ld a,128+18					;offset
	; out (VdpOut_Control), a
	; inc de						;Next Tile
	; ld bc,$FFFF					;Delay
	
;MSX2 HVShift + SoftScroll
	; ld a,e
	; and %00000111				;8 pixel shift
	; out (VdpOut_Control), a
	; ld a,128+18
	; out (VdpOut_Control), a

	 ; push de
		 ; ld hl,&1800			;Tilemap
		 ; call VDP_SetWriteAddress
		; srl d					;Remaining bits for soft shift
		; rr e
		; srl d
		; rr e
		; srl d
		; rr e
	
		; ld hl,VdpBuffer			;Tilemap cache (&C000)
		; add hl,de				;Add scroll offset
		; ld de,768
		; call OutiDE				;Send to VRAM
	 ; pop de
	 ; inc de						;Shift position
	 ; ld bc,&2FFF				;Delay

	
;MSX2 Vscroll
	ld bc,3000					;Delay
	ld a,e	
	out (VdpOut_Control), a
	ld a,128+23					;Vscroll
	out (VdpOut_Control), a
	inc de 						;Scroll vertically
	
	
;MSX2+ HShift	
	; ld bc,5000					;Delay
	; push de
		; ld a,e
		; and %00000111
		; out (VdpOut_Control), a
		; ld a,128+27				;Hscroll
		; out (VdpOut_Control), a
		
		; rr d
		; rr e
		; rr e
		; rr e
		; ld a,e
		; and %00111111
		; xor %00111111
		; out (VdpOut_Control), a
		; ld a,128+26				;Hscroll
		; out (VdpOut_Control), a
	; pop de	
	; inc de						;Scroll Horizontally
	
	jp ScrollAgain

	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
Sprite:	
	incbin "\ResALL\Sprites\RawMSX.RAW"
SpriteEnd:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	;Settings to define our graphics screen

VDPScreenInitData:	
	db %00000110,128+0		;mode register #0
	db %01100000,128+1		;mode register #1
	db 31		,128+2		;pattern name table
	db 239		,128+5		;sprite attribute table (LOW)
	db %11110000,128+7		;border colour/character colour at text mode
	db %00001010,128+8		;mode register #2
	db %00000000,128+9	 	;mode register #3
	db 128		,128+10		;colour table (HIGH)
VDPScreenInitData_End:	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
VDP_HMMM_ViaStack:		;Fast copy from VRAM to VRAM

		ld bc,&00D0		;Command Byte (don't change)
		push bc
		push bc			;unused
		push de			;Height
		push hl			;Width
		exx
			push de		;DestY
			push hl		;DestX
		exx
		push iy			;SourceY
		push ix			;SourceX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call VDP_FirmwareSafeWait	;Wait for VDP to be ready
			call VDP_HMMM
		pop hl
		
		ld bc,16		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
				
VDP_HMMM:				;Fast copy from VRAM to VRAM

	ld a,32				;AutoInc From 32
	call SetIndirect
	
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3	
	ret														  ;outi x 15
	

; MyHMMM:						;Tile Copy command Vars 	
; MyHMMM_SX:	defw &0000 		;SY 32,33	;Destination Xpos
; MyHMMM_SY:	defw &0200 		;SY 34,35	;Tiles start 512 pixels down
; MyHMMM_DX:	defw &0000 		;DX 36,37	;Destination X
; MyHMMM_DY:	defw &0000 		;DY 38,39	;Destination Y
; MyHMMM_NX:	defw &0008 		;NX 40,41 	;Width=8px
; MyHMMM_NY:	defw &0008 		;NY 42,43	;Height=8px
				; defb 0     		;Color 44 	;unused
; MyHMMM_MV:	defb 0     		;Move 45	;Unused
				; defb %11010000 	;Command 46	;HMMM command - Don't mess with this 
; T_TemplateCommands_End	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
		
VDP_HMMC_Generated_ViaStack:	;Fill ram from calculated values (first in A)

		ld bc,&00F0		;Command Byte (don't change)
		push bc
		ld c,a			;First Pixel (B unused)
		push bc
		push de			;Height
		push hl			;Width
		push iy			;Ypos
		push ix			;Xpos
		
		ld hl,0
		add hl,sp
		push hl
			call VDP_HMMC_Generated
		pop hl
		
		ld bc,12	;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
		
VDP_HMMC_Generated:		;Fill ram from calculated values (first in A)

	;Set the autoinc for more data
	ld a,36				;AutoInc From 36
	call SetIndirect
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3			; 11 outis
	
	ld a,128+44			;128 = NO Increment ;R#44    Color byte (from CPU->VDP)
SetIndirect:
	out (VdpOut_Control),a		
	ld a,128+17			;R#17 -	Indirect Register 128=no inc  [AII] [ 0 ] [R5 ] [R4 ] [R3 ] [R2 ] [R1 ] [R0 ] 	
	out (VdpOut_Control),a
	ld c,VdpOut_Indirect	
	ret

;MyHMMC:								:HMMC Command looks like this
;MyHMMC_DX:	defw &0000 ;DX 36,37
;MyHMMC_DY:	defw &0000 ;DY 38,39
;MyHMMC_NX:	defw &0032 ;NX 40,41
;MyHMMC_NY:	defw &0032 ;NY 42,43
;MyHMMCByte:	defb 255   ;Color 44
;				defb 0     ;Move 45
;				defb %11110000 ;Command 46	


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	;Wait for VDP to be ready
VDP_FirmwareSafeWait:
	di
	call VDP_Wait						;Wait for the VDP to be available
	call VDP_GetStatusFirwareDefault	;Reset selected Status register to 0 for the firmware
	ret

VDP_Wait: 			;Get The status register - Disable interrupts, 
						;as they require status register 0 to be selected!

	call VDP_GetStatusRegister
VDP_DoWait:
	in a,(VdpIn_Status)	;Status register 2	- S#2  [TR ] [VR ] [HR ] [BD ] [ 1 ] [ 1 ] [EO ] [CE ] 
	rra
	ret nc
	jr VDP_DoWait




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;Set Status Reg

VDP_GetStatusFirwareDefault:
	xor a
	jr VDP_GetStatusRegisterB
VDP_GetStatusRegister:		;Get The status register - Disable interrupts!
	ld a,2					;S#2  [TR ] [VR ] [HR ] [BD ] [ 1 ] [ 1 ] [EO ] [CE ] - Status register 2
VDP_GetStatusRegisterB:
	out (VdpOut_Control),a
	ld a,128+15				;R#15  [ 0 ] [ 0 ] [ 0 ] [ 0 ] [S3 ] [S2 ] [S1 ] [S0 ] - Set Stat Reg to read
	out (VdpOut_Control),a
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	org &C000		;Pad to 32k