 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

