
;Sprite Controller for Ubicom SX28A @ 64MHz Clock (Turbo mode).
;By Phil Ruston 18-7-2005

; v46 - changes:
; skip sprites if totally left clipped
; added a NOP where SRAM access delay was < 4 cycles
; Status.... Changes seem to have taken effect.

;---------------------------------------------------------------------------------------------
; Chip Config......

DEVICE		SX28AC,TURBO,BANKS8,OSCHS3,SYNC,OPTIONX,IFBD

;---------------------------------------------------------------------------------------------
IRC_CAL		IRC_SLOW	;to stop SASM warning only
;----------------------------------------------------------------------------------------------
FREQ		64_000_000	;for debug only
;----------------------------------------------------------------------------------------------

RESET		init_chip


; Generic macros...

SKIPIFZERO	macro
		SB status.2
		endm
SKIPNOTZERO	macro
		SNB status.2
		endm

SKIPONCARRY	macro
		SB status.0
		endm
SKIPNOCARRY	macro
		SNB status.0
		endm

SKIPONBORROW	macro
		SNB status.0
		endm
SKIPNOBORROW	macro
		SB status.0
		endm


; Project macros..


SRAM_ACCESS_DELAY	macro
			NOP
			NOP
			NOP
			NOP
			endm

LATCH_HI		macro
			CLRB RA.addr_hi_latch	;latch clock line 0 (for def high byte)		
			NOP			;short delay for stability
			SETB RA.addr_hi_latch	;latch clock line 1 (rising edge latch)
			endm

;---------------------------------------------------------------------------------------------

; Project variables


sync0	 	equ $08		;used only during synchronization
sync1	 	equ $09		;	""	""	""
sync2	 	equ $0a		;	""	""	""
sync3	 	equ $0b		;	""	""	""
temp		equ $0c		;	""	""	""
count		equ $0d		;	""	""	""


SPRITE_COUNT 	EQU $08
LINE_COUNTER	EQU $09
TEMPBYTE	EQU $0a
Y_SLICE	   	EQU $0b
CLIP_INDEX  	EQU $0c
SPRITE_NUMBER	EQU $0d
SYNC_PADDING    EQU $0e


; Project Equates

addr_hi_latch	equ 0
busy_signal	equ 1
x_mask		equ 2
y_mask		equ 3

;--------------------------------------------------------------------------------------------
; *** PAGE 0 ***
;--------------------------------------------------------------------------------------------

		ORG $000

;--------------------------------------------------------------------------------------------

init_chip	MOV W,#$fc		;Set bits 0/1 of PORT A to outputs
		MOV !RA,W
		MOV W,#$00		;Set bits 0-7 of PORT C to outputs
		MOV !RC,W
		
		MOV M,#$0d		;Mode $0D = adjust voltage levels
		MOV W,#$00		;Set all ports to use CMOS levels
		MOV !RA,W
		MOV !RB,W
		MOV !RC,W

		MOV W,#$0		;Set bits 0/1 of PORT A low
		MOV RA,W

		MOV W,#$df
		MOV !OPTION,W		;RTCC counts on instruction clock 

;----------------------------------------------------------------------------------------

init_sys	PAGE $400
		JMP synchronize		; find closest jmp-loop approach to x-mask signal

;-----------------------------------------------------------------------------------------

RTCC_align_p0	MOV W,RTCC		;1 (copied here for page 0 calls) 
		AND W,#3		;1 
		JMP PC+W		;3
		NOP			;RTCC = 0
		NOP			;RTCC = 1
		NOP			;RTCC = 2
		NOP			;RTCC = 3	
		RET			;3 

do_padding_p0:	MOV W,sync_padding	;1 cycle
		jmp PC+W		;3 cycles
		nop			;jmp 0 - never executed
		nop			;jmp 1
		nop			;jmp 2
		nop			;jmp 3
		ret			;jmp 4

;-----------------------------------------------------------------------------------------

wait_newframe	SB RA.y_mask		; Ensure we're in Y border area before
		JMP wait_newframe	; waiting for new frame
		NOP
		NOP
		NOP
wait_newframe2	SNB RA.y_mask		; Wait for a new frame window to start
		JMP wait_newframe2	; RA bit to go LOW
		
		MOV W,#$10		; First line number
		MOV LINE_COUNTER,W
		JMP dump_line		; first line is blank - not enough time to generate it

;------------------------------------------------------------------------------------------
; Build the sprite line 
;------------------------------------------------------------------------------------------

build_line	CLR RC			;Reset Ext SRAM address to 0 for sprite X/Y/DEF block
		SETB RA.busy_signal	;SX is accessing sprite SRAM
		CLR SPRITE_NUMBER	;First sprite
		NOP			;Delay

build_loop	LATCH_HI		;Latch value of RC in high address latch
		MOV W,<>SPRITE_NUMBER	;0-7 -> address $00,$10,$20 etc
		MOV RC,W		;set sprite number base address
		SRAM_ACCESS_DELAY	;allow time from address -> valid data  
		MOV W,RB		;Find out if sprite is on this line & what slice
		MOV W,LINE_COUNTER-W	;subtract Y COORDINATE (addr 0) from line number
		SKIPNOBORROW		;
		JMP sprite_end		;sprite is below this line
		MOV Y_SLICE,W		;store slice number
		MOV W,#$f0		
		ADD W,Y_SLICE		;check to see if sprite is above line
		SKIPNOCARRY	
		JMP sprite_end		;skip draw if (sprite_y + $10) is above this line
		INC RC			;move to X-COORDINATE address (addr 1)
		AND W,#$0f
		MOV Y_SLICE,W		;from now on guaranteed to be $00-$0f 
		NOP			;SRAM access delay min of 4 cycles

spr_onthisline	MOV W,#$f0		;find out if sprite is clipped on left
		ADD W,RB		;Subtract 16 from sprite's x coord LSB (addr 1)
		SKIPNOCARRY	
		JMP no_leftclip1	;if no carry, it cant need left clipping
		INC RC			;move to X-COORDINATE MSB location (addr 2)
		SRAM_ACCESS_DELAY	;allow time from address -> valid data  
		SNB RB.0		;$f0 + x_pos is < 0, BUT! MSB may not be zero
		JMP no_leftclip2	;only if it is zero does it needs clipping


left_clip	INC RC			;move to DEFINITION location
		XOR W,#$ff		;make w = pixels missing from left side -1
		MOV CLIP_INDEX,W	
		XOR W,#$0f		;skip if sprite totally left-clipped (pos $000)
		SKIPNOTZERO		;
		JMP sprite_end		;
		MOV W,RB		;Get DEFINITION value from SRAM
		SKIPNOTZERO		;def 0 = sprite disabled
		JMP sprite_end
		MOV RC,W		;put definition on output port C for def latch
		LATCH_HI		;Latch value of RC in high address latch
		MOV W,#$10
		MOV FSR,W		;start drawing sprite at SX SRAM address 0
		INC CLIP_INDEX
		RR CLIP_INDEX
		SKIPNOCARRY
		JMP shifted_clip
unshiftedclip	MOV W,<>Y_SLICE		;present slice to EPROM address lines A4:A7		
		OR W,CLIP_INDEX	
		MOV RC,W		;offset for sprite source address 
		DEC CLIP_INDEX		;jump to position in sprite line draw
		SKIPNOTZERO		;based on clipped width of sprite
		JMP pixels23		;1
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixels45		;2
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixels67		;3
		DEC CLIP_INDEX
		SKIPNOTZERO	
		JMP pixels89		;4
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixelsab		;5
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixelscd		;6
		JMP pixelsef		;7


no_leftclip1	INC RC			;move to X-COORDINATE MSB location (addr 2)
		SRAM_ACCESS_DELAY	;allow time from address -> valid data  
		SNB RB.0		;if X-COORD MSB = 1 skip sprite as x => 110
		JMP sprite_end		;

no_leftclip2	MOV FSR,W		;calc destination FSR value (W = x pos 0 to 255 here)
		AND W,#$e0		;isolate BITS 5:7 of x_pos in W
		MOV TEMPBYTE,W		;stash W for a while
		MOV W,<>SPRITE_NUMBER	;spr base addr
		OR W,#3			;plus 3 = def
		MOV RC,W		;set sprite DEFINITION address
		SRAM_ACCESS_DELAY	;allow time from address -> valid data  
		MOV W,RB		;Get DEFINITION value from SRAM
		SKIPNOTZERO		;if def = 0, sprite is disabled
		JMP sprite_end		
		MOV RC,W		;put definition on output port C for def latch (addr high bits)
		LATCH_HI		;Latch value of RC in high address latch
		MOV W,>>FSR		;get continuous 0 - 127 value
		SKIPNOCARRY		;if LSB was 1, need to used pre-shifted definitions
		JMP shifted_copy	;

		AND W,#$f		;keep only bits 0:3 (register 0-15)
		OR W,TEMPBYTE		;mix in bits 5-7 as the bank select
		MOV FSR,W		;set as FSR for sprite bytes, bit 4 is fixed set later
		MOV W,<>Y_SLICE		;present slice to SRAM address lines A4:A7		
		MOV RC,W		;source low address bits set
		SRAM_ACCESS_DELAY	;allow time from address -> valid data  	


;-------------------------------------------------------------------------------------------
; copy sprite pixels to SX RAM registers using unshifted definitions
;-------------------------------------------------------------------------------------------
		

		SETB FSR.4
		MOV W,RB		;pixels 0 & 1
		AND W,#$0f
		SKIPIFZERO
		JMP branch1a
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP byteduna
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP byteduna
branch1a	MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP branch2a
branch3a	MOV W,RB
		MOV INDF,W
		JMP byteduna
branch2a	MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byteduna	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end	
		SETB FSR.4
		
pixels23	MOV W,RB		;pixels 2 & 3
		AND W,#$0f
		SKIPIFZERO
		JMP branch1b
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP bytedunb
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP bytedunb
branch1b	MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP branch2b
branch3b	MOV W,RB
		MOV INDF,W
		JMP bytedunb
branch2b	MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
bytedunb	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end
		SETB FSR.4	

pixels45	MOV W,RB		;pixels 4 & 5
		AND W,#$0f
		SKIPIFZERO
		JMP branch1c
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP bytedunc
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP bytedunc
branch1c	MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP branch2c
branch3c	MOV W,RB
		MOV INDF,W
		JMP bytedunc
branch2c	MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
bytedunc	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end
		SETB FSR.4

pixels67	MOV W,RB		;pixels 6 & 7
		AND W,#$0f
		SKIPIFZERO
		JMP branch1d
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP bytedund
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP bytedund
branch1d	MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP branch2d
branch3d	MOV W,RB
		MOV INDF,W
		JMP bytedund
branch2d	MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
bytedund	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end
		SETB FSR.4

pixels89	MOV W,RB		;pixels 8 & 9
		AND W,#$0f
		SKIPIFZERO
		JMP branch1e	
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP bytedune
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP bytedune
branch1e	MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP branch2e
branch3e	MOV W,RB
		MOV INDF,W
		JMP bytedune
branch2e	MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
bytedune	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end
		SETB FSR.4

pixelsab	MOV W,RB		;pixels 10 & 11
		AND W,#$0f
		SKIPIFZERO
		JMP branch1f
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP bytedunf
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP bytedunf
branch1f	MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP branch2f
branch3f	MOV W,RB
		MOV INDF,W
		JMP bytedunf
branch2f	MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
bytedunf	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end
		SETB FSR.4

pixelscd	MOV W,RB		;pixels 12 & 13
		AND W,#$0f
		SKIPIFZERO
		JMP branch1g
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP bytedung
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP bytedung
branch1g	MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP branch2g
branch3g	MOV W,RB
		MOV INDF,W
		JMP bytedung
branch2g	MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
bytedung	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end
		SETB FSR.4

pixelsef	MOV W,RB		;pixels 14 & 15
		AND W,#$0f
		SKIPIFZERO
		JMP branch1h
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP sprite_end
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP sprite_end
branch1h	MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP branch2h
branch3h	MOV W,RB
		MOV INDF,W
		JMP sprite_end
branch2h	MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W	

;--------------------------------------------------------------------------------------------

sprite_end	CLR RC			;zero addr for high latch of next pass
		INC SPRITE_NUMBER
		MOV W,SPRITE_NUMBER
		XOR W,#$8
		SKIPIFZERO
		JMP build_loop
	
		CLRB RA.busy_signal	; Allow CPU access sprite to SRAM

;------------------------------------------------------------------------------------------
; Dump line on screen
;------------------------------------------------------------------------------------------

dump_line	call rtcc_align_p0	; following instruction is aligned to RTCC/4 on return

		nop			;1	- added to call of subroutine below for entry alignment	
		call do_padding_p0	;3	
		nop			;1	- added to ret of subroutine above for exit alignment

wait_raster	SB RA.x_mask		;1	    busy wait until video x-mask signal  
		JMP wait_raster		;3         (PORT A bit 2) goes high
		nop			;zzz
		nop			;zzz

;-----------------------------------------------------------------------------------------

		MOV W,#$10		; dump 128 bytes of uController's SRAM onto
		MOV FSR,W		; port C for 256 pixels (4 bits per pixel)

line_dumploop	SETB FSR.4		; 1
		MOV W,<>INDF		; 1
		MOV RC,W		; 1
		NOP			; 1
		NOP			; 1
		NOP			; 1
		NOP			; 1
		NOP			; 1_________ 8 clocks per pixel
		NOP			; 1
		MOV W,INDF		; 1
		MOV RC,W		; 1
		CLR INDF		; 1
		INCSZ FSR		; 1
		JMP line_dumploop	; 3___________ 8 clocks per pixel
		NOP
		NOP
		NOP
		CLR RC			; set output of PORT C at zero (transparent)

;------------------------------------------------------------------------------------------

		INC LINE_COUNTER	; inc line counter
		MOV W,#$30		; is it the last line (ie: line $c0 + $10)
		ADD W,LINE_COUNTER	;	
		SKIPIFZERO		;
		JMP build_line		; create next line 
		JMP wait_newframe	; wait for next frame	

;========================================================================================


shifted_copy	PAGE $200		;Ensure jumps go to $200+
		JMP shifted_copy2

;-----------------------------------------------------------------------------------------


shifted_clip	PAGE $200		;Ensure jumps go to $200+
		JMP shifted_clip2

;----------------------------------------------------------------------------------------
; *** PAGE $200 ***
;----------------------------------------------------------------------------------------

		ORG $200		; code resides on page 1 

;---------------------------------------------------------------------------------------

shifted_copy2	AND W,#$f		;keep only bits 0:3 (register 0-15)
		OR W,TEMPBYTE		;mix in bits 5-7 as the bank select
		MOV FSR,W		;set as FSR for sprite bytes, bit 4 is fixed set later
		MOV W,<>Y_SLICE		;present slice to SRAM address lines A4:A7		
		OR W,#$8		;move to pre-shifted definitions
		MOV RC,W
		SRAM_ACCESS_DELAY	;allow time from address -> valid data  
		
;-------------------------------------------------------------------------------------------
; copy sprite pixels to SX RAM registers using pre-shifted definitions
;-------------------------------------------------------------------------------------------
	
		SETB FSR.4		;ensure accessing SRAM registers $10-$1f 
		TEST RB
		SKIPNOTZERO
		JMP byt_duna
		MOV W,INDF		;pixel 0
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byt_duna	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end2
		SETB FSR.4
		
pixels12	MOV W,RB		;pixels 1 & 2
		AND W,#$0f
		SKIPIFZERO
		JMP brnch1b
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP byt_dunb
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP byt_dunb
brnch1b		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP brnch2b
brnch3b		MOV W,RB
		MOV INDF,W
		JMP byt_dunb
brnch2b		MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byt_dunb	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end2
		SETB FSR.4	
		
pixels34	MOV W,RB		;pixels 3 & 4
		AND W,#$0f
		SKIPIFZERO
		JMP brnch1c
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP byt_dunc
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP byt_dunc
brnch1c		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP brnch2c
brnch3c		MOV W,RB
		MOV INDF,W
		JMP byt_dunc
brnch2c		MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byt_dunc	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end2
		SETB FSR.4
		
pixels56	MOV W,RB		;pixels 5 & 6
		AND W,#$0f
		SKIPIFZERO
		JMP brnch1d
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP byt_dund
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP byt_dund
brnch1d		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP brnch2d
brnch3d		MOV W,RB
		MOV INDF,W
		JMP byt_dund
brnch2d		MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byt_dund	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end2
		SETB FSR.4
		
pixels78	MOV W,RB		;pixels 7 & 8
		AND W,#$0f
		SKIPIFZERO
		JMP brnch1e
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP byt_dune
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP byt_dune
brnch1e		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP brnch2e
brnch3e		MOV W,RB
		MOV INDF,W
		JMP byt_dune
brnch2e		MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byt_dune	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end2
		SETB FSR.4
		
pixels9a	MOV W,RB		;pixels 9 & 10
		AND W,#$0f
		SKIPIFZERO
		JMP brnch1f
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP byt_dunf
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP byt_dunf
brnch1f		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP brnch2f
brnch3f		MOV W,RB
		MOV INDF,W
		JMP byt_dunf
brnch2f		MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byt_dunf	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end2
		SETB FSR.4
		
pixelsbc	MOV W,RB		;pixels 11 & 12
		AND W,#$0f		
		SKIPIFZERO
		JMP brnch1g
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP byt_dung
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP byt_dung
brnch1g		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP brnch2g
brnch3g		MOV W,RB
		MOV INDF,W
		JMP byt_dung
brnch2g		MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byt_dung	INC RC		
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end2
		SETB FSR.4
		
pixelsde	MOV W,RB		;pixels 13 & 14
		AND W,#$0f
		SKIPIFZERO
		JMP brnch1h
		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP byt_dunh
		MOV W,INDF
		AND W,#$0f
		OR W,RB
		MOV INDF,W
		JMP byt_dunh
brnch1h		MOV W,RB
		AND W,#$f0
		SKIPNOTZERO
		JMP brnch2h
brnch3h		MOV W,RB
		MOV INDF,W
		JMP byt_dunh
brnch2h		MOV W,INDF
		AND W,#$f0
		OR W,RB
		MOV INDF,W
byt_dunh	CLRB RC.3		;use byte 7 of non pre-shifted definition
		INC FSR		
		SKIPNOTZERO		
		JMP sprite_end2
		SETB FSR.4
			
pixelf		MOV W,<>RB		;pixel 15
		AND W,#$f0
		SKIPNOTZERO
		JMP sprite_end2
		MOV TEMPBYTE,W
		MOV W,INDF		
		AND W,#$0f
		OR W,TEMPBYTE
		MOV INDF,W

sprite_end2	PAGE 0			;jump will go back to page 0 ($000-$1ff)
		JMP sprite_end

;-----------------------------------------------------------------------------------------

shifted_clip2	INC CLIP_INDEX		; adjust for correct offset
		MOV W,<>Y_SLICE		; present slice to SRAM address lines A4:A7		
		OR W,CLIP_INDEX	
		OR W,#$8		; offset for preshifted defs
		MOV RC,W		; modified source index low addr bits for SRAM
		DEC CLIP_INDEX		; jump to position in sprite line draw
		SKIPNOTZERO		; based on clipped width of sprite
		JMP pixels12		; 1
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixels34		; 2
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixels56		; 3
		DEC CLIP_INDEX
		SKIPNOTZERO	
		JMP pixels78		; 4
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixels9a		; 5
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixelsbc		; 6
		DEC CLIP_INDEX
		SKIPNOTZERO
		JMP pixelsde		; 7
		MOV W,<>Y_SLICE		; use non pre-shifted for last pixel 		
		OR W,#$7		
		MOV RC,W		
		NOP			
		JMP pixelf		; 8


;==========================================================================================

		org $400		; code is on page 2

;------------------------------------------------------------------------------------------

wait_y_mask	SB RA.y_mask		;1 (2)
		JMP wait_y_mask		;3 (0)
		nop			;1
		nop			;1
wait_y_mask2	SNB RA.y_mask		;1 (2)
		JMP wait_y_mask2	;3 (0)
		ret			;3 - always a multiple of 4 instructions incl. call and ret
		
;------------------------------------------------------------------------------------------

align_to_RTCC	MOV W,RTCC		;1 align following test+jmp to rtcc0:1=00	
		AND W,#3		;1 
		JMP PC+W		;3
		NOP			;RTCC = 0
		NOP			;RTCC = 1
		NOP			;RTCC = 2
		NOP			;RTCC = 3	
		RET			;3

;------------------------------------------------------------------------------------
; Find best sync to video controller SX x-mask signal
;------------------------------------------------------------------------------------

synchronize	mov w,#255-50		;delay startup by 50 frames to ensure 
		mov temp,w		;everything is settled
delaystart	call wait_y_mask
		incsz temp
		jmp delaystart
		
synctest0	call align_to_rtcc	;Standard to each test
		call wait_y_mask	;Standard to each test
		call align_to_rtcc	;Standard to each test
		MOV W,RTCC		;
		NOP			;
		NOP			;
		NOP			;4 -------- Padding = 0
wait_xmask0	SB RA.x_mask		;1
		JMP wait_xmask0		;3		
		NOP			;1
		NOP			;1
		MOV W,RTCC-W		;1
		MOV sync0,W		;1

synctest1	call align_to_rtcc	;Standard to each test
		call wait_y_mask	;Standard to each test
		call align_to_rtcc	;Standard to each test
		MOV W,RTCC		;
		NOP			;
		NOP			;
		NOP			;4
		NOP			;------ Padding = 1
wait_xmask1	SB RA.x_mask		;1
		JMP wait_xmask1		;3		
		NOP			;1
		NOP			;1
		MOV W,RTCC-W		;1
		MOV sync1,W		;1

synctest2	call align_to_rtcc	;Standard to each test
		call wait_y_mask	;Standard to each test
		call align_to_rtcc	;Standard to each test
		MOV W,RTCC		;
		NOP			;
		NOP			;
		NOP			;4
		NOP			;-------- Padding = 2
		NOP 			;--------------------
wait_xmask2	SB RA.x_mask		;1
		JMP wait_xmask2		;3		
		NOP			;1
		NOP			;1
		MOV W,RTCC-W		;1
		MOV sync2,W		;1

synctest3	call align_to_rtcc	;Standard to each test
		call wait_y_mask	;Standard to each test
		call align_to_rtcc	;Standard to each test
		MOV W,RTCC		;
		NOP			;
		NOP			;
		NOP			;4
		NOP			;-----------------------
		NOP			;---------- Padding = 3
		NOP 			;-----------------------
wait_xmask3	SB RA.x_mask		;1
		JMP wait_xmask3		;3		
		NOP			;1
		NOP			;1
		MOV W,RTCC-W		;1
		MOV sync3,W		;1


		CLR count		;find fastest offset
find_fastest	MOV W,count
		XOR W,sync0
		skipnotzero
		JMP usesync0
		MOV W,count
		XOR W,sync1
		skipnotzero
		JMP usesync1
		MOV W,count
		XOR W,sync2
		skipnotzero
		JMP usesync2
		MOV W,count
		XOR W,sync3
		skipnotzero
		JMP usesync3
		INCSZ count
		JMP find_fastest

usesync0	MOV W,#4
		JMP gotsync
usesync1	MOV W,#3
		JMP gotsync
usesync2	MOV W,#2
		JMP gotsync
usesync3	MOV W,#1
gotsync		MOV sync_padding,W
		
		page $0
		jmp wait_newframe

;=============================================================================================================

		END
