*-------------------------------
*
* Macro manager.
*
* This routine manages the macros.
*
* Updated 6/98 -- Fixed compile/marker bug, added
*       load/save single file.
*

         DSK '@0:macman'

         REL

VERSION  = $A000          ;File type ID

         PUT 'playvars.k.s'
         PUT 'diskio.ext.s'

CHROUT   = $FFD2
GETIN    = $FFE4
PLOT     = $FFF0

MACBEGIN = $02            ;End of player/beginning of macros
BFIELD1  = $04            ;Beginning of field 1
BFIELD2  = $06            ;Beginning of field 2
BFIELD3  = $08            ;Beginning of field 3
EFIELD3  = $0A            ;End of field 3
ENDFIELD = $0A            ;End of all fields

TEMP     = $FF
POINT1   = $FD

CODETEXT = $61            ;Compiler text pointer
CODEP    = $63            ;Compiler code pointer

ENTRYP   EXT              ;Entry point for macro

TEXTEND  EXT
TEXT     EXT
NEDINIT  EXT
COMPILER EXT
ERROR    EXT
INSTED   EXT
MUSICED  EXT
MUSINIT  EXT
INTINIT  EXT
PLAYFLAG EXT
CLRGATE  EXT

FREBOT   EXT
FRETOP   EXT
CLIP     EXT


MACTEXT  = LINKADDR-386   ;Table of names and addresses
                          ;xx xx address
                          ;14*xx name
                          ;+2 bytes end of all macros

*-------------------------------

*
* Initialize macro manager
*
MACINIT  ENT
*
* RESETMAC -- Resets all macros and pointers
*
RESETMAC 
         LDA #00          ;Erase all names
         STA POINT1
         LDX #>MACTEXT
         LDY #<MACTEXT
         LDA #32
:L1      STX POINT1+1
:LOOP1   STA (POINT1),Y
         INY
         BNE :LOOP1
         INX
         CPX #>LINKADDR
         BNE :L1
RESET2   
         LDA #00          ;Reset all macro text
         LDY #23
:LOOP2   STA MACTEXT-24,Y
         DEY
         BPL :LOOP2

         LDA #<LINKADDR-2 ;End address of all macros
         STA POINT1
         LDA #>LINKADDR-2
         STA POINT1+1

         LDX #<MACTEXT    ;Reset addresses
         LDA #24
         STA CURMAC
:LOOP3   LDY #01
         LDA #>MACTEXT
         STA (POINT1),Y
         DEY
         TXA
         STA (POINT1),Y
         LDA POINT1
         SEC
         SBC #16
         STA POINT1
         BCS :C1
         DEC POINT1+1
:C1      DEX
         DEC CURMAC
         BPL :LOOP3

         JSR SETTOP

         INC CURMAC       ;CURMAC=0
         RTS

HILIGHT                   ;(Un)Hilight current selection
         LDX CURMAC
         LDY #9
         JSR PLOPXY
:LOOP    
         LDA (SCREENP),Y
         EOR #$80
         STA (SCREENP),Y
         INY
         CPY #23
         BNE :LOOP
         RTS

PNAMES   
         LDA #155
         JSR CHROUT
         LDA #147
         JSR CHROUT
         LDA #15
         STA COLOR

         LDA #23
         STA TEMP
:LOOP    LDX TEMP         ;First print out names etc.
         LDY #00
         JSR PLOPXY
         TXA
         LDX #00
         LDY #10
         JSR PLOPNUM

         LDX TEMP
         LDY #3
         JSR PLOPXY

         JSR GETINDEX

         LDA #'$'
         JSR CHAROUT
         LDY #01
         LDA (POINT1),Y   ;Address, hi byte
         JSR PHBYTE
         DEY
         LDA (POINT1),Y
         JSR PHBYTE       ;Low byte
         LDA #32
         JSR CHAROUT

         LDY #02
:LOOP2   LDA (POINT1),Y
         JSR CHAROUT
         INY
         CPY #16          ;14 chars per entry
         BNE :LOOP2

         DEC TEMP         ;Move on to next one
         BPL :LOOP
         RTS

* Get table index of macro # contained in .X
* and store in POINT1
GETINDEX 
         LDA #00
         STA POINT1+1
         TXA
         ASL              ;Get the table index
         ASL
         ASL
         ASL
         ROL POINT1+1     ;0 or 1
         ADC #<MACTEXT
         STA POINT1       ;Low byte of string address
         LDA POINT1+1
         ADC #>MACTEXT
         STA POINT1+1
         RTS

SETTOP   
         LDA MACTEXT      ;Two bytes for file ID
         SEC
         SBC #3
         STA FRETOP
         LDA MACTEXT+1
         SBC #00
         STA FRETOP+1     ;End of memory
         RTS

*
* Main manager
*
CURMAC   DFB 00

MACMAN   ENT
         LDA #12
         STA $D020
         LDA #6
         STA $D021
         JSR PNAMES
         LDA #14          ;Lower case
         JSR CHROUT

         JSR SETTOP

:LOOP    JSR HILIGHT

:WAIT    JSR GETIN
         BEQ :WAIT

         CMP #133         ;F1
         BEQ :MUSIC
         CMP #134
         BEQ :INST
         CMP #17
         BEQ :DOWN
         CMP #29
         BEQ :RIGHT
         CMP #145
         BEQ :UP
         CMP #13
         BEQ :EDIT
         CMP #'e'
         BEQ :EDIT
         CMP #147
         BEQ :CLR
         CMP #136         ;F7
         BEQ DISK
         CMP #140         ;F8
         BEQ :SINGLE
         CMP #'c'
         BEQ :COMP
         CMP #16          ;Ctrl-P
         BEQ :PLAY
         CMP #'a'         ;Auto-compile
         BEQ :AUTO
         CMP #'d'
         BNE :WAIT

:DEL     JSR DELETE
         JMP MACMAN

:CLR     JSR CLEAR
         JMP MACMAN

:MUSIC   JMP MUSICED

:INST    JMP INSTED

:DOWN    JSR HILIGHT
         LDA CURMAC
         CMP #23
         BEQ :LOOP
         INC CURMAC
         BNE :LOOP

:UP      JSR HILIGHT
         LDA CURMAC
         BEQ :LOOP
         DEC CURMAC
         BPL :LOOP

:RIGHT   JSR EDNAME
         JMP MACMAN

:EDIT    JSR EDMAC
         JMP MACMAN

:COMP    JSR COMPILE
         JMP MACMAN

:PLAY    LDA PLAYFLAG
         EOR #$FF
         STA PLAYFLAG
         BNE :PBLAH
         JSR CLRGATE
         JMP MACMAN
:PBLAH   JSR PLAYINIT
         JMP MACMAN

:AUTO    LDA #$FF
         EOR AUTOFLAG
         STA AUTOFLAG
         JMP MACMAN

:SINGLE  JMP SINGLE

DISK     LDA FREBOT
         STA LOADADDR
         LDA FREBOT+1
         STA LOADADDR+1

         LDA MACTEXT
         SEC
         SBC #2           ;2 byte file ID
         STA SAVESTRT
         STA POINT1
         LDA MACTEXT+1
         SBC #00
         STA SAVESTRT+1
         STA POINT1+1

         LDY #00
         LDA #<VERSION
         STA LOADID
         STA (POINT1),Y
         LDA #>VERSION
         INY
         STA LOADID+1
         STA (POINT1),Y
         LDA #$FF
         STA CLIP+1       ;Reset clipboard

         LDA #>LINKADDR
         STA SAVEEND+1
         LDA #<LINKADDR
         STA SAVEEND
         LDX #<:TEXT
         LDA #>:TEXT
         JSR DISKIO
         LDA NEWDATA
         BNE :MOVE
         JMP MACMAN

:MOVE    LDA FREBOT
         STA BLSTART
         LDA FREBOT+1
         STA BLSTART+1
         LDA $AF          ;EOF+1
         STA BLEND+1
         LDA $AE
         STA BLEND
         BNE :C1
         DEC BLEND+1
:C1      DEC BLEND

         LDA BLEND
         SEC
         SBC BLSTART
         STA DIST
         LDA BLEND+1
         SBC BLSTART+1
         STA DIST+1

         LDA #<LINKADDR-1
         SEC
         SBC DIST
         STA BLDEST
         LDA #>LINKADDR-1
         SBC DIST+1
         STA BLDEST+1
         JSR BLMOVE

                          ;Fix up macro addresses
         LDA #<LINKADDR-2
         STA POINT1
         LDA #>LINKADDR-2
         STA POINT1+1

         LDY #0
         LDA (POINT1),Y
         STA CODEP        ;Temp pointer
         INY
         LDA (POINT1),Y
         STA CODEP+1      ;CODEP = Old top of macros

         LDA #>MACTEXT
         STA (POINT1),Y
         LDA #<MACTEXT
         DEY
         STA (POINT1),Y

         LDX #24
:FIXLOOP LDA POINT1
         SEC
         SBC #16
         STA POINT1
         BCS :C2
         DEC POINT1+1
:C2      
         LDY #00
         LDA CODEP
         SEC
         SBC (POINT1),Y
         STA DIST
         LDA CODEP+1
         INY
         SBC (POINT1),Y
         STA DIST+1

         LDA (POINT1),Y
         STA CODEP+1
         DEY
         LDA (POINT1),Y
         STA CODEP

         LDY #16
         LDA (POINT1),Y
         SEC
         SBC DIST
         LDY #00
         STA (POINT1),Y
         LDY #17
         LDA (POINT1),Y
         SBC DIST+1
         LDY #01
         STA (POINT1),Y

         DEX
         BNE :FIXLOOP

*               0123456789012345678901234567890123456789
:DONE    JMP MACMAN
:TEXT    DFB 147,18,153
         TXT '         Load/Save macro bundle         '
         DFB 146,13,00

*
* Load/save single file.  Works like EDMAC.
*
SINGLE   
         JSR MOVEMACS

         LDA TEXT
         STA LOADADDR
         STA SAVESTRT
         LDA TEXT+1
         STA LOADADDR+1
         STA SAVESTRT+1
         LDA TEXTEND
         STA SAVEEND
         LDA TEXTEND+1
         STA SAVEEND+1
         LDA #$FF
         STA LOADID
         STA LOADID+1

         LDX #<:TEXT
         LDA #>:TEXT
         JSR DISKIO
         LDA NEWDATA
         BEQ :DONE
         LDA $AE
         STA TEXTEND
         LDA $AF
         STA TEXTEND+1
         LDY #16          ;Use filename as new macro name
:LOOP    LDA LASTFILE,Y
         STA STRBUF,Y
         DEY
         BPL :LOOP
         JSR NEWNAME

:DONE    JSR GETMACS
         JMP MACMAN
:TEXT    DFB 147,18,5
         TXT '         Load/Save single file          '
         DFB 146,13,00

*
* EDNAME -- Edit macro name
*
EDNAME   
         LDX CURMAC
         LDY #9
         JSR PLOPXY

         LDA #32          ;Erase old name
:LOOP    JSR CHAROUT
         INY
         CPY #24
         BNE :LOOP

         LDY #9
         CLC
         JSR PLOT

         LDX #14
         JSR INPUT

NEWNAME  
         LDX CURMAC
         JSR GETINDEX
         LDY #02
:LOOP2   LDA STRBUF-2,Y   ;Copy string buffer
         BEQ :LOOP3
         STA (POINT1),Y
         INY
         CPY #16
         BNE :LOOP2
         BEQ :DONE
:LOOP3   LDA #32
         STA (POINT1),Y
         INY
         CPY #16
         BNE :LOOP3

:DONE    RTS

*
* CLEAR -- Clear all macros
*
CLEAR    
         LDA #1
         STA COLOR
         LDX #24
         LDY #00
         JSR PLOPXY
         JSR PLOPSTR
         TXT 'Clear all macros? (y/n)',00
:WAIT    JSR GETIN
         BEQ :WAIT
         CMP #'y'
         BNE :RTS
         LDY #00
         STY COLUMN
         JSR PLOPSTR
         TXT 'Clear names? (y/n)     ',00
:WAIT2   JSR GETIN
         BEQ :WAIT2
         CMP #'y'
         BEQ :CLR
         JMP RESET2
:CLR     JMP RESETMAC
:RTS     RTS

*
* DELETE -- Delete macro
*
BLEN     DA 00            ;Block length
DELETE   
         LDA #13
         STA COLOR
         LDX #24
         LDY #00
         JSR PLOPXY
         JSR PLOPSTR
         TXT 'Delete macro? (y/n)',00
:WAIT    JSR GETIN
         BEQ :WAIT
         CMP #'y'
         BEQ :DEL
         RTS

:DEL     LDX CURMAC
         JSR GETINDEX
         LDA #32
         LDY #15
:LOOP1   STA (POINT1),Y
         DEY
         CPY #2
         BPL :LOOP1

         LDA MACTEXT      ;First pointer
         STA BLSTART
         LDA MACTEXT+1
         STA BLSTART+1

         LDY #0
         LDA (POINT1),Y
         SEC
         SBC #1
         STA BLEND
         INY
         LDA (POINT1),Y
         SBC #00
         STA BLEND+1

         LDY #16          ;Compute size of macro text
         LDA (POINT1),Y
         LDY #0
         CLC              ;Pn+1 - Pn - 1
         SBC (POINT1),Y
         STA BLEN
         LDY #17
         LDA (POINT1),Y
         LDY #1
         SBC (POINT1),Y
         STA BLEN+1

         LDA BLEN
         CLC
         ADC MACTEXT
         STA BLDEST
         LDA BLEN+1
         ADC MACTEXT+1
         STA BLDEST+1

         LDX CURMAC
:LOOP2   LDY #0           ;Move all pointers forwards
         LDA BLEN
         CLC
         ADC (POINT1),Y
         STA (POINT1),Y
         INY
         LDA BLEN+1
         ADC (POINT1),Y
         STA (POINT1),Y
         LDA POINT1
         SEC
         SBC #16
         STA POINT1
         BCS :CONT
         DEC POINT1+1
:CONT    DEX
         BPL :LOOP2

         JMP BLMOVE       ;Move it, buster!

*
* EDMAC -- Edit the current macro
*
MEMTOP   DA 00            ;"Top" of memory
DIST     DA 00            ;Distance to move mem
AUTOFLAG DFB 00           ;Automatically compiler

EDMAC    
         JSR MOVEMACS
         JSR NEDINIT
         JSR GETMACS
         LDA AUTOFLAG
         BPL :EXIT
         JMP COMPILE
:EXIT    RTS

* A procedure, so that SINGLE can use it too.

MOVEMACS 
         LDA #$FF
         STA CLIP+1       ;Reset clipboard

         LDX CURMAC
         INX
         JSR GETINDEX

         LDY #00
         LDA (POINT1),Y   ;Next macro text begin
         STA MEMTOP
         TAX
         INY
         LDA (POINT1),Y
         STA MEMTOP+1

         STX POINT1
         STA POINT1+1
         LDA #13          ;Change end 00 to return
         LDY #$FF
         DEC POINT1+1
         STA (POINT1),Y

         LDA MACTEXT
         STA BLSTART
         SEC
         SBC FREBOT
         STA DIST
         LDA MACTEXT+1
         STA BLSTART+1
         SBC FREBOT+1
         STA DIST+1

         LDA MEMTOP+1
         STA BLEND+1
         LDA MEMTOP
         STA BLEND
         BNE :C1
         DEC BLEND+1
:C1      DEC BLEND

         LDA FREBOT
         STA BLDEST
         LDA FREBOT+1
         STA BLDEST+1

         LDX CURMAC

:LOOP    JSR GETINDEX
         LDY #00          ;Fix up pointers
         LDA (POINT1),Y
         SEC
         SBC DIST
         STA (POINT1),Y
         INY
         LDA (POINT1),Y
         SBC DIST+1
         STA (POINT1),Y
         DEX
         BPL :LOOP

         LDX CURMAC
         JSR GETINDEX
         LDA (POINT1),Y
         STA TEXT+1
         DEY
         LDA (POINT1),Y
         STA TEXT

         JSR BLMOVE

         LDA MEMTOP       ;NED stuff
         SEC
         SBC DIST
         STA TEXTEND
         STA POINT1
         LDA MEMTOP+1
         SBC DIST+1       ;End of file +1
         STA TEXTEND+1
         STA POINT1+1
         LDA #13
         LDY #00
         STA (POINT1),Y   ;Fix up ending byte
         RTS

*
* Get macros back and restore pointers
*
GETMACS  
         LDA MEMTOP
         SEC
         SBC TEXTEND
         STA DIST
         LDA MEMTOP+1
         SBC TEXTEND+1
         STA DIST+1

         LDA FREBOT
         STA BLSTART
         CLC
         ADC DIST
         STA BLDEST
         LDA FREBOT+1
         STA BLSTART+1
         ADC DIST+1
         STA BLDEST+1

         LDA TEXTEND      ;EOF points to last location+1
         SEC
         SBC #01
         STA BLEND
         STA POINT1
         LDA TEXTEND+1
         SBC #00
         STA BLEND+1
         STA POINT1+1
         LDA #00
         TAY
         STA (POINT1),Y   ;Files end with 00 for compiler

         JSR BLMOVE       ;Move everything back up

         LDX CURMAC
:LOOP3   JSR GETINDEX
         LDY #00          ;Fix pointers
         LDA (POINT1),Y
         CLC
         ADC DIST
         STA (POINT1),Y
         INY
         LDA (POINT1),Y
         ADC DIST+1
         STA (POINT1),Y
         DEX
         BPL :LOOP3

         RTS              ;Done!

*
* COMPILE
*
COMPMSG  
         JSR STROUT
         DFB 19           ;Home
         TXT 'Compiling macro ',00
         LDA COMPMAC
         LDX #00
         LDY #10
         JSR PRINTNUM
         LDA #13
         JSR CHROUT
         LDA #13
         JMP CHROUT

EMPTYMAC JSR RETURN
         PLA
         RTS
         DFB 00

COMPMAC  DFB 00           ;Macro being compiled
COMPILE  
         LDA PLAYFLAG     ;Don't compile if player active
         BEQ :C1
         RTS

:C1      LDY #62          ;Both markers and folds will
:LOOP1A  LDA MARKERS,Y    ;probably move
         SEC
         SBC BFIELD1
         STA MARKERS,Y
         LDA MARKERS+1,Y
         SBC BFIELD1+1
         STA MARKERS+1,Y
         DEY
         DEY
         BPL :LOOP1A

         LDA ENDFIELD
         STA CODEP        ;Temp pointer
         LDA ENDFIELD+1
         STA CODEP+1

:LOOP2A  LDA CODEP
         CMP FREBOT
         LDA CODEP+1
         SBC FREBOT+1
         BCS :DONE2A
         LDY #00
:L2A     LDA (CODEP),Y
         SEC
         SBC BFIELD1
         STA (CODEP),Y
         INY
         LDA (CODEP),Y
         SBC BFIELD1+1
         STA (CODEP),Y
         INY
         CPY #4
         BCC :L2A

         LDA CODEP
         CLC
         ADC #12
         STA CODEP
         BCC :LOOP2A
         INC CODEP+1
         BNE :LOOP2A
:DONE2A  

         LDA MACTEXT      ;Onwards...
         SEC
         SBC FREBOT
         STA DIST
         LDA MACTEXT+1
         SBC FREBOT+1
         STA DIST+1
         DEC DIST+1       ;Safety margin

         LDA BFIELD1
         STA BLSTART
         CLC
         ADC DIST
         STA BLDEST
         LDA BFIELD1+1
         STA BLSTART+1
         ADC DIST+1
         STA BLDEST+1
         LDA FREBOT
         STA BLEND
         LDA FREBOT+1
         STA BLEND+1

         JSR BLMOVE

         LDY #06
:L1      LDA DIST
         CLC
         ADC BFIELD1,Y
         STA BFIELD1,Y
         LDA DIST+1
         ADC BFIELD1+1,Y
         STA BFIELD1+1,Y
         DEY
         DEY
         BPL :L1
         LDA FREBOT
         CLC
         ADC DIST
         STA FREBOT
         LDA FREBOT+1
         ADC DIST+1
         STA FREBOT+1

         LDA MACBEGIN
         STA CODEP
         STA ENTRYP       ;In case no macros present
         LDA MACBEGIN+1
         STA CODEP+1
         STA ENTRYP+1

         LDY #00          ;Start with JSR RETURN PLA RTS
:L2      LDA EMPTYMAC,Y   ;For empty macros to point to
         BEQ :OUT
         STA (MACBEGIN),Y
         INY
         BNE :L2
:OUT     TYA
         CLC
         ADC MACBEGIN
         STA CODEP
         LDA MACBEGIN+1
         ADC #00
         STA CODEP+1

         LDA #147
         JSR CHROUT
         LDA #$FF
         STA COMPMAC
:LOOP    
         INC COMPMAC
         LDX COMPMAC
         CPX #24
         BEQ :DONE
         JSR COMPMSG
         LDX COMPMAC
         JSR GETINDEX
         TXA
         ASL
         TAX              ;.X is index into macro address tab

         LDA MACBEGIN     ;Empty macro
         STA MACADR,X     ;Also covers errors
         LDA MACBEGIN+1
         STA MACADR+1,X

         LDY #16          ;Check to see if macro is empty
         LDA (POINT1),Y
         LDY #00
         CLC              ;Size=1 means empty
         SBC (POINT1),Y
         STA TEMP
         LDY #17
         LDA (POINT1),Y
         LDY #01
         SBC (POINT1),Y
         ORA TEMP
         BEQ :LOOP
                          ;Compile!
         LDY #00
         LDA (POINT1),Y
         STA CODETEXT
         INY
         LDA (POINT1),Y
         STA CODETEXT+1
         JSR COMPILER
         LDA ERROR
         BEQ :CONT
         JSR :RET
         JMP :LOOP

:CONT    LDA COMPMAC
         ASL
         TAX
         LDA ENTRYP       ;Entry point from compiler
         STA MACADR,X
         LDA ENTRYP+1
         STA MACADR+1,X
         BNE :LOOP

:DONE    
         LDA BFIELD1
         STA BLSTART
         SEC
         SBC CODEP
         STA DIST
         LDA BFIELD1+1
         STA BLSTART+1
         SBC CODEP+1
         STA DIST+1

         LDA FREBOT
         STA BLEND
         LDA FREBOT+1
         STA BLEND+1
         LDA CODEP
         STA BLDEST
         LDA CODEP+1
         STA BLDEST+1

         JSR BLMOVE

         LDY #6
:L3      LDA BFIELD1,Y
         SEC
         SBC DIST
         STA BFIELD1,Y
         LDA BFIELD1+1,Y
         SBC DIST+1
         STA BFIELD1+1,Y
         DEY
         DEY
         BPL :L3

         LDA FREBOT
         SEC
         SBC DIST
         STA FREBOT
         STA FIELDP+4
         LDA FREBOT+1
         SBC DIST+1
         STA FREBOT+1
         STA FIELDP+5

         LDY #62          ;Fix markers
:LOOP1B  LDA MARKERS,Y
         CLC
         ADC BFIELD1
         STA MARKERS,Y
         LDA MARKERS+1,Y
         ADC BFIELD1+1
         STA MARKERS+1,Y
         DEY
         DEY
         BPL :LOOP1B

         LDA ENDFIELD
         STA CODEP        ;Temp pointer
         LDA ENDFIELD+1
         STA CODEP+1

:LOOP2B  LDA CODEP
         CMP FREBOT
         LDA CODEP+1
         SBC FREBOT+1
         BCS :DONE2B
         LDY #00
:L2B     LDA (CODEP),Y
         CLC
         ADC BFIELD1
         STA (CODEP),Y
         INY
         LDA (CODEP),Y
         ADC BFIELD1+1
         STA (CODEP),Y
         INY
         CPY #4
         BCC :L2B

         LDA CODEP
         CLC
         ADC #12
         STA CODEP
         BCC :LOOP2B
         INC CODEP+1
         BNE :LOOP2B
:DONE2B  

         LDY #5           ;Fix up player stuff
:L4      LDA BFIELD1,Y
         STA FIELDS,Y
         DEY
         BPL :L4

         LDA ENDFIELD
         STA FIELDP+2     ;Player, $0FE2
         LDA ENDFIELD+1
         STA FIELDP+3
         JSR MUSINIT      ;Reset music ed pointers

:RET     LDX #24
         LDY #00
         CLC
         JSR PLOT
         JSR STROUT
         TXT '(return)',00
         LDX #00
         JSR INPUT
         LDA #147
         JMP CHROUT
