         .TITLE "SPY 1.0"
;
; SPYCORE 1.0
; -----------
;
         JSR SAVEPROG
;
; Set initial Get Sector cmd.
;
BEGIN
         JSR SETCMD
READSEC
         JSR SIOV
;
; Another sector to read ?
;
         INC DAUX1
         LDA DAUX1
         CMP # <LASTSEC
         BEQ PRGDISK
;
; Update Get Sector command for
; the next sector
;
         LDA DBUFLO
         CLC 
         ADC #$80
         STA DBUFLO
         LDA DBUFHI
         ADC #$00
         STA DBUFHI
         LDA #$40
         STA DSTATS
         BNE READSEC
;
; Display title and prompt user
; to insert his program disk
;
PRGDISK
;
; Was it Spy disk ?
;
         JSR CHKMAGIC
         BCC STARTKEY
         JSR WAITSTART
         JMP BEGIN
;
; It was Spy disk !
; Now, ask for boot disk.
;
STARTKEY
         JSR BOOTPROMPT
         JSR WAITSTART
         JSR RESTPROG
;
; Load boot sector of prg disk
;
         LDA #$01
         STA DAUX1
         LDA #$00
         STA DAUX2
         LDA # <BOOTSEC
         STA DBUFLO
         LDA # >BOOTSEC
         STA DBUFHI
         LDA #$40
         STA DSTATS
         JSR SIOV
;
; Move sector 1 to dest addr
;
         LDA BOOTSEC+2
         STA ZTMP
         LDA BOOTSEC+3
         STA ZTMP+1
         LDY #0
MOVEBCL
         LDA BOOTSEC,Y
         STA (ZTMP),Y
         INY 
         CPY #128
         BNE MOVEBCL
;
; Read other sectors
;
         LDA BOOTSEC+2
         STA DBUFLO
         LDA BOOTSEC+3
         STA DBUFHI
READOTHER
         DEC BOOTSEC+1
         LDA BOOTSEC+1
         BEQ DOPATCH
         LDA DBUFLO
         CLC 
         ADC #$80
         STA DBUFLO
         LDA DBUFHI
         ADC #0
         STA DBUFHI
         INC DAUX1
         LDA #$40
         STA DSTATS
         JSR SIOV
         JMP READOTHER
;
; Make patch to come back into
; SPY after boot has executed.
;
DOPATCH
         LDA #0
         STA CURPATCH
         JSR SETPATCH
;
; Call boot program
;
         LDA BOOTSEC+2
         STA BOOTAD
         LDA BOOTSEC+3
         STA BOOTAD+1
         LDA BOOTSEC+4
         STA DOSINI
         LDA BOOTSEC+5
         STA DOSINI+1
         JSR PUSHRET
         JMP SAVERESULT
PUSHRET
         JMP (DOSINI)
;
; Make a Patch
;
SETPATCH
         LDY CURPATCH
         LDA PATCHADDR,Y
         STA ZTMP
         LDA PATCHADDR+1,Y
         STA ZTMP+1
         BNE PATCHEXIST
         LDA ZTMP
         BNE PATCHEXIST
         SEC 
         RTS 
;
; There is a patch to do
;
PATCHEXIST
         LDY #0
         LDA (ZTMP),Y
         STA SAVPATCH,Y
         LDA #$4C    ; JMP opcode
         STA (ZTMP),Y
         INY 
         LDA (ZTMP),Y
         STA SAVPATCH,Y
         LDA # <SAVERESULT
         STA (ZTMP),Y
         INY 
         LDA (ZTMP),Y
         STA SAVPATCH,Y
         LDA # >SAVERESULT
         STA (ZTMP),Y
         CLC 
         RTS 
;
; Make a Patch
;
UNDOPATCH
         LDY CURPATCH
         LDA PATCHADDR,Y
         STA ZTMP
         STA LASTPATCH
         LDA PATCHADDR+1,Y
         STA ZTMP+1
         STA LASTPATCH+1
         LDY #0
         LDA SAVPATCH,Y
         STA (ZTMP),Y
         INY 
         LDA SAVPATCH,Y
         STA (ZTMP),Y
         INY 
         LDA SAVPATCH,Y
         STA (ZTMP),Y
         INC CURPATCH
         INC CURPATCH
         RTS 
;
; Run program
;
RUNPROG
         LDA LASTPATCH
         STA ZTMP
         LDA LASTPATCH+1
         STA ZTMP+1
         LDX SAVEREGS+1
         LDY SAVEREGS+2
         LDA SAVEREGS+3
         PHA 
         LDA SAVEREGS
         PLP 
         JMP (ZTMP)
;
; Save prog context.
;
SAVEPROG
         JSR SAVECOLOR
         JSR SAVEDLIST
         JSR SETCOLOR
         JSR VBLANK
         JMP SETDLIST
;
; Restore prog context.
;
RESTPROG
         JSR RESTCOLOR
         JSR VBLANK
         JSR RESTDLIST
         JMP VBLANK
;
; Check magic code of spy disk
;
CHKMAGIC
         LDA SPYMAGIC
         CMP #'S
         BNE BADMAGIC
         LDA SPYMAGIC+1
         CMP #'P
         BNE BADMAGIC
         LDA SPYMAGIC+2
         CMP #'Y
         BNE BADMAGIC
         JSR VBLANK
         LDA # <PRGNAME
         STA TITLE
         LDA # >PRGNAME
         STA TITLE+1
         CLC 
         RTS 
BADMAGIC
         SEC 
         RTS 
;
; Ask for Boot disk
;
BOOTPROMPT
         JSR VBLANK
         LDA # <PRGPROMPT
         STA PROMPT
         LDA # >PRGPROMPT
         STA PROMPT+1
         RTS 
;
; Set colors
;
SETCOLOR
         LDY #$00
COLORBCL
         LDA SETCOL,Y
         STA COLOR0,Y
         STA COL0,Y
         INY 
         CPY #5
         BNE COLORBCL
         RTS 
;
; Save program colors
;
SAVECOLOR
         LDY #$00
COLORBCL2
         LDA COLOR0,Y
         STA SAVCOL,Y
         INY 
         CPY #5
         BNE COLORBCL2
         RTS 
;
; Restore program colors
;
RESTCOLOR
         LDY #$00
COLORBCL3
         LDA SAVCOL,Y
         STA COLOR0,Y
         STA COL0,Y
         INY 
         CPY #5
         BNE COLORBCL3
         RTS 
;
; Set Display list to spy
; screen.
;
SETDLIST
         LDA # <DLISTSPY
         STA SDLSTL
         STA DLISTL
         LDA # >DLISTSPY
         STA SDLSTH
         STA DLISTH
         RTS 
;
; Save Display list addr
;
SAVEDLIST
         LDA SDLSTL
         STA SAVDL
         LDA SDLSTH
         STA SAVDL+1
         RTS 
;
; Restore Display list
;
RESTDLIST
         LDA SAVDL
         STA SDLSTL
         STA DLISTL
         LDA SAVDL+1
         STA SDLSTH
         STA DLISTH
         RTS 
;
; Wait for start key
;
WAITSTART
         LDA CONSOL
         CMP #6
         BNE WAITSTART
NOSTART
         LDA CONSOL
         CMP #7
         BNE NOSTART
         RTS 
;
; Fill SIO command
;
SETCMD
         LDY #0
SETCMDBCL
         LDA GETDATA,Y
         STA DDEVIC,Y
         INY 
         CPY #GETLEN
         BNE SETCMDBCL
         RTS 
;
; Wait for Vertical blank
;
VBLANK
         LDA VCOUNT
         CMP #$7A
         BNE VBLANK
         RTS 
;
; Print Patch number
;
PRINTNUM
         LDA CURPATCH
         LSR A
NUMNEXT
         CMP #10
         BMI NUMDIGIT
         SEC 
         SBC #10
         INC PATCHDIGIT
         JMP NUMNEXT
NUMDIGIT
         CLC 
         ADC PATCHDIGIT+1
         STA PATCHDIGIT+1
         LDY #0
NUMBCL
         LDA PATCHNUM,Y
         STA PRGSTATUS,Y
         INY 
         CPY #20
         BNE NUMBCL
         RTS 
;
; Print Wrong Disk
;
PRINTWRONG
         LDY #0
PRINTBCL
         LDA WRONGDISK,Y
         STA PRGSTATUS,Y
         INY 
         CPY #20
         BNE PRINTBCL
         RTS 
;
; Print Error
;
PRINTERROR
         LDY #0
ERRORBCL
         LDA ERRORMSG,Y
         STA PRGSTATUS,Y
         INY 
         CPY #20
         BNE ERRORBCL
         RTS 
;
; Print End
;
PRINTEND
         LDY #0
ENDBCL
         LDA FINISHED,Y
         STA PRGSTATUS,Y
         INY 
         CPY #20
         BNE ENDBCL
         RTS 
;
; Clear status line
;
CLRSTATUS
         LDY #0
         TYA 
CLRBCL
         STA PRGSTATUS,Y
         INY 
         CPY #20
         BNE CLRBCL
         RTS 
;
; Clear prompt line
;
CLRPROMPT
         LDY #0
         TYA 
CLRBCL2
         STA SPYPROMPT,Y
         INY 
         CPY #40
         BNE CLRBCL2
         RTS 
;
; After program execution, we
; should come back here !
; Undo the current patch and
; install next one.
;
SAVERESULT
         PHP 
         STA SAVEREGS
         STX SAVEREGS+1
         STY SAVEREGS+2
         PLA 
         STA SAVEREGS+3
         JSR UNDOPATCH
USERPATCH
         JSR SETPATCH
         BCS NOPATCH
;
; Next patch is installed.
; We must jump to the addr
; where we left off.
;
         JMP RUNPROG
;
; No more patch. It's time
; to save memory on disk.
;
NOPATCH
         JMP USERCONTROL
USEREND
         LDA # <SPYPROMPT
         STA PROMPT
         LDA # >SPYPROMPT
         STA PROMPT+1
         JSR PRINTNUM
         JSR SAVEPROG
;
; Check if SPY disk is inserted
;
CHKSPY
         JSR WAITSTART
         JSR CLRSTATUS
         JSR SETCMD
         LDA # <CHKPATCH
         STA DBUFLO
         LDA # >CHKPATCH
         STA DBUFHI
         JSR SIOV
         LDY #0
CHKBCL
         LDA CHKPATCH,Y
         CMP PATCHDATA,Y
         BNE BADDISK
         INY 
         CPY #128
         BNE CHKBCL
         BEQ GOODDISK
;
; This is not spy disk !
;
BADDISK
         JSR PRINTWRONG
         JMP CHKSPY
;
; Write data to SPY disk.
;
GOODDISK
         JSR CLRPROMPT
         LDY #0
SETPUT
         LDA PUTDATA,Y
         STA DDEVIC,Y
         INY 
         CPY #PUTLEN
         BNE SETPUT
         LDA # <MEMADDR
         STA ZTMP
         LDA # >MEMADDR
         STA ZTMP+1
         LDA # <MEMSECTOR
         STA ZTMP+2
         LDA # >MEMSECTOR
         STA ZTMP+3
         LDY #0
PUTBCL
         LDA (ZTMP),Y
         STA DBUFLO
         LDA (ZTMP+2),Y
         STA DAUX1
         INY 
         LDA (ZTMP),Y
         STA DBUFHI
         LDA (ZTMP+2),Y
         STA DAUX2
         INY 
         CPY #254
         BEQ SPYEND
         LDA DAUX1
         BNE DOPUT
         LDA DAUX2
         BEQ SPYEND
DOPUT
         LDA #$80
         STA DSTATS
         STY CURINDEX
         JSR SIOV
         BMI ERROR
         LDY CURINDEX
         JMP PUTBCL
;
; An error occured while writing
;
ERROR
         JSR PRINTERROR
         JMP STOP
;
; Finished !
;
SPYEND
         JSR PRINTEND
         LDA PATCHDATA
         BEQ STOP
;
; Continue program.
;
         JSR BOOTPROMPT
         JSR WAITSTART
         JSR RESTPROG
         JMP RUNPROG
;
; Freeze Atari.
;
STOP     JMP STOP
;
; SAVE #D:SPYCORE.M65
