; 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