; MenuBoxUtils.asm -- a collection of assembly code display procedures


; write -- procedure to write on the display

	.BEXT		write

	.SREL
write:	WRITE

; write(StringPointer,nwrds,dba,wad,bitlimit,FontPointer)
; use GetFont(dsp) for system font
; returns the width of the string ( in bits )
; wad=word address of scanline
; dba=bit address in scanline, varies from 1 to whatever
; nwrds=width (in words) of scanline
; bitlimit=maximum number of bits to be written per string
;
; wad and dba use different conventions from wr.asm
;
;	In wr():
;		wad is the starting word in which the string will be written
;		dba is the starting bit position: leftmost bit=15, rightmost bit=0
;
;	In write():
;		wad is the address of any word before the one in which the
;			string will be written
;		dba is the number of bits from wad to the starting bit position
;			dba starts at unity and can be any positive number.
;		example: write(string,38,150,array+nlines*38,200,GetFont(dsp))
;			this writes the string nlines down from the beginning
;			of "array" and 150 bits from the beginning of this line
;			anything over 200 bits from the beginning of the string
;			will not be printed.





StringPointer=4
nwrds=5
dba=6
wad=7
bitlimit=8.
FontPointer=9.
bsofar=10.
charsdone=11.
ret=12.

	.NREL

WRITE:	STA 3 1 2
	JSR@ 370
	20
	JSR@ 367

	LDA 3 wad,2
	LDA 0 nwrds,2
	SUB 0 3
	STA 3 wad,2
	LDA 1 dba,2
	ADC 0 0
	ADD 1 0				; .ac0=dba-1
	LDA 1 c20			; .ac1=divisor
	JSR @344
	LDA 3 wad,2
	ADD 3 1
	STA 1 wad,2		; wad=wad+(dba-1)/16
	LDA 1 c17
	SUB 0 1
	STA 1 dba,2		; dba=15-((dba-1) rem 16

	SUB 0 0
	STA 0 bsofar,2
	LDA 0 @StringPointer,2
	MOVS 0 0
	LDA 1 c377
	AND 1 0
	STA 0 charsdone,2
doright:	LDA 0 @StringPointer,2
	JSR docnv
	ISZ StringPointer,2
	DSZ charsdone,2
	JMP doleft
	JMP retx
doleft:	LDA 0 @StringPointer,2
	MOVS 0 0
	JSR docnv
	DSZ charsdone,2
	JMP doright
retx:	LDA 0 bsofar,2
	JMP@ 366

temp: 0
c377:	377
c17:	17
c20:	20

docnv:	STA 3 ret,2
	LDA 1 c377
	AND 1 0
put1:	LDA 3 FontPointer,2
	ADD 0 3

	LDA 0 0 3			; get self relative pointer
	ADD 3 0			; add to get loc of xh
	STA 0 temp
	LDA 0 @temp		; width or pseudo-code
	MOVZR 0 0 snc		; skip if no extension
	LDA 0 c20			; there is an extension
	LDA 1 bitlimit,2
	SUBZ 0 1 snc		; skips if difference is positive
	JMP retx			; difference is neg - will overrun - go home
	STA 1 bitlimit,2		; bitlimit still positive - look at it again later

	LDA 0 wad,2
	CONVERT nwrds
	JMP put2			;character has an extension
	LDA 0 bsofar,2		;no extension--ac3=width,ac1=dba and 17b
	ADD 3 0
	STA 0 bsofar,2
	SUBZ 3 1 szc
	JMP put3			;didn't overflow a word boundary
	ISZ wad,2
	LDA 3 c20
	ADD 3 1
put3:	STA 1 dba,2
	JMP@ ret,2

put2:	ISZ wad,2
	LDA 0 bsofar,2
	LDA 1 c20
	ADD 1 0
	STA 0 bsofar,2
	MOV 3 0
	JMP put1



; puts -- procedure to put a character on the display

	.BEXT		puts

	.SREL
puts:	PUTS

; puts(char,nwrds,bitpos,wordpos,font)
; char=ASCII character
; wordstart=word address of scanline
; nwords=width (in words) of scanline
; bitstart=bit address in scanline, varies from 0 to whatever
; font=font pointer, use GetFont(dsp) for system font


char=4
bitpos=6
wordpos=7
font=8.

	.NREL



PUTS:	STA 3 1 2
	JSR@ 370
	20
	JSR@ 367

	LDA 0 bitpos,2			; .ac0=bitpos
	LDA 1 c20					; .ac1=divisor
	JSR @344
	LDA 3 wordpos,2
	ADD 3 1
	LDA 3 nwrds,2
	SUB 3 1
	STA 1 wordpos,2		; wordpos=wordpos+bitpos/16-nwrds
	LDA 1 c17
	SUB 0 1
	STA 1 bitpos,2		; bitpos=15-(bitpos rem 16)

	LDA 0 char,2		; get char & #377
	LDA 1 c377
	AND 1 0

put:	LDA 3 font,2
	ADD 0 3
	LDA 0 wordpos,2
	CONVERT nwrds
	JMP .+2			;character has an extension
	JMP@ 366		; return
	ISZ wordpos,2
	MOV 3 0
	JMP put



; erase -- procedure to erase bits on the display
;   using BITBLT

	.BEXT		erase

	.SREL

erase:		ERASE

; erase(nbits,wordstart,bitstart,nwords,nlines,flag [0])
; nbits=number of bits to be changed
; wordstart=starting word position of first line
; bitstart=starting bit position within the line (0 ge bitstart ge nwords*16-1)
; nwords=number of words per scan line
; nlines=number of scan lines to be changed
; flag=0 or omitted means set bits to 0
; flag=1 means set bits to 1
; flag=-1 means invert bits from their present state

nbits=4
wordstart=5
bitstart=6
nwords=7
nlines=8.
flag=9.


	.NREL


c2:	2
c6:	6
c14:	14
c16:	16
c46:	46
SaveAC2:	0
AddrBBTable: 0




ERASE:STA 3 1 2
	JSR @370
	30
	JSR @367
	SUB 3 3				; number arguments is stored in register 0
	LDA 1 c6
	SGE 0 1
	STA 3 flag,2			; default case - flag=0

	LDA 0 nbits,2
	SNZ 0 0				; check if nbits=0
	JMP @366			; return if nbits=0

	LDA 1 bitstart,2
	SN 0 0				; check sign of nbits
	JMP nbitsgr0			; nbits > 0 
	ADD 0 1
	INC 1 1				; .ac1=bitstart+nbits+1 (new bitstart)
	NEG 0 0		; .ac0=-nbits

nbitsgr0: JSR .+22
	0
	0
	0
	0
	0
	0
	0
	0
	0
	0
	0
	0
	0
	0
	0
	0
	0
	STA 3 AddrBBTable
	MOV 2 3		; set up BBTable
	LDA 2 AddrBBTable
	SKEVEN 2 2		; test if AddrBBTable is even
	INC 2 2				; odd so add one
	STA 0 6,2			; store dest W
	STA 1 4,2			; store dest LX
	LDA 0 wordstart,3
	STA 0 2,2			; store dest BCA
	LDA 0 nwords,3
	STA 0 3,2		; store dest BMR
	LDA 0 nlines,3
	SP 0 0			; check that nlines > 0
	JMP return
	STA 0 7,2		; store dest H
	LDA 0 c46
	STA 0 11,2	; store source BMR

	LDA 0 flag,3		; now determine how store
	SUB 1 1				; grey block is white
	SZ 0 0
	ADC 1 1			; grey block is black
	STA 1 14,2		; store word0 of grey block
	STA 1 15,2		; store word1 of grey block
	STA 1 16,2		; store word2 of grey block
	STA 1 17,2		; store word3 of grey block
	LDA 1 c16			; function=14 if flag < 0
	SN 0 0
	LDA 1 c14			; function=12 if flag gr 0
	STA 1 0,2
	SUB 1 1			; zero dest TY
	STA 1 5,2		; BBTable now complete
	STA 3 SaveAC2	; .ac3 really has .ac2's previous contents


	61024				; BITBLT


return:LDA 2 SaveAC2		; restore .ac2
	JMP @366









; select -- procedure to select positions on the display

	.BEXT		select

	.SREL
select:	SELECT

; select(mxl,mxr,myt,myb,key)
; returns true if key is released, false if region is exceeded prior
; mxl=left x boundary
; mxr=right x boundary
; myt=top y boundary
; myb=bottom y boundary
; key=key selected, RED=4, YELLOW=1, GREEN=2

mxl=4
mxr=5
myt=6
myb=7
key=8.


	.NREL

C377:	377
mkey:177030
mx:	424
my:	425


SELECT:STA 3 1 2
	JSR@ 370
	20
	JSR@ 367

start:LDA 3 C377			; top of loop
	LDA 1 @mkey		; get mouse key
	COM 1 1
	AND 3 1
	LDA 0 key,2		; get selected key
	AND 0 1
	SNZ 1 1			; compare the two
	JMP true			; key was released

	LDA 0 @mx			; get mouse x coordinate
	SP 0 0			;   check if mx < 0
	SUB 0 0			;   if mx < 0 set it to 0
	LDA 1 @my			; get mouse y coordinate
	LDA 3 mxl,2
	SGE 0 3			; compare to left boundary
	JMP false			; outside region
	LDA 3 mxr,2
	SLE 0 3			; compare to right boundary
	JMP false			; outside region
	LDA 3 myt,2
	SGE 1 3			; compare to upper boundary
	JMP false			; outside region
	LDA 3 myb,2
	SLE 1 3			; compare to lower boundary
	JMP false			; outside region
	JMP start			; still inside region go to beginning

true:	ADC 0 0			; key released, return true
	JMP @366

false:SUB 0 0			; outside region, return false
	JMP @366


	.END