P*------------------------------- * * SPED * * My Special Editor, for use in writing macros for * the music composition program. * * SLJ 9/7/96 * Completed: 12/9/96 sort-of :) * * This is a fairly poor design -- I was still in * "demo mode", e.g. zero page for everything, don't waste * cycles, etc., when I wrote it. But it works! * * ORG $0801 ;Basic REL DSK 'sped' FIELDP = $0FE0 ;Set in playvars * * External variables * ERROR EXT CODETEXT = $61 CODEP = $63 CURLINE EXT COMPILER EXT LOADID EXT LOADADDR EXT SAVESTRT EXT SAVEEND EXT NEWDATA EXT DISKIO EXT * * Variables * DO 0 ;Don't assemble BLNON EQU $0A26 ;$CF on 64 BLNSW EQU $0A27 ;$CC on C64 side BLNCT EQU $0A28 ;$CD on 64 GDBLN EQU $0A29 ;$CE on 64 PNT EQU $E0 ;$D1 for 64 ;Maybe easier to use than SCREENP FIN BLNON EQU $CF ;Use the 64 variables instead BLNSW EQU $CC BLNCT EQU $CD GDBLN EQU $CE SA EQU $B9 ;Seconday address FA EQU $BA ;Current device number EAL EQU $AE ;Load end address FAQ2 EQU $6A ;Used as a temporary location ;(all 5 bytes) TEXTP EQU $FB ;Pointer to current text line EOF EQU $FD ;Pointer to end of file SCREENP EQU $F9 ;Pointer to current screen line TEMP EQU $FF MODFLAG EQU $B4 ;Flag: has text been modified POINT1 EQU $B4 ;Used as a spare pointer as well POINT2 EQU $B0 COUNT EQU $B2 ;Temporary counter/pointer (2-byte) * * Kernal routines * CHROUT = $FFD2 GETIN = $FFE4 PLOT = $FFF0 ACPTR = $FFA5 CHKIN = $FFC6 CHKOUT = $FFC9 CLRCHN EQU $FFCC CHRIN EQU $FFCF CLALL EQU $FFE7 LOAD EQU $FFD5 SAVE EQU $FFD8 OPEN = $FFC0 CLOSE = $FFC3 READST = $FFB7 SETLFS = $FFBA SETNAM = $FFBD STOP = $FFE1 TALK EQU $FFB4 TKSA EQU $FF96 UNTLK EQU $FFAB *------------------------------- DO 0 DA $0800 ;Next link DA 1996 ;Line number DFB $9E ;SYS TXT '2065 slj' DFB 00 ;end of line DA 00 * ERR *-2065 ;Error if we're not at 2065! FIN *------------------------------- SPEDEOF ENT DA $2100 SPEDBUFF ENT ;Text buffer BUFFER DA $2000 SPED ENT ;Where to enter SPED from JSR CLRSCR LDA $0286 STA $0287 LDA #00 STA MODFLAG STA TEMPX STA TEMPY LDA #<1024 STA SCREENP LDA #>1024 STA SCREENP+1 LDA BUFFER STA TEXTP LDA BUFFER+1 STA TEXTP+1 LDA SPEDEOF STA EOF LDA SPEDEOF+1 STA EOF+1 JSR RESTORE JMP MAIN CLEAR ;Clears the buffer of all text JSR CLRSCR JSR INIT LDA #13 LDY #00 STA (TEXTP),Y ;First char needs to be a chr$(13) MAIN JSR GETKEY PHA SEC JSR PLOT JSR CRSRFIX PLA BPL :C2 :C1 CMP #192 BCC :OTHER ;Shifted chars :C2 CMP #32 BCC :OTHER :CONT STA MODFLAG CPY #39 ;Handle last column special BNE :NORMAL EOR #$E0 ;Convert to screen char CLC ADC #32 BPL :CONT2 EOR #$C0 CMP #64 BCC :CONT2 EOR #32 :CONT2 STA (SCREENP),Y JMP ALLDONE :NORMAL JSR CHROUT JMP ALLDONE :OTHER INS CMP #148 ;Insert BNE DEL STA MODFLAG STY TEMP LDY #38 :LOOP CPY TEMP BCC :DONE LDA (SCREENP),Y INY STA (SCREENP),Y DEY DEY BPL :LOOP :DONE LDY TEMP LDA #32 ;Stick a space in there STA (SCREENP),Y JMP ALLDONE DEL CMP #20 BNE LEFT CPY #00 BEQ :DONE STA MODFLAG JSR CHROUT ;That ought to work :DONE JMP ALLDONE LEFT CMP #157 BNE RIGHT CPY #0 BEQ :DONE JSR CRSRFIX JSR CHROUT :DONE JMP ALLDONE RIGHT CMP #29 BNE UP CPY #39 BEQ :DONE JSR CRSRFIX JSR CHROUT :DONE JMP ALLDONE * UP: * - parse the line if necessary * - move the text and screen pointer to the previous line * - move the screen down if at the top * * TEXTP points to current line - 1 ? * Nah, let TEXTP point to the beginning of the current line. * Let EOF point to the end of the text+1 * UP CMP #145 BNE DOWN STX TEMPX STY TEMPY JSR CRSRFIX LDA MODFLAG BEQ :NOMOD JSR PARSE ;Parse the line into the buffer :NOMOD DO 0 LDA TEXTP+1 ;Check if we are at beginning CMP BUFFER+1 ;and skip if we are. BNE :CONT LDA TEXTP CMP BUFFER BEQ :DONE :CONT FIN JSR ATBEGIN BEQ :DONE JSR BACKP ;Point to previous line ;Next, update the screen :BAIL LDX TEMPX ;Check to see if at beginning BNE :DONE ;Otherwise, move screen down JSR MOVDOWN ;starting at line 0! JSR PRLINE ;Print out the line LDY TEMPY CLC JSR PLOT ;Restore old column :DONE LDA #145 ;Move the cursor up! JSR CHROUT LDA #00 STA MODFLAG JMP ALLDONE * * DOWN -- Mighty similar to UP * DOWN CMP #17 BNE RETURN STY TEMPY JSR CRSRFIX LDA MODFLAG BEQ :NOMOD JSR PARSE :NOMOD JSR NEXTP ;Point to next line BCC :CONT ;Check if we are on last line CPX #24 ;If we are on last line, then SCREENP BNE :NODATE ;has not been updated LDX #$FF :NODATE INX ;Just in case on line 0 JSR BACKP ;Put the pointer back JMP :DONE :CONT LDA #17 ;Move the cursor down JSR CHROUT CPX #24 ;Check to see if at bottom BNE :DONE JSR PRLINE ;Print out the line LDY TEMPY CLC JSR PLOT :DONE LDA #00 STA MODFLAG JMP ALLDONE * * RETURN * RETURN CMP #13 BNE DLINE * JSR CRSRFIX JSR PARSE JSR NEXTP ;Move the text pointer to the next line JSR BUMP ;Add in a CHR$(13) LDA #13 ;Return JSR CHROUT CPX #24 BEQ :SKIP INX ;Move all lower lines down JSR MOVDOWN ;on the screen. :SKIP LDA #00 STA MODFLAG :DONE JMP ALLDONE * * Delete line * DLINE CMP #172 ;Delete line, Com-D BNE TDISK * JSR CRSRFIX LDY #39 LDA #32 ;Clear the line :L1 STA (SCREENP),Y DEY BPL :L1 JSR PARSE ;Zap all the chars in the text JSR BUMPBACK ;Delete the chr$(13), unless at beginning LDY #00 JSR PRTEXT ;Print out the rest of the file. JMP ALLDONE * * Disk commands. All disk commands now use the * common disk routine. * TDISK CMP #136 ;F7 BNE CLR JSR WAITFIX JSR CRSRFIX STX TEMPX STY TEMPY JSR PARSE LDA #$FF ;No ID check STA LOADID STA LOADID+1 LDA BUFFER STA LOADADDR STA SAVESTRT LDA BUFFER+1 STA LOADADDR+1 STA SAVESTRT+1 LDA EOF STA SAVEEND LDA EOF+1 STA SAVEEND+1 LDX #<:DSTRING LDA #>:DSTRING JSR DISKIO LDA NEWDATA BEQ :CONT JSR INIT LDA EAL ;End of load STA EOF LDA EAL+1 STA EOF+1 :CONT LDA #155 ;Back to gray 3 JSR CHROUT LDA #15 ;Hammer to fit, paint to match... STA $0287 JSR CLRSCR JSR RESTORE JMP ALLDONE :DSTRING DFB 147,5 TXT 'load/save text file' DFB 13,13,0 CLR CMP #147 ;Shift-clear BNE :DONE STX TEMPX STY TEMPY JSR PARSE LDY #00 :LOOP LDA :TEXT,Y BEQ :CONT JSR CHROUT INY BNE :LOOP :CONT JSR GETKEY CMP #'y' BNE :SKIP JMP CLEAR ;OK by me! :SKIP JSR RESTORE JMP ALLDONE :TEXT DFB 147,13 TXT 'clear all text: are you sure? (y/n)' DFB 00 :DONE COMP CMP #188 ;C=-C ompile BNE :DONE JSR WAITFIX JSR CRSRFIX STX TEMPX STY TEMPY JSR PARSE LDY #00 TYA STA (EOF),Y ;Needs to end in a 00 JSR FREEZEP JSR CLRSCR LDA BUFFER ;Tell compiler where text STA CODETEXT ;starts. LDA BUFFER+1 STA CODETEXT+1 LDA #00 STA CODEP LDA #$E0 ;Compile to $E000 STA CODEP+1 JSR COMPILER JSR PRESSKEY JSR WAITFIX JSR CLRSCR JSR THAWP ;Restore pointers JSR RESTORE JMP ALLDONE :DONE QUIT CMP #189 ;C=-x BEQ :EXIT JSR STOP BNE ALLDONE :EXIT JSR PARSE LDA EOF STA SPEDEOF LDA EOF+1 STA SPEDEOF+1 RTS ALLDONE JMP MAIN TEMPX DFB 00 ;Temporary storage TEMPY DFB 00 * * FREEZEP preserves the contents of the major variables * i.e. SCREENP etc. Use THAWP to get them back! * TEMPTEXT DA 0 TEMPEOF DA 0 TEMPSCR DA 0 FREEZEP LDA SCREENP STA TEMPSCR LDA SCREENP+1 STA TEMPSCR+1 LDA TEXTP STA TEMPTEXT LDA TEXTP+1 STA TEMPTEXT+1 LDA EOF STA TEMPEOF LDA EOF+1 STA TEMPEOF+1 RTS THAWP LDA TEMPSCR STA SCREENP LDA TEMPSCR+1 STA SCREENP+1 LDA TEMPTEXT STA TEXTP LDA TEMPTEXT+1 STA TEXTP+1 LDA TEMPEOF STA EOF LDA TEMPEOF+1 STA EOF+1 RTS * * Initialize pointers and such * INIT LDA BUFFER STA TEXTP CLC ADC #01 STA EOF ;End+1 LDA BUFFER+1 STA TEXTP+1 ADC #00 STA EOF+1 LDA #>1024 STA SCREENP+1 LDA #<1024 STA SCREENP LDA #00 STA MODFLAG RTS * * This procedure parses a new line into the file. It first * figures out how much text needs to be put in, by starting * at column 39 and working backwards until either a non-space * or column 0 is reached. It then compares this with the * amount of text that is currently present in this line in * the file, and adjusts the text accordingly, either * forwards or backwards. Then it inserts the text along with * a CHR$(13). * * Thus, it replaces the current line in the text with the * current line on the screen. * * On exit, TEMP contains the number of characters inserted * or deleted from the text. * PARSE LDY #39 :LOOP1 LDA (SCREENP),Y CMP #32 BNE :DONE1 DEY BPL :LOOP1 :DONE1 INY ;This is for the chr$(13) STY TEMP ;This is how many chars to be added LDY #00 ;Now find the next spot in the text :LOOP2 LDA (TEXTP),Y CMP #13 BEQ :DONE2 INY BPL :LOOP2 :DONE2 TYA SEC SBC TEMP ;differential PHA ;Need the differential to update ;the pointers with! BCC FORWARD ;C=0 means #screen > #text CLC ADC TEXTP ;Copy from point2->point1 STA POINT2 LDA TEXTP+1 ADC #00 STA POINT2+1 LDA TEXTP STA POINT1 ;Point1 points to current line LDA TEXTP+1 STA POINT1+1 LDA EOF SEC SBC POINT2 STA COUNT ;This is how many chars to copy LDA EOF+1 SBC POINT2+1 STA COUNT+1 INC COUNT ;Because of the way the counting BNE :CONT1 ;is checked INC COUNT+1 :CONT1 LDY #00 ;Now copy the text :BLOOP LDA (POINT2),Y STA (POINT1),Y DEC COUNT BNE :BCONT DEC COUNT+1 BMI CPYSCRN :BCONT INY BNE :BLOOP INC POINT2+1 INC POINT1+1 BNE :BLOOP FORWARD ;Same thing, but bump text forwards EOR #$FF ;Make it positive ADC #01 STA POINT1 LDA #00 ;Y will offset STA POINT2 LDA EOF+1 STA POINT1+1 STA POINT2+1 LDA EOF SEC SBC TEXTP STA COUNT ;This is how many chars to copy LDA EOF+1 SBC TEXTP+1 STA COUNT+1 INC COUNT ;Because of the way the counting BNE :CONT1 ;is checked INC COUNT+1 :CONT1 LDY EOF ;Y is offset :BLOOP LDA (POINT2),Y STA (POINT1),Y DEC COUNT BNE :BCONT DEC COUNT+1 BMI :BDONE :BCONT DEY CPY #$FF BNE :BLOOP DEC POINT2+1 DEC POINT1+1 BNE :BLOOP :BDONE CPYSCRN ;Finally, copy from screen to text LDY TEMP ;TEMP contains screen pos LDA #13 ;Insert a CR STA (TEXTP),Y DEY BMI :ACK :LOOP2 LDA (SCREENP),Y AND #$7F CMP #96 ;Convert from screen to petscii BCC :C1 ADC #63 BNE :OK :C1 CMP #64 BCC :C2 ADC #31 :C2 CMP #32 BCS :OK ORA #64 :OK STA (TEXTP),Y DEY BPL :LOOP2 :ACK PLA STA TEMP ;And update the pointers BMI :ADD LDA EOF ;A>0 means text was deleted SEC ;so back up the pointer SBC TEMP STA EOF LDA EOF+1 SBC #00 STA EOF+1 RTS :ADD EOR #$FF ;Otherwise, move pointer forwards! SEC ADC EOF STA EOF LDA EOF+1 ADC #00 STA EOF+1 RTS ;At last! * * This procedure moves the text pointer forwards to the * next line in the buffer, and updates the screen pointer * if not at the bottom of the screen. * * On exit, carry will be set if TEXTP is at EOF, so e.g. * DOWN will know to back the pointer up. * NEXTP LDY #00 JSR ATEOF ;This is purely for the benefit of BCS INCSCR ;subroutine PRTEXT :LOOP LDA (TEXTP),Y CMP #13 BEQ :DONE INY BNE :LOOP :DONE SEC ;Move one past the CR TYA ADC TEXTP STA TEXTP LDA TEXTP+1 ADC #00 STA TEXTP+1 * Increment the screen pointer INCSCR CPX #24 BCS :CONT LDA SCREENP ADC #40 STA SCREENP LDA SCREENP+1 ADC #00 STA SCREENP+1 :CONT * * This guy just checks to see if TEXTP=EOF, (C=1 if at EOF) * ATEOF LDA TEXTP+1 CMP EOF+1 ;Check if we are at the end BCC :RTS LDA TEXTP CMP EOF ;Carry will be set if at EOF :RTS RTS * * ATBEGIN -- See if text pointer = BUFFER * T1 DFB 00 ATBEGIN LDA TEXTP SEC SBC BUFFER STA T1 LDA TEXTP+1 SBC BUFFER+1 ORA T1 RTS * * This procedure backs the text pointer to the previous line * Not to mention the screen pointer, if not on line 0. * * This procedure assumes we are not at the beginning of the * file (currently). * BACKP LDY #00 JSR ATBEGIN BEQ :RTS JSR DECP ;First, back up past the chr$(13) :LOOP JSR DECP JSR ATBEGIN BEQ :CONT2 BCC :BAIL LDA (TEXTP),Y CMP #13 BNE :LOOP :BAIL INC TEXTP ;Move text pointer past the last BNE :CONT2 ;chr$(13) to beginning of line. INC TEXTP+1 :CONT2 CPX #00 BEQ :RTS LDA SCREENP SEC SBC #40 STA SCREENP LDA SCREENP+1 SBC #00 STA SCREENP+1 :RTS RTS * * DECP -- Back up the pointer by one * DECP LDA TEXTP BNE :NOSUB DEC TEXTP+1 :NOSUB DEC TEXTP RTS * * PRTEXT prints out the file to the screen, beginning * with the current line, until the end of the screen is * reached (so it clears the screen underneath). * PRTEXT TYA ;Need to restore original line PHA TXA PHA LDA TEXTP PHA LDA TEXTP+1 PHA LDA SCREENP PHA LDA SCREENP+1 PHA :LOOP1 LDY #00 JSR ATEOF ;Don't print if at EOF! BCS :SPACE JSR PRLINE ;Sets Y to last char position+1 :SPACE LDA #32 :LOOP2 CPY #40 ;Space the rest of the line BCS :NEXT STA (SCREENP),Y INY BPL :LOOP2 :NEXT JSR NEXTP ;Go to next point INX ;Advance to next line CPX #25 BNE :LOOP1 ;and repeat :DONE PLA STA SCREENP+1 PLA STA SCREENP PLA STA TEXTP+1 PLA STA TEXTP PLA TAX PLA TAY CLC ;Go back to original pos JSR PLOT :RTS RTS * * This guy prints out a line to the screen. * PRLINE TXA PHA LDY #00 CLC JSR PLOT ;Go to column 0 on line LDY #00 :LOOP2 LDA (TEXTP),Y ;And print out line CMP #13 BEQ :DONE AND #$7F ;Strip high bit (shift-spc, etc.) CMP #64 ;skip punctuation and numbers BCC :SKIP2 CMP #96 ;Handle upper-case BCC :CONT ADC #31 ;add 32 :CONT SBC #63 ;How very unelegant. :SKIP2 STA (SCREENP),Y INY CPY #40 BCC :LOOP2 :DONE PLA TAX RTS * * This procedure moves the screen downwards, until it * hits the row stored in X, which it then blanks. * MOVDOWN CPX #24 BPL :SPACE STX TEMP LDX #24 LDA #<40*24+1024 STA POINT2 LDA #>40*24+1024 STA POINT2+1 LDA #<40*23+1024 STA POINT1 LDA #>40*23+1024 STA POINT1+1 :LOOP3 LDY #39 :LOOP2 LDA (POINT1),Y STA (POINT2),Y DEY BPL :LOOP2 LDA POINT1 ;Move pointers back a row STA POINT2 SEC SBC #40 STA POINT1 LDA POINT1+1 STA POINT2+1 SBC #00 STA POINT1+1 DEX CPX TEMP BNE :LOOP3 :SPACE LDY #39 LDA #32 ;Fill this line with spaces :LOOP4 STA (SCREENP),Y DEY BPL :LOOP4 :ALLDONE RTS ;And X equals its original value * * This routine moves all text forwards of TEXTP ahead * one character and adds a CHR$(13) (It inserts a return * into the text). * * It updates EOF, but not TEXTP * BUMP LDA EOF STA POINT1 LDA EOF+1 STA POINT1+1 :LOOP LDY #00 LDA (POINT1),Y INY STA (POINT1),Y LDA POINT1+1 CMP TEXTP+1 BNE :CONT1 LDA POINT1 CMP TEXTP BEQ :DONE :CONT1 DEC POINT1 LDA #$FF CMP POINT1 BNE :LOOP DEC POINT1+1 BNE :LOOP :DONE LDA #13 LDY #00 STA (TEXTP),Y INC EOF BNE :RTS INC EOF+1 :RTS RTS * * This is just like BUMP, but deletes a char out of the file * unless EOF = TEXTP+1, i.e. no chars left to delete * BUMPBACK LDA EOF+1 CMP TEXTP+1 BNE :CONT LDA EOF CLC ;Subtract 1 more SBC TEXTP BEQ :RTS :CONT LDA TEXTP STA POINT1 LDA TEXTP+1 STA POINT1+1 :LOOP LDY #01 LDA (POINT1),Y DEY STA (POINT1),Y LDA POINT1+1 CMP EOF+1 BNE :CONT1 LDA POINT1 CMP EOF BEQ :DONE :CONT1 INC POINT1 BNE :LOOP INC POINT1+1 BNE :LOOP :DONE LDA EOF BNE :SKIP DEC EOF+1 :SKIP DEC EOF :RTS RTS * * RESTORE restores the screen from the values stored in * TEMPX and TEMPY. * RESTORE JSR WAITFIX JSR FREEZEP LDX TEMPX BEQ :DONE :L1 JSR BACKP DEX BNE :L1 :DONE LDA #<1024 ;Always start at top o screen STA SCREENP LDA #>1024 STA SCREENP+1 JSR PRTEXT JSR THAWP LDX TEMPX LDY TEMPY CLC JMP PLOT * * PRINTDEC prints out the 2-byte number contained in * (X,Y) = (hi, lo) to the screen (or wherever). * * (Based on ascii32.s) * * Take 2 -- Divide by 10 manually; remainder is coeff * of successive powers of 10 * * Number to convert -> faq2..faq2+1 (lo..hi) * PRINTDEC LDA #10 STA TEMP ;Divide by 10 STY POINT1 STX POINT1+1 JSR DIV16 PHA ;10^0 JSR DIV16 PHA ;10^1 JSR DIV16 PHA ;10^2 JSR DIV16 TAY ;10^3 BEQ :SKIP3 ;Don't print leading zeros JSR :PRINT :SKIP3 PLA ;10^2 BNE :CONT2 CPY #00 BEQ :SKIP2 :CONT2 INY ;Make sure Y nonzero JSR :PRINT :SKIP2 PLA ;10^1 BNE :CONT1 CPY #00 BEQ :SKIP1 :CONT1 INY JSR :PRINT :SKIP1 PLA ;10^0 :PRINT CLC ;Always print last digit ADC #48 JMP CHROUT * * Routine to divide a 16-bit number (in point1,point1+1) by * the 8-bit number in temp. Result -> (point1,point1+1), * remainder in A. Numbers all go lo..hi * DIV16 LDA #00 LDY #$10 :LOOP ASL POINT1 ROL POINT1+1 ROL CMP TEMP BCC :DIV2 SBC TEMP INC POINT1 :DIV2 DEY BNE :LOOP RTS *------------------------------- DO 0 * * INPUT inputs a string of data into STRBUF. The maximum * number of chars to be read are passed in X. On output, * zero set means the input was aborted with R/S (or the * filename length is zero); A contains the number of chars * read. * INPUT LDY #00 STY POINT1 ;Number of chars in string STX POINT1+1 ;Max number of chars :LOOP JSR GETKEY CMP #91 ;Alphanumeric characters BCS :OTHER CMP #32 BCC :OTHER LDX POINT1+1 ;Too many characters BEQ :LOOP JSR CHROUT LDY POINT1 STA STRBUF,Y ;STRBUF is at the end of this code INC POINT1 DEC POINT1+1 JMP :LOOP :OTHER JSR WAITFIX ;Fix cursor phase CMP #20 ;Delete BNE :RET LDY POINT1 ;No more chars in buffer BEQ :LOOP JSR CHROUT INC POINT1+1 DEC POINT1 JMP :LOOP :RET CMP #13 ;Return BNE :STOP LDA #13 JSR CHROUT LDA POINT1 ;Zero flag set if no chars in name RTS ;clear otherwise! :STOP JSR STOP BNE :LOOP LDA #13 JSR CHROUT LDA #00 ;Set zero flag. RTS FIN *------------------------------- * * PRESSKEY prompts for a key and waits for that key. * PRESSKEY LDY #00 :LOOP LDA :MESG,Y BEQ :DONE JSR CHROUT INY BNE :LOOP :DONE JMP GETKEY :MESG TXT 'press a key to continue...' HEX 00 * * GETKEY -- turn on cursor, wait for keypress * GETKEY LDA #00 STA BLNSW ;Turn cursor on. :WAITKEY JSR GETIN TAY BEQ :WAITKEY INC BLNSW RTS * * CRSRFIX resets the blink phase and restores the * correct character to the screen. (Color is ignored) * It assumes Y contains the correct column. * CRSRFIX PHA LDA #01 ;Turn cursor off STA BLNSW STA BLNCT STA BLNON LDA (SCREENP),Y AND #$7F STA (SCREENP),Y PLA RTS * * WAITFIX is similar but waits for the cursor to fix * itself, and hence doesn't need Y set correctly. * WAITFIX PHA LDA #2 STA BLNCT LDA #0 ;Make sure timer is on! STA BLNSW :L1 LDA BLNON ;Wait for correct phase BNE :L1 INC BLNSW ;...and turn it off. PLA RTS CLRSCR ;Clear screen in friendly way LDA $D021 PHA LDA #15 STA $0286 STA $D021 LDA #147 JSR CHROUT PLA STA $D021 RTS