       
*
* PSMALL -- print a small number, i.e. faster for
*   little numbers.
*
PSMALL   
         LDY #00
:LOOP    INY
         SEC
         SBC ARGBASE
         BCS :LOOP
         ADC ARGBASE
         DEY
         BEQ :PRINT
         PHA
         TYA
         JSR :PRINT
         PLA
:PRINT   CMP #10          ;Convert to screen char
         BCC :CONT
         ADC #6
         CLC
:CONT    ADC #$30
         JMP CHAROUT


*
* SETNOTE -- Compute note from LAST values, store,
*   and return result in .A and .X
*
SETNOTE  
         LDX LASTNOT
         CPX #$F0         ;Hold
         BEQ :CONT
         LDA NOTEPOS,X
         LDY LASTOCT      ;Last octave
         CLC
         ADC OCTTAB,Y     ;Octave offset
         TAX
:CONT    LDA LASTDUR
         JSR STAFIELD     ;Place data into field
         JSR SETMSG       ;Set (row,col) to message bar
                          ;clear bar, etc.
         JMP PLNOTE

*
* READNOTE
*   Data is a note value.  Fetch the octave and duration
*
READNOTE 
         CMP #'x'
         BNE :NOHOLD
         LDX #$F0         ;Hold code
         STX LASTNOT
         LDA LASTDUR
         JSR STAFIELD
         JSR SETMSG
         LDA SINGLEKEY    ;Single-keypress mode?
         BEQ :GETDUR
         JMP RET

:NOHOLD  CMP #'y'         ;Skip over x
         BCC :CONT
         SBC #2           ;If so, then adjust
:CONT    SBC #64          ;subtract 65 or 64
         CMP #12
         BCS :STNOTE
         CLC
         ADC SHARPVAL     ;Can press # beforehand
:STNOTE  STA LASTNOT
         JSR SETNOTE
         LDA #00
         STA SHARPVAL
         LDA SINGLEKEY    ;Single-keypress mode?
         BPL :GETOCT
         JMP RET

:GETOCT  LDA #2           ;Octave
         JSR SETACT
:WAIT1   JSR GETIN        ;Wait for a digit 0-7
         CMP #'#'         ;Extended codes
         BNE :SPA

         LDA LASTNOT      ;'#' will add 12 to the
         CMP #12          ;current note
         BCS :WAIT1
         ADC #12
         BNE :STNOTE

:SPA     CMP #32          ;space accepts current value
         BEQ :GETDUR
         JSR ISEDIT       ;editor commands
         BEQ :EDIT
         JSR ISOTHER      ;Special commands
         BEQ :OTHER
         CMP #'_'
         BEQ :RTS
         CMP #'0'         ;Or another letter?
         BCC :WAIT1
         CMP #'8'
         BCS :WAIT1

         AND #$0F         ;Get digit
         STA LASTOCT
         JSR SETNOTE

:GETDUR  LDA #3
         JSR SETACT
:WAIT2   JSR GETIN        ;Letter or terminating char
         CMP #'_'
         BEQ :GETOCT
         CMP #32
         BEQ :RTS
         JSR ISEDIT
         BEQ :EDIT
         JSR ISOTHER
         BEQ :OTHER
         CMP #'0'
         BCC :WAIT2
         CMP #'9'+1
         BCC :DIGIT
         CMP #79          ;A-N for 10-23
         BCS :WAIT2
         CMP #65
         BCC :WAIT2

         SBC #7           ;This puts A-N on top of 0-9
:DIGIT   SEC
         SBC #48          ;Convert to number
         STA LASTDUR
         JSR SETNOTE

:DONE    JMP RET
:RTS     RTS

:EDIT    JMP EDIT
:OTHER   JMP OTHER

*
* PRFIELDS
*   Prints out the field data for the current field as
*   pointed to by POINT1.
*

ADD2P    
         STX BACKTEMP
         JSR INFOLD
         BNE :NOFOLD
         LDA OPENFOLD,X
         BEQ :NOFOLD
         LDA FOLDHI2,X
         STA POINT1+1
         LDA FOLDHI1,X
         STA POINT1
         INC POINT1
         BNE :RTS
         INC POINT1+1
         BNE :RTS

:NOFOLD  LDA POINT1
         CLC
         ADC #2
         STA POINT1
         BCC :RTS
         INC POINT1+1
:RTS     LDX BACKTEMP
         RTS

BACKP                     ;Back up the pointer X-1 rows
         STX BACKTEMP
:LOOP    DEC BACKTEMP
         BEQ :RTS
         LDA POINT1
         SEC
         SBC #2           ;Back up the pointer
         STA POINT1
         BCS :C1
         DEC POINT1+1

:C1      JSR INFOLD
         BNE :LOOP
         LDA OPENFOLD,X
         BEQ :LOOP
         LDA FOLDLO1,X
         STA POINT1
         LDA FOLDLO2,X
         STA POINT1+1
         BNE :LOOP
:RTS     
         RTS

BACKTEMP DFB 00

PRTEMP   DFB 00           ;temporary storage
PRFIELDS 
         LDA POINT1+1
         PHA
         LDA POINT1
         PHA

         LDY CURFLD
         LDX F1ROW,Y
         JSR BACKP
         JSR ATBEGIN      ;Because of folds, it is possible
         BCS :CONT        ;to back up past the beginning

         LDX CURFLD       ;If so, then back up and try again
         DEC F1ROW,X      ;(No worse than 10 tries)
         PLA
         STA POINT1
         PLA
         STA POINT1+1
         BNE PRFIELDS

:CONT    LDX #1
         TYA
         STA TEMP
         ASL
         ASL
         ASL
         SEC
         ADC TEMP         ;x9+1
         TAY
         STY PRTEMP
         JSR PLOPXY
         JSR PRFIELD
         PLA
         STA POINT1
         PLA
         STA POINT1+1
         RTS

TCHARS   DFB 12           ;May change to 11
PFOLD    
         LDA #'@'
         JSR PRFOLD
         LDA FOLDHI1,X    ;Go to end of fold
         SEC
         SBC #01          ;-1, because of NEXTROW
         STA POINT1
         LDA FOLDHI2,X
         SBC #00
         STA POINT1+1
         JMP NEXTROW
PRFOLD                    ;Print fold name
         JSR CHAROUT
         JSR TWELVEX      ;Compute 12*.X -> ACC
         LDY #5
:LOOP    LDA (ACC),Y
         JSR CHAROUT
         INY
         CPY TCHARS
         BNE :LOOP
         RTS

PRFIELD                   ;Print a single chunk of data
         LDA #15          ;Light gray
         STA COLOR
         LDY #32
         JSR INFOLD
         BNE :MARK
         LDY #'%'
         LDA OPENFOLD,X
         BNE PFOLD
:MARK    JSR ISMARKER     ;Are we at a marker?
         BNE :C1
         LDY #43          ;+ sign
:C1      LDA BLFLAG       ;See if block needs to be marked
         BEQ :C0
         LDA POINT1
         CMP CLIPLO
         LDA POINT1+1
         SBC CLIPLO+1
         BCC :C0
         LDA POINT1
         CMP CLIPHI
         LDA POINT1+1
         SBC CLIPHI+1
         BCS :C0
         LDY #'>'
:C0      LDA FOLDFLAG
         BEQ :C00
         LDA POINT1
         CMP FOLDBOT
         LDA POINT1+1
         SBC FOLDBOT+1
         BCC :C00
         LDA POINT1
         CMP FOLDTOP
         LDA POINT1+1
         SBC FOLDTOP+1
         BCS :C00
         LDY #'%'

:C00     TYA
         JSR CHAROUT

         LDY #00
         LDA (POINT1),Y
         TAX
         INY
         LDA (POINT1),Y
         BMI :INST        ;Instruction or note?

         PHA
         LDA #13          ;Lt. Green
         STA COLOR
         CPX #$F0         ;Hold
         BNE :C5
         JSR PLOPSTR
         TXT 'hld',00
         JMP :C6

:C5      LDY #8           ;Compute note and octave
         TXA
:LOOP    DEY
         CMP OCTTAB,Y
         BCC :LOOP
         SBC OCTTAB,Y     ;Y=octave
         TAX              ;Note
         LDA KEYPOS,X     ;Figure out which key it corresponds
         TAX              ;to
         LDA NOTETEXT,X   ;Now print text
         JSR CHAROUT      ;two chars per note
         LDA NOTETEXT+24,X
         JSR CHAROUT
         TYA
         ORA #48
         JSR CHAROUT      ;Octave

:C6      LDA #32
         JSR CHAROUT
         JSR CHAROUT
         JSR CHAROUT
         PLA              ;Duration
         CLC
         ADC #48
         CMP #58
         BCC :PRDUR
         ADC #6           ;+7
:PRDUR   JSR CHAROUT
         JMP NEXTROW

:INST    CMP #LOADGLOB
         BCS :LOADVAR
         CMP #ACTLOC
         BEQ :ACTL
         CMP #DACTLOC
         BEQ :DACTL
         CMP #JSUB
         BEQ :JSUB
:CMAC    AND #$7F
         STA TEMP
         ASL
         ADC TEMP
         TAY
         LDA ITEXT,Y
         JSR CHAROUT
         LDA ITEXT+1,Y
         JSR CHAROUT
         LDA ITEXT+2,Y
         JSR CHAROUT
         LDA #32
         JSR CHAROUT
         JSR CHAROUT
         TXA
         JSR PHBYTE       ;Argument
         JMP NEXTROW

:LOADVAR INC PLOADFLAG    ;Signal for PLOADVAR
         JSR PLOADVAR     ;to space stuff out right.
         DEC PLOADFLAG
         LDA #32
         JSR CHAROUT
         TXA
         JSR PHBYTE
         JMP NEXTROW

:JSUB    LDY #5
         STY COLOR
         LDY MACFLAG
         BPL :CMAC
         LDA #11          ;Only print 6 chars
         STA TCHARS
         INC PLOADFLAG    ;If not in fold, then print
         LDA #'^'         ;spaces
         JSR PJFOLD
         DEC PLOADFLAG
         LDA #12
         STA TCHARS
         JMP NEXTROW

:ACTL    LDY #'+'
         DFB $2C
:DACTL   LDY #'-'
         PHA
         LDA #4           ;Purple
         STA COLOR
         LDA MACFLAG      ;Expand macro names?
         ASL
         PLA
         BCC :CMAC        ;Think BPL macflag
         TYA
         JSR CHAROUT
         TXA
         ASL              ;16 bytes per entry
         ASL
         ASL
         ASL
         TAY
         LDX #6           ;Only print 6 chars
         JSR PNAME2

NEXTROW  JSR ADD2P
         LDA #13
         STA COLOR
:NEXT    LDX ROW
         CPX #21
         BCS :DONE
         INX
         LDY PRTEMP
         JSR PLOPXY
         JSR ATEND
         BEQ :BLAH
         JMP PRFIELD
:BLAH    JSR PLOPSTR
         TXT ' --- ---',00
         JMP :NEXT

:DONE    RTS

ITEXT    TXT 'VOL'
         TXT 'AGL'
         TXT 'DGL'
         TXT 'ALO'
         TXT 'DLO'
         TXT 'LIN'
         TXT 'REP'
         TXT 'REN'
         TXT 'STP'
         TXT 'GON'
         TXT 'GOF'
         TXT 'RES'
         TXT 'JMP'
         TXT 'JSR'
         TXT 'RTS'
         TXT 'WAI'
         TXT 'SYN'
         TXT 'CYC'
         TXT 'SLR'
         TXT 'SOF'

ATEND                     ;Check to see if POINT1 equals
         LDA CURFLD
         ASL
         TAX
         LDA POINT1       ;the end of a field.
         SEC
         SBC BFIELD2,X    ;End of field
         STA TEMP
         LDA POINT1+1
         SBC BFIELD2+1,X
         ORA TEMP
         RTS

ATBEGIN                   ;Check if at the beginning of a field
         LDA CURFLD
         ASL
         TAX
         LDA POINT1
         SEC
         SBC BFIELD1,X    ;Begin of field 1
         STA TEMP
         LDA POINT1+1
         SBC BFIELD1+1,X
         ORA TEMP
         RTS


*
* ISMARKER checks to see if POINT1 equals any current
* marker.  The Z flag is set if a marker is found
* and A contains the marker number.  X contains $FF
* if not found and 0 if found.
* Y is unaffected.
*
ISMARKER 
         LDX #00
:LOOP    LDA POINT1
         CMP MARKERS,X
         BNE :CONT
         LDA POINT1+1
         CMP MARKERS+1,X
         BEQ :GOTCHA
:CONT    INX
         INX
         CPX #64          ;32 markers total
         BNE :LOOP
         LDX #$FF
         RTS
:GOTCHA  TXA
         LSR
         LDX #00
         RTS

*
* SETACT
*   Sets the action box to the message number passed in
*   in A.
*   (The action box tells what action the program is
*   waiting for).
*
SETACT   
         PHA
         LDA #7
         STA COLOR
         LDX #23
         LDY #1
         JSR PLOPXY
         LDA #'?'
         JSR CHAROUT

         PLA
         ASL
         ASL
         TAX
         LDA :TABLE,X
         JSR CHAROUT
         LDA :TABLE+1,X
         JSR CHAROUT
         LDA :TABLE+2,X
         JSR CHAROUT
         LDA :TABLE+3,X
         JMP CHAROUT

:TABLE   TXT '    '       ;0
         TXT 'Note'       ;1 note/instruction
         TXT 'Oct '
         TXT 'Dur '
         TXT 'Var#'       ;4 variable number

*
* SETMSG
*   Prints the appropriate data in the status bar.
*   A contains the duration or player directive and
*   X contains the note or directive parameter.
*   This routine thus mimics the player.
*
TA       DFB 00
TX       DFB 00
TY       DFB 00
SETMSG   
         STA TA
         STX TX
         STY TY

         LDA #23
         STA ROW
         LDA #7
         STA COLUMN
         LDA #14
         STA COLOR
         JSR PLOP
         JSR ISMARKER
         BNE :CONT2
         PHA
         LDA #'('         ;Indicate marker number
         JSR CHAROUT
         LDA #'M'
         JSR CHAROUT
         PLA
         JSR PSMALL
         LDA #')'
         JSR CHAROUT
:CONT2   LDY TY
         LDX TX
         LDA TA
         BMI :DIRECT      ;Directives have bit 7 set

:NOTEDUR 
         PHA
         CPX #$F0
         BEQ :HOLD
         LDY #8           ;Compute note and octave
         TXA
:LOOP    DEY
         CMP OCTTAB,Y
         BCC :LOOP
         SBC OCTTAB,Y     ;Y=octave
         TAX              ;Note
         LDA KEYPOS,X
         TAX
                          ;Now print text
                          ;two chars per note
         LDA NOTETEXT,X   ;First char
         CMP #32
         BEQ :SKIP
         JSR CHAROUT
:SKIP    LDA NOTETEXT+24,X
         CMP #32
         BEQ :SKIP2
         JSR CHAROUT
:SKIP2   LDA #'-'
         JSR CHAROUT
         TYA              ;Octave
         ORA #48
         JSR CHAROUT
:DUR     JSR PLOPSTR
         TXT ' dur ',00
         PLA              ;And the duration
         TAX
         LDA DURTAB,X
         LDX #00
         LDY ARGBASE      ;Base
         JSR PLOPNUM
         JMP CLEARMSG

:HOLD    
         JSR PLOPSTR
         TXT 'Hold note,',00
         JMP :DUR

:DIRECT                   ;Handle directives
         CMP #$C0         ;Load variables
         BCS :LOADVAR
         ASL
         TAY              ;Otherwise, find handler address
         LDA :TABLE1,Y
         STA :JMP+1
         LDA :TABLE1+1,Y
         STA :JMP+2
:JMP     JMP $C000

:TABLE1  DA PSETV
         DA PACTG
         DA PDACTG
         DA PACTL
         DA PDACTL
         DA PLDINST
         DA PREP
         DA PENDR
         DA PSTO
         DA PGON
         DA PGOFF
         DA PRESTRT
         DA PJMP
         DA PJSR
         DA PRTS
         DA PWAIT
         DA PSYNC
         DA PCYCTEST
         DA PSLUR
         DA PSLOFF

:LOADVAR JSR PLOADVAR
         JMP PRINTX

PLOADFLAG DFB 00          ;Flag, depending on who calls
                          ;PLOADVAR
PLNUM    DFB 00           ;temp var

PLOADVAR 
         CMP #$E0
         BCS :LOCAL
         EOR #$C0         ;Load global variable
         PHA              ;variable number
         LDA #'G'
         JSR CHAROUT
         PLA
:STA     STA PLNUM        ;flag
         CMP ARGBASE
         BCC :CONT
         ORA #$80         ;to tell us if we need an
         STA PLNUM        ;extra space or not.
         EOR #$80
:CONT    JSR PSMALL
         LDA PLNUM
         BMI :C2
         PHA
         LDA #32
         JSR CHAROUT
         PLA
:C2      AND #$7F
         TAY
         LDA #'='
         JMP CHAROUT      ;.Y = variable number
:LOCAL   
         AND #$1F
         PHA
         LDA #'L'
         JSR CHAROUT
         PLA
         BPL :STA

*
* Print individual directives
*
PSETV    
         JSR PLOPSTR
         TXT 'Set vol=',00
         JMP PRINTX
PACTG    
         JSR PLOPSTR
         TXT 'Act glob ',00
PNAME    TXA
         PHA
         JSR PSMALL       ;Plop a small number
         LDA #32
         JSR CHAROUT
         PLA
         ASL              ;16 bytes per entry
         ASL
         ASL
         ASL
         TAY
         LDX #14          ;14 chars per name
         JSR PNAME2
         JMP CLEARMSG
PNAME2   
         BCS :LOOP2
:LOOP    LDA MACTEXT+2,Y
         JSR CHAROUT
         LDA COLUMN
         CMP #39
         BEQ :DONE
         INY
         DEX
         BNE :LOOP
:DONE    RTS

:LOOP2   LDA MACTEXT+2+256,Y
         JSR CHAROUT
         LDA COLUMN
         CMP #39
         BEQ :DONE
         INY
         DEX
         BNE :LOOP2
         RTS

PDACTG   
         JSR PLOPSTR
         TXT 'Deact. global ',00
         JMP PNAME
PACTL    
         JSR PLOPSTR
         TXT 'Act. local ',00
         JMP PNAME
PDACTL   
         JSR PLOPSTR
         TXT 'Deact. local ',00
         JMP PNAME

PLDINST  
         JSR PLOPSTR
         TXT 'Load inst ',00
         TXA
         STA TEMP
         ASL
         ADC TEMP
         ASL              ;times 6
         TAX
         LDY #6
:LOOP    LDA INAMES,X
         JSR CHAROUT
         INX
         DEY
         BNE :LOOP
         JMP CLEARMSG

PREP     
         JSR PLOPSTR
         TXT 'Play next sect ',00
         TXA
         LDX #00
         LDY ARGBASE
         JSR PLOPNUM
         JSR PLOPSTR
         TXT ' times',00
         JMP CLEARMSG
PENDR    
         JSR PLOPSTR
         TXT 'End repeat',00
         JMP CLEARMSG
PSTO     
         JSR PLOPSTR
         TXT 'Stop voice',00
         JMP CLEARMSG
PGON     
         JSR PLOPSTR
         TXT 'Gate on',00
         JMP CLEARMSG
PGOFF    
         JSR PLOPSTR
         TXT 'Gate off',00
         JMP CLEARMSG
PRESTRT  
         JSR PLOPSTR
         TXT 'Restart!',00
         JMP CLEARMSG

TMARK    DFB 00
PJMP     
         JSR PLOPSTR
         TXT 'Jump to M',00
PJMARK   STX TMARK
         TXA
         LSR
         JSR PSMALL
         LDA #32
         JSR CHAROUT
         LDA #'@'
         LDX TMARK
         JSR PJFOLD
         JMP CLEARMSG

PJFOLD   STA TEMP
         LDA POINT1       ;If inside of a fold, print
         PHA              ;fold name.
         LDA POINT1+1
         PHA

         LDA MARKERS,X
         STA POINT1
         LDA MARKERS+1,X
         STA POINT1+1

         JSR INFOLD
         BEQ :OK
         LDA PLOADFLAG
         BEQ :DONE
         LDA TEMP
         JSR CHAROUT
         LDA #' '
         LDX #6
:LOOP    JSR CHAROUT
         DEX
         BNE :LOOP
         BEQ :DONE

:OK      LDA TEMP
         JSR PRFOLD
:DONE    PLA
         STA POINT1+1
         PLA
         STA POINT1
         RTS

PJSR     
         JSR PLOPSTR
         TXT 'Jump to subr M',00
         JMP PJMARK

PRTS     
         JSR PLOPSTR
         TXT 'Return from subr',00
         JMP CLEARMSG

PWAIT    
         JSR PLOPSTR
         TXT 'Wait for Sync',00
         JMP CLEARMSG

PSYNC    
         JSR PLOPSTR
         TXT 'Sync',00
         JMP CLEARMSG

PCYCTEST 
         JSR PLOPSTR
         TXT 'Cycle test bit',00
         JMP CLEARMSG

PSLUR    
         JSR PLOPSTR
         TXT 'Slur mode',00
         JMP CLEARMSG

PSLOFF   
         JSR PLOPSTR
         TXT 'Slur off',00
         JMP CLEARMSG

*
* Print the number contained in X and clear message line
*
PRINTX   
         TXA
         LDX #00
         LDY ARGBASE
         JSR PLOPNUM

CLEARMSG LDY COLUMN       ;Clear mesg bar to end
         LDA #32
:LOOP    CPY #39
         BCS :RTS
         JSR CHAROUT
         INY
         BNE :LOOP
:RTS     RTS
