
VdpIn_Status equ &99
VdpOut_Control equ &99
VdpOut_Indirect equ &9B
Vdp_SendByteData equ &9B	
VdpIn_Data equ &98
VdpOut_Data equ &98


;Bit 1 seems to be backwards to documentation in v9938 guide?
SRC_EqRight	  equ %00000000	
SRC_EqLeft	  equ %00000100
SRC_NeRight	  equ %00000010
SRC_NeLeft    equ %00000110

DIR_MAJ		  equ %00000001
DIR_DownRight equ %00000000
DIR_DownLeft  equ %00000100
DIR_UpRight   equ %00001000
DIR_UpLeft    equ %00001100

LOG_IMP	 	  equ %00000000
LOG_AND	 	  equ %00000001
LOG_OR	 	  equ %00000010
LOG_XOR 	  equ %00000011
LOG_NOT 	  equ %00000100

LOG_TIMP	  equ %00001000
LOG_TAND	  equ %00001001
LOG_TOR	 	  equ %00001010
LOG_TXOR 	  equ %00001011
LOG_TNOT 	  equ %00001100

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	ifdef vasm
		include "..\SrcALL\VasmBuildCompat.asm"
	else
		read "..\SrcALL\WinApeBuildCompat.asm"
	endif
	read "..\SrcALL\CPU_Compatability.asm"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


	include "..\SrcALL\V1_Header.asm"
	
ProgramStart:	
	;Initialize screen
	ld c,VdpOut_Control	
	ld b,VDPScreenInitData_End-VDPScreenInitData
	ld hl,VDPScreenInitData
	otir
	
	call HMMCtest ;Copy Bitmap from Cpu Ram
	
	;call VramTest	;Test RW Vram
	
	call pause
	call pause
	call pause
	
	call YMMMtest ;Test L/R Directions (Do HMMCtest first)
	call YMMMtest2 ;Test U/D Directions
	;call pause
	;call pause
	;call pause
	;call HMMMtest ; Fast copy (do HMMCtest first)
	
	;call HMMVtest	;Fast fill
	
	
	;call LMMCtest ;Logical Copy Bitmap from Cpu Ram
	;call LMCMtest	;Logical copy to Cpu (do HMMCtest first)
	;call LMMMtest	;Logical copy (do HMMCtest first)
	;call LMMVtest	;Logical fill
	;Call LINEtest	;Draw Line
	

	di
	halt
	
	;Call PSETtest	;Draw Pixel
	
	;call POINTtest	;ReadPixel (Do PSETtest first)
	;call SRCHtest	;FindPixel (Do PSETtest first)
	
	
	;call STOPtest	;Stop
	
	di
	halt
	
	call pause
	call pause
	call pause
	
	
	push bc
		call TextScreen
	pop bc
	
	ld a,b
	call ShowHex
	ld a,c
	call ShowHex
	
	call newline
	
	;ld hl,ProgramStart				;Address to show (Code - For Vramtest)
	ld hl,Sprite					;Address to show (Sprite - for LMCMtest)
	ld c,32						;Bytes to show
	call Monitor_MemDumpDirect	;Show memory to screen
	
	ld hl,&D000					;Address to show
	ld c,64						;Bytes to show
	call Monitor_MemDumpDirect	;Show memory to screen
	
	di
	halt
	
pause:
	push bc
		ld bc,0
pauseb:	
		dec bc
		ld a,b
		or c
		jr nz,pauseb
	pop bc
	ret
pause2:	
		dec bc
		ld a,b
		or c
		jr nz,pause2
	ret	
TextScreen:
	call &006F			;INIT32 - initialises the screen to GRAPHIC1 mode (32x24)
	ld a,32				;Set Screen width to 32 chars
	ld (&F3B0),a		;LINLEN 
	
	ret
	
PrintChar equ &00A2
	
NewLine:
	push af
		ld a,13			;Carriage return
		call PrintChar
		ld a,10			;Line Feed
		call PrintChar
	pop af
	ret
SimpleBuild equ 1
	include "\SrcALL\Multiplatform_Monitor_RomVer.asm"
	include "\SrcALL\Multiplatform_ShowHex.asm"
	include "\SrcALL\Multiplatform_MonitorMemdump.asm"
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;VRAM READ /Write
VramTest:
	ld a,&00
	ld HL,&0000
	call VDP_SetWriteAddress 		;Write to VRAM &00000
	
	ld hl,ProgramStart				;Source Program code
	ld bc,ProgramEnd-ProgramStart
	call ldirToVram
	
	
	ld a,&00
	ld HL,&0000						
	call VDP_SetReadAddress 		;Read from VRAM &00000
	
	ld hl,&D000						;Destination &D000
	ld bc,128
	call LDIRFromVRAM
	ret


LDIRToVRAM:	;Copy BC bytes from HL to VRAM (Set Write Address First)
	ld a,(hl)				;Read a byte from VRAM via port &98
	out (VdpOut_Data),a		;Send To Vram
	inc hl
	dec bc					;Repeat until BC=0
	ld a,b
	or c
	jr nz,LDIRToVRAM
	ret	
	
LDIRFromVRAM:	;Copy BC bytes from VRAM to HL (Set Read Address First)
	in a,(VdpIn_Data)		;Read byte from VRAM via port &98
	ld (hl),a				;Write to RAM
	inc hl
	dec bc					;Repeat until BC=0
	ld a,b
	or c
	jr nz,LDIRFromVRAM
	ret	
	
;       A        H        L
;000000SS YMYYYYYY YXXXXXXX	S=Screen Y=vert line X=horiz byte M=RW mode


VDP_SetReadAddress:	;AHL=Address
	ld C,0			;Bit 6=0 when reading, 1 when writing
	jr VDP_SetAddress
VDP_SetWriteAddress:
	ld C,64
VDP_SetAddress:
	rlc     h
	rla
	rlc     h
	rla
	srl     h
	srl     h
	;di
	out     (VdpOut_Control),a       ;set bits 15-17
	ld      a,14+128
	out     (VdpOut_Control),a
	ld      a,l           ;set bits 0-7
	nop
	out     (VdpOut_Control),a
	ld      a,h           ;set bits 8-14
	or      C            ; 64= write access 0=read
	;ei
	out     (VdpOut_Control),a 
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
;LMMC - Logical Send Sprite data from CPU to VRAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
LMMCtest:
	ld hl,sprite
	ld a,(hl)				;First Color of sprite data
	rrca
	rrca
	rrca
	rrca
	push hl
		ld c,LOG_XOR		;Logical XOR (invert back)
		ld ix,50			;Xpos
		ld iy,0				;Ypos
		ld hl,48			;Width
		ld de,48			;Height
		call VDP_LMMC_Generated_ViaStack
	pop hl
	call LMMCtest2
	
	ld hl,sprite
	ld a,(hl)			;First Color of sprite data
	rrca
	rrca
	rrca
	rrca
	push hl
		ld c,LOG_NOT		;Logical NOT (Invert pixels)
		ld ix,100			;Xpos
		ld iy,0				;Ypos
		ld hl,48			;Width
		ld de,48			;Height
		call VDP_LMMC_Generated_ViaStack
	pop hl
	call LMMCtest2
	ret
	
LMMCtest2:	
	ld bc,SpriteEnd-Sprite-1	;Length of prite		
	ld a,(hl)					;Low Nibble
	out (Vdp_SendByteData),a	;Send nibble to vdp
LMMCNextByte:
	call WaitForTrFlag			;We should really do this 
	inc hl							;but actually don't need to?
	ld a,(hl)					;Low Nibble
	rrca
	rrca
	rrca
	rrca
	out (Vdp_SendByteData),a	;Send High nibble to vdp
	
	call WaitForTrFlag			;We should really do this
	ld a,(hl)					;Read next byte of sprite
	out (Vdp_SendByteData),a	;Send Low nibble to vdp (&99)
	dec bc
	ld a,b
	or c
	jr nz,LMMCNextByte
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Fill ram from calculated values (first in A)
	
VDP_LMMC_Generated_ViaStack:
		push af
			ld a,&B0	;Command Byte (don't change)
			or c
			ld c,a
		pop af
		push bc
		ld c,a			;First Pixel / Logical Operation
		push bc
		push de			;Height
		push hl			;Width
		push iy			;Ypos
		push ix			;Xpos
		
		ld hl,0
		add hl,sp
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_LMMC_Generated
		pop hl
		
		ld bc,12	;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
		
VDP_LMMC_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)
	call SetIndirect	
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;HMMC - Send Sprite data from CPU to VRAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
HMMCtest:
	ld hl,sprite	;Sprite Address
	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 sprite	 Data
NextByte:
	;call WaitForTrFlag		;We should really do this 
							;but actually don't need to?	
	ld a,(hl)					;Read next byte of sprite
	out (Vdp_SendByteData),a	;Send next byte to vdp via port &9B
	dec bc
	inc hl
	ld a,b
	or c
	jr nz,NextByte
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Fill ram from calculated values (first in A)
VDP_HMMC_Generated_ViaStack:	
		ld c,&F0		;Command Byte (don't change)
		push bc
		ld b,DIR_DownRight	;Direction
		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 WaitForCeFlag	;Wait for VDP to be ready
			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
	out (VdpOut_Control),a
	ld c,VdpOut_Indirect ;Port (&9B)
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;YMMM - Fast Copy - Y Axis ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
YMMMtest:
	ld b,DIR_DownRight			;Copy Right
	ld iy,50		;YSource
	ld de,50		;Height
	exx
		ld hl,70	;Xdest
		ld de,100	;YDest
	exx
	call VDP_YMMM_ViaStack		;Fast Copy Vram->Vram	
	
	ld b,DIR_DownLeft			;Copy Left
	ld iy,50		;YSource
	ld de,50		;Height
	exx
		ld hl,70	;Xdest
		ld de,150	;YDest
	exx
	call VDP_YMMM_ViaStack		;Fast Copy Vram->Vram	
	ret
	
YMMMtest2:
	ld b,DIR_DownRight			;Copy Downwards (overlap - will fill area)
	ld iy,00		;YSource
	ld de,50		;Height
	exx
		ld hl,70	;Xdest
		ld de,04	;YDest
	exx
	call VDP_YMMM_ViaStack		
	
	ld b,DIR_UpLeft				;Copy upwards (Overlap - Move area)
	ld iy,50		;YSource
	ld de,50		;Height
	exx
		ld hl,70	;Xdest
		ld de,54	;YDest
	exx
	call VDP_YMMM_ViaStack		;Fast Copy Vram->Vram			
	ret	
	
	
VDP_YMMM_ViaStack:		;Fast copy from VRAM to VRAM (Src+Dest Same Y)
		ld c,&E0		;Command Byte (don't change)
		push bc
		push bc			;Direction + Color (unused)
		push de			;Height
		push hl			;Width	(unused)
		exx
			push de		;DestY
			push hl		;DestX 
		exx
		push iy			;SourceY
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_YMMM
		pop hl
		
		ld bc,14		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
				
VDP_YMMM:				;Fast Copy - Same Y 
	ld a,34				;AutoInc From 34
	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
	ret														  ;outi x 13
	

	



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
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:	

;HMMM - Fast Copy The sprite ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
HMMMtest:
	ld b,DIR_DownRight	;Copy Direction (DownRight Fastest)
	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
	ret
	
	
VDP_HMMM_ViaStack:		;Fast copy from VRAM to VRAM

		ld c,&D0		;Command Byte (don't change)
		push bc
		push bc			;Color (unused) / Direction
		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 WaitForCeFlag	;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

;STOP - Stop Processing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
STOPtest:
	ld ix,0		
	ld iy,0		
	ld hl,256	
	ld de,256	
	ld a,&FF
	call VDP_HMMV_ViaStack	;Test Fill
	ld bc,128
	call pause2
	
	call VDP_STOP		;Abort the command
	ret
	
VDP_STOP:
	xor a 				;Command 0
	out (VdpOut_Control),a		
	ld a,128+46			;Command Reg 46
	out (VdpOut_Control),a
	ret
	
;HMMV - Fill area ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
HMMVtest:
	ld ix,0			;XDest
	ld iy,0			;YDest
	ld hl,128		;Width
	ld de,20		;Height
	ld a,&FF		;Colors (&LR)
	call VDP_HMMV_ViaStack		;Fast Copy Vram->Vram
	
	ld ix,128		;XDest
	ld iy,24		;YDest
	ld hl,128		;Width
	ld de,20		;Height
	ld a,&CD		;Colors (&LR)
	call VDP_HMMV_ViaStack		;Fast Copy Vram->Vram
	ret
	

VDP_HMMV_ViaStack:	;Fill Area
		ld bc,&00C0		;Command Byte (don't change)
		push bc
		ld c,a			;Color / Direction (UNUSED)
		push bc			
		push de			;Height
		push hl			;Width
		push IY			;DestY
		push IX			;DestX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_HMMV
		pop hl
		
		ld bc,12		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
				
VDP_HMMV:				;Fast copy from VRAM to VRAM
	ld a,36				;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						 ;outi x 11
	ret											
	
	
;LMCM - Logical  Move from Vram to Cpu;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LMCMtest:
	ld ix,50			;Xpos
	ld iy,50			;Ypos
	ld hl,48			;Width
	ld de,48			;Height
	call VDP_LMCM_ViaStack

	ld hl,&D000			;Destination Vram
	ld bc,SpriteEnd-Sprite-1	;Length of sprite	
LMCM_NextByte:
	Call WaitForTrFlag
	Call GetColorByte	;read a color pixel
	ld (hl),a			;Write a byte to ram
	inc hl
	dec bc				;Repeat until BC=0
	ld a,b
	or c
	jr nz,LMCM_NextByte
	
	call VDP_GetStatusFirwareDefault
	ret
	
GetColorByte:
	ld a,7
	call VDP_GetStatusRegisterB
	in a,(VdpIn_Status)		;Read next byte of sprite
	ret
	

VDP_LMCM_ViaStack:		;Fast copy from VRAM to VRAM
		Call GetColorByte	;Clear TR Flag	
		ld c,&00A0		;Command Byte (don't change)
		push bc
		push bc			;Direction / Color (unused)
		push de			;Height
		push hl			;Width
		push de			;DestY (unused)
		push hl			;DestX (unused)
		push iy			;SourceY
		push ix			;SourceX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_LMCM
		pop hl
		
		ld bc,16		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl	
		ret
				
VDP_LMCM:				;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





;LMMM - Logical Copy The sprite ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
LMMMtest:
	ld hl,0				;XDest
	ld c,LOG_IMP
	call LMMMtestOne
	ld hl,20			;XDest
	ld c,LOG_AND
	call LMMMtestOne
	ld hl,40			;XDest
	ld c,LOG_OR
	call LMMMtestOne
	ld hl,60			;XDest
	ld c,LOG_XOR
	call LMMMtestOne
	ld hl,80			;XDest
	ld c,LOG_NOT
	call LMMMtestOne
	ld hl,100			;XDest
	ld c,LOG_TIMP
	call LMMMtestOne
	ld hl,120			;XDest
	ld c,LOG_TAND
	call LMMMtestOne
	ld hl,140			;XDest
	ld c,LOG_TOR
	call LMMMtestOne
	ld hl,160			;XDest
	ld c,LOG_TXOR
	call LMMMtestOne
	ld hl,180			;XDest
	ld c,LOG_TNOT
	call LMMMtestOne
	ret
	
LMMMtestOne:
		ld de,0			;YDest
		ld a,c
	exx
	ld c,a
	ld ix,50			;XSource
	ld iy,50			;YSource
	ld hl,20			;Width
	ld de,48			;Height
	call VDP_LMMM_ViaStack	;Fast Copy Vram->Vram
	ret
	
	
VDP_LMMM_ViaStack:		;Fast copy from VRAM to VRAM		
		ld a,&90		;Command Byte (don't change)
		or c			;or in Logical Operation
		ld c,a	
		push bc
		ld b,&00		;Direction
		push bc
		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 WaitForCeFlag	;Wait for VDP to be ready
			call VDP_LMMM
		pop hl
		
		ld bc,16		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret		
VDP_LMMM:				;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


;Line - Line draw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
LINEtest:
	ld ix,128		;XDest
	ld iy,128		;YDest
	ld hl,64		;Long Side (NX)
	ld de,64		;Short Side (NY)
	ld a,&0F		;Color  (White)
	ld b,DIR_DownRight;Direction
	call VDP_LINE_ViaStack		
	
	ld ix,128		;XDest
	ld iy,128		;YDest
	ld hl,64		;Long Side (NX)
	ld de,10		;Short Side (NY)
	ld a,&02		;Color (Dark Green)
	ld b,DIR_DownLeft;Direction
	call VDP_LINE_ViaStack		
	
	ld ix,128		;XDest
	ld iy,128		;YDest
	ld hl,64		;Long Side (NX)
	ld de,10		;Short Side (NY)
	ld a,&03		;Color (Light Green)
	ld b,DIR_DownLeft+DIR_MAJ	
					;Flip MAJor axis (0=Maj=X 1=MajY)
	call VDP_LINE_ViaStack
	ret
	

VDP_LINE_ViaStack:		;Fast copy from VRAM to VRAM
		ld c,&70	 	;Command Byte (don't change)
		push bc
		ld c,a			;Color Byte
		push bc			;B=Direction (Bit 0 = MAJ) C=Color
		push de			;Height
		push hl			;Width
		push IY			;DestY
		push IX			;DestX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_LINE
		pop hl
		
		ld bc,12		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret	
VDP_LINE:		
	ld a,36				;AutoInc From 36
	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
	ret														  ;outi x 11
	

;POINT - get pxel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
POINTtest:
	ld HL,120			;XDest
	ld DE,120			;YDest
	call VDP_POINT_ViaStack	
	ld b,a
	
	push bc
		ld HL,128		;XDest
		ld DE,128		;YDest
		call VDP_POINT_ViaStack		
	pop bc
	ld c,a
	ret
	

VDP_POINT_ViaStack:		;Fast copy from VRAM to VRAM
		ld bc,&0040		;Command
		push bc
		push bc			
		push de			;Height (UNUSED)
		push hl			;Width  (UNUSED)
		push DE			;DestY  (UNUSED)
		push HL			;DestX  (UNUSED)
		push DE			;DestY  (UNUSED)
		push HL			;DestX  (UNUSED)
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_POINT
		pop hl
		
		ld bc,16		;Skip 6 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		call WaitForCeFlag	;Wait for VDP to be ready
		Call GetColorByte	;Read Status Reg 7
		push af
			call VDP_GetStatusFirwareDefault	
		pop af		
		ret
				
VDP_POINT:				;Logical POINT
	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;outi x 15
	ret
	
;PSET - Fill Pixel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
PSETtest:
	ld b,5
PSETtestAgain:
	push bc
		ld HL,120		;XDest
		ld DE,120		;YDest
		ld a,&0F		;Color 
		ld c,LOG_IMP	;Logical OP
		call VDP_PSET_ViaStack	
		
		ld HL,128		;XDest
		ld DE,128		;YDest
		ld a,&02		;Color 
		ld c,LOG_XOR 	;Logical OP (XOR)
		
		call VDP_PSET_ViaStack	
		call pause 		;Wait (Xored pixel will flash)
	pop bc
	djnz PSETtestAgain
	ret
	
	

VDP_PSET_ViaStack:		;Fast copy from VRAM to VRAM
		push af
			ld a,&50	;Command Byte (don't change)
			or c		;OR in Logical Operation
			ld c,a
		pop af
		push bc
		ld c,a			;Color / Direction
		push bc			
		push de			;Height (UNUSED)
		push hl			;Width  (UNUSED)
		push DE			;DestY
		push HL			;DestX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_PSET
		pop hl
		
		ld bc,12		;Skip 6 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
				
VDP_PSET:				;Logical PSET
	ld a,36				;AutoInc From 36
	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
	ret													 ;outi x 11
	
;SRCH - Search Pixel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

SRCHtest:
		ld b,SRC_EqRight;Search Right
		ld a,&0F		;Search pixel color
		ld HL,0			;XDest
		ld DE,120		;YDest
		call VDP_SRCH_ViaStack
	ret
	

VDP_SRCH_ViaStack:		
		ld c,&60	;Command Byte (don't change)
		push bc
		ld c,a		;Color / Direction
		push bc
		push de		;Height (unused)
		push hl		;Width (unused)	
		push de		;DestY (unused)
		push hl		;DestX (unused)
		push de		;SourceY
		push hl		;SourceX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_SRCH
			call WaitForCeFlag	;Wait for VDP to be ready
		pop hl
		
		ld bc,16		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
	
		ld bc,&0000		;Result of not found
		ld a,2
		call VDP_GetStatusRegisterB
		in a,(VdpIn_Status)			;Did we find it?
		and %00010000	;BD - Zero if Color not found (BD=Border Detect?)
		jr z,VDP_SRCH_Done
		
		ld a,8
		call VDP_GetStatusRegisterB
		in a,(VdpIn_Status)			;Low Byte of Xpos
		ld c,a
		ld a,9
		call VDP_GetStatusRegisterB
		in a,(VdpIn_Status)			;High Byte of Xpos
		ld b,a
VDP_SRCH_Done
		call VDP_GetStatusFirwareDefault
		ret
				
VDP_SRCH:				;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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;LMMV - Logical Fill area ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
LMMVtest:
	ld ix,0			;XDest
	ld c,LOG_IMP
	call LMMVtestOne
	ld ix,20		;XDest
	ld c,LOG_XOR
	call LMMVtestOne
	ret
LMMVtestOne:
	ld iy,0			;YDest
	ld hl,20		;Width
	ld de,128		;Height
	ld a,&0F		;Color (one nibble only)
	call VDP_LMMV_ViaStack		;Fast Copy Vram->Vram
	ret
	
VDP_LMMV_ViaStack:		;Fast copy from VRAM to VRAM
		push af
			ld a,&80	;Command Byte (don't change)
			or c		;or in Logical Operation
			ld c,a
		pop af
		push bc
		ld b,&00		;Direction
		ld c,a			;Color
		push bc			
		push de			;Height
		push hl			;Width
		push IY			;DestY
		push IX			;DestX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_LMMV
		pop hl
		
		ld bc,12		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
				
VDP_LMMV:				;Logical Flood Fill
	ld a,36				;AutoInc From 36
	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
	ret													 ;outi x 11
	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
;VDP_FirmwareSafeWait
WaitForCeFlag:	;Command Execution - Wait for VDP to be ready
	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
	rra						;S#2  [TR ] [VR ] [HR ] [BD ] [ 1 ] [ 1 ] [EO ] [CE ] 
	ret nc
	jr VDP_DoWait

WaitForTrFlag:	;Transmit Ready flag
	ld a,2
	call VDP_GetStatusRegisterB
	in a,(VdpIn_Status)
	and %10000000
	jr z,WaitForTrFlag
	ret

VDP_GetStatusFirwareDefault:	;Set Status Reg
	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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	
ProgramEnd:	
	include "..\SrcALL\V1_Footer.asm"