utils.asm
dschmenk_LightCycles/utils.asm
;*
;* Read both game controllers in parallel
;* 
GCREAD	BIT	GCSTROBE
	LDY	#$00
	LDX	#$00
	LDA	#GCMAX
GCLOOP	BIT	GC0
	BPL	+
	INY
	BNE	++	; Timing
+	NOP
	NOP
++	BIT	GC1
	BPL	+
	INX
	BNE	++	; Timing
+	NOP
	NOP
++	SEC
	SBC	#$01
	BNE	GCLOOP
	LDA	GCPB1	; Read GC buttons
	ASL
	LDA	GCPB2
	ROR
	AND	#$C0
	RTS
;*
;* Text routines
;*
GOTOXY	STX	CH
	STY	CV
	LDA	TXT_TBLL,Y
	STA	TBAS1L
	STA	TBAS2L
	LDA	TXT_TBLH,Y
	ORA	#$04
	STA	TBAS1H
	EOR	#$0C
	STA	TBAS2H
	RTS
NORMAL	LDA	#$FF
	STA	INVFLAG
	RTS
INVERSE	LDA	#$3F
	STA	INVFLAG
	RTS
FLASH	LDA	#$7F
	STA	INVFLAG
	RTS
PUTXA	PHA
	TXA
	JSR	PUTA
	PLA
PUTA	PHA
	LSR
	LSR
	LSR
	LSR
	TAX
	LDA	HEXCHR,X
	JSR	PUTC
	PLA
	AND	#$0F
	TAX
	LDA	HEXCHR,X
PUTC	ORA	#$80
	AND	INVFLAG
	LDY	CH
	STA	(TBAS1),Y
	STA	(TBAS2),Y
	INC	CH
	RTS
PUTSXY	JSR	GOTOXY
PUTS	TSX
	LDA	$101,X
	STA	LDCHR+1
	LDA	$102,X
	STA	LDCHR+2
	LDX	#$01
LDCHR	LDA	$1000,X
	BEQ	+
	JSR	PUTC
	INX
	BNE	LDCHR
+	TXA
	TSX
	CLC
	ADC	$101,X
	STA	$101,X
	BCC	+
	INC	$102,X
+	RTS
HEXCHR	!TEXT	"0123456789ABCDEF"
;*
;* Fill screen with color
;*
GFILL	LDX	#$23
--	PHA
	LDA	TXT_TBLL,X
	STA	GBASL
	LDA	TXT_TBLH,X
	ORA	GPAGE
	STA	GBASH
	PLA
	LDY	#39
-	STA	(GBASE),Y
	DEY
	BPL	-
	DEX
	BPL	--
	RTS
;*
;* Plot X,Y with GCLR
;*
GPLOT	TYA
	PHA
	LSR
	TAY
	LDA	TXT_TBLL,Y
	STA	GPLOTA+1
	STA	GPLOTB+1
	LDA	TXT_TBLH,Y
	ORA	GPAGE
	STA	GPLOTA+2
	STA	GPLOTB+2
GPLOTA	LDA	$FFFF,X
	BCC	+
	AND	#$0F
	STA	TMP
	LDA	GCLR
	AND	#$F0
	BCS	++
+	AND	#$F0
	STA	TMP
	LDA	GCLR
	AND	#$0F
++	ORA	TMP
GPLOTB	STA	$FFFF,X
--	PLA
	TAY
	RTS
;*
;* Plot horizontal line from X,Y to A,Y with GCLR
;*
GHLIN	STA	GHLRHT
	TYA
	PHA
	LSR
	TAY
	LDA	#$F0
	BCC	+
	LDA	#$0F
+	STA	DSTMASK
	EOR	#$FF
	STA	SRCMASK
	LDA	TXT_TBLL,Y
	STA	GHLINA+1
	STA	GHLINB+1
	LDA	TXT_TBLH,Y
	ORA	GPAGE
	STA	GHLINA+2
	STA	GHLINB+2
GHLINA	LDA	$FFFF,X
	AND	DSTMASK
	STA	TMP
	LDA	GCLR
	AND	SRCMASK
	ORA	TMP
GHLINB	STA	$FFFF,X
	CPX	GHLRHT
	BEQ	--
	INX
	BNE	GHLINA
GHLRHT	!BYTE	$00
;*
;* Fill rectangle fro X,Y to A,SCANLN with GCLR
;*
GRECT	STX	GRCTLFT
-	PHA
	JSR	GHLIN
	PLA
	CPY	SCANLN
	BEQ	+
	LDX	GRCTLFT
	INY
	BNE	-
+	RTS
GRCTLFT	!BYTE	$00
;*
;* Swap rendered and displayed GR pages
;*
GSWAP	LDA	#$01
	EOR	CURPAGE
	STA	CURPAGE
	TAX
	LDA	$C054,X
	LDA	PGBASE,X
	STA	GPAGE
	RTS
;*
;* Multiply X by A, return X:A
;*
MUL8X8	LSR
	STA	TMP
	LDA	#$00
	BCC	+	; BIT 0
	TXA
+	DEX		; Because carry will be set for ADC
	STX	TMP+1
	LSR
	ROR	TMP
	BCC	+	; BIT 1
	ADC	TMP+1
+	LSR
	ROR	TMP
	BCC	+	; BIT 2
	ADC	TMP+1
+	LSR
	ROR	TMP
	BCC	+	; BIT 3
	ADC	TMP+1
+	LSR
	ROR	TMP
	BCC	+	; BIT 4
	ADC	TMP+1
+	LSR
	ROR	TMP
	BCC	+	; BIT 5
	ADC	TMP+1
+	LSR
	ROR	TMP
	BCC	+	; BIT 6
	ADC	TMP+1
+	LSR
	ROR	TMP
	BCC	+	; BIT 7
	ADC	TMP+1
+	LSR
	TAX
	LDA	TMP
	ROR
	RTS
;*
;* Signed multiply 8x8
;*
SMUL8X8	STX	SIGN
	PHA
	EOR	SIGN
	STA	SIGN
	CPX	#$80
	BCC	+
	TXA
	EOR	#$FF
	TAX
	INX
+	PLA
	CMP	#$80
	BCC	+
	EOR	#$FF
	ADC	#$00
+	JSR	MUL8X8
	ASL	SIGN	; SIGN(RESULT) = SIGN(MULTIPLCAND) ^ SIGN(MULTIPLIER)
	BCC	+
	EOR	#$FF
	ADC	#$00
	PHA
	TXA
	EOR	#$FF
	ADC	#$00
	TAX
	PLA
+	RTS
;*
;* Unsigned divide, return X:A
;*
DIV 	LDX	#$00
	STX	TMP	; REMNDRL
	STX	TMP+1	; REMNDRH
;	LDA	DVSR+1	; Check for divide by zero
; 	ORA	DVSR
	LDA	DVDND+1	; Check for zero divide
 	ORA	DVDND
	BEQ	++
 	LDY	#$11	; #BITS+1
-	ASL	DVDND
	ROL	DVDND+1
	DEY
	BCC	-
- 	ROL	TMP	; REMNDRL
	ROL	TMP+1	; REMNDRH
	LDA	TMP	; REMNDRL
	CMP	DVSR
	LDA	TMP+1	; REMNDRH
	SBC	DVSR+1
	BCC	+
	STA	TMP+1	; REMNDRH
	LDA	TMP	; REMNDRL
	SBC	DVSR
	STA	TMP	; REMNDRL
	SEC
+	ROL	DVDND
	ROL	DVDND+1
	DEY
	BNE	-
	LDA	DVDND
	LDX	DVDND+1
++	RTS
;*
;* Signed divide: return X:A
;*
SDIV 	LDX	DVSR+1
	STX	SIGN
	BPL	+
	LDA	DVSR
	JSR	NEG
	STX	DVSR+1
	STA	DVSR
+ 	LDX	DVDND+1
	BPL	+
	TXA
	EOR	SIGN
	STA	SIGN
	LDA	DVDND
	JSR	NEG
	STX	DVDND+1
	STA	DVDND
+ 	JSR	DIV
	ASL	SIGN	; SIGN(RESULT) = SIGN(DIVIDEND) ^ SIGN(DIVISOR)
	BCC	+
NEG 	STA	TMP
	STX	TMP+1
	LDA	#$00
	SEC
	SBC	TMP
	STA	TMP
	LDA	#$00
	SBC	TMP+1
	TAX
	LDA	TMP
+	RTS
