;-----------------------------------------------------------------------------
;
; FREELOAD Cassette multi load program
;
; Version 5.0 (252 bytes)
;
; (c) Paul Hughes 01.01.1989
;
; This is the new standard multi load routine
;
; Ported to DASM 9/11/04 by Paulie
;
;-----------------------------------------------------------------------------

; To use
;
;  JSR INIT_TURBO  ;to initialise the loader (blanks the screen)
;  LDY #NN         ;where NN equals the number of files to load
;  JSR TURBO_LOAD  ;this loads in NN number of files (and unblanks the screen)
; .....            ;the rest of your program

;-----------------------------------------------------------------------------

	processor 6502

;-----------------------------------------------------------------------------
;
; Constants
;

HEADER_BYTE    EQU $40                  ;header byte value
HEADER_END     EQU $5A                  ;header end byte value

;-----------------------------------------------------------------------------
;
;VARIABLES - Variables used by cassette loader, MUST follow contiguously
;

	seg.u data

ZP             EQU $20
               ORG ZP

LOAD_ADDR      dc.w 0                    ;loader data start
LOAD_END       dc.w 0                    ;loader data end
VERIFY         dc.b 0                    ;saved checksum
CHECKSUM       dc.b 0                    ;checksum value
BIT_COUNT      dc.b 0                    ;bit store
LOAD_FLAG      dc.b 0                    ;loader monitor flag

;-----------------------------------------------------------------------------
;
; Little test program.
;

		seg code

               ORG $C000                ;Or wherever !

               JSR INIT_TURBO
               LDY #2
               JSR TURBO_LOAD

               INC $D020
               JMP .-3

;-----------------------------------------------------------------------------
;
; INIT_TURBO - Initialises Freeload
;

INIT_TURBO     SEI
               LDA #0
               STA LOAD_FLAG            ;reset load flag
               STA BIT_COUNT            ;reset bit count
               STA $D01A                ;halt rasters
               LDA #$0F
               STA $D019                ;halt NMI's
               LDA #$7F                 ;latch interrupts
               STA $DC0D
               STA $DD0D
               LDA $DC0D                ;unlatch interrupts
               LDA $DD0D

               LDA #5                   ;ROMS's out cassette motor on
               STA 1

               LDA #<$0368
               STA $DC04                ;set CIA #1 Timer A countdown time
               LDA #>$0368
               STA $DC05

               LDA #$90
               STA $DC0D

               LDA #<LOADER_IRQ
               STA $FFFE                ;point the interrupt vector to loader
               LDA #>LOADER_IRQ
               STA $FFFF

               LDA #$0B
               STA $D011                ;screen off
               CLI
               RTS                      ;exit

;-----------------------------------------------------------------------------
;
; TURBO_LOAD - Entered with "Y" equals number of files to load
;

TURBO_LOAD     LDX LOAD_FLAG            ;wait for nonzero loadflag value
               BEQ TURBO_LOAD
               INX                      ;reset loadflag
               STX LOAD_FLAG
               DEY                      ;get next file
               BNE TURBO_LOAD

               SEI
               LDA #$35                 ;motor off, ROMS out
               STA 1
               LDA #$7F                 ;unlatch interrupts
               STA $DC0D
               STA $DD0D
               LDA $DC0D
               LDA $DD0D

               LDA #0                   ;reset border colour
               STA $D020
               LDA #$1B
               STA $D011                ;screen on
               RTS

;-----------------------------------------------------------------------------
;
; LOADER_IRQ - All data is recieved through here
;

LOADER_IRQ     PHA
               TYA
               PHA

               LDA $D020                ;flash the border
               EOR #5
               STA $D020

               LDA $DC05
               LDY #$19                 ;trigger the counters
               STY $DC0E
               EOR #2
               LSR
               LSR                      ;shift in a BIT
               ROL BIT_COUNT            ;until dummy bit 7 gets shifted out
               LDA BIT_COUNT
BRANCH_MOD_1   BCC WAIT_HEADER          ;self modified branch
REFERENCE      BCS EXIT
WAIT_HEADER    CMP #HEADER_BYTE         ;is it a Header ?
               BNE EXIT
               LDA #HEADER_CHECK-REFERENCE
               STA BRANCH_MOD_1+1

SET_AND_EXIT   LDA #%11111110           ;init bit counter for the next 8
               STA BIT_COUNT
EXIT           LDA $DC0D                ;acknowledge NMI
               PLA
               TAY
               PLA
               RTI                      ;return

;----

HEADER_CHECK   CMP #HEADER_BYTE
               BEQ SET_AND_EXIT         ;confirmed Header Byte
               CMP #HEADER_END          ;is it a Header END marker ?
               BEQ CLEAR_CHECKSUM       ;yes it is
               BNE SET_HEADER

;----

CLEAR_CHECKSUM LDA #SET_LOAD_ADDR-REFERENCE
               STA BRANCH_MOD_1+1
               LDA #0                   ;clear the checksum
               STA CHECKSUM
               BEQ SET_AND_EXIT         ;branch always !

;----

SET_LOAD_ADDR  STA LOAD_ADDR            ;store start Address
               INC SET_LOAD_ADDR+1      ;and end address
               LDA SET_LOAD_ADDR+1
               CMP #LOAD_ADDR+4
               BNE SET_AND_EXIT
               LDA #STORE_BYTE-REFERENCE
               STA BRANCH_MOD_1+1
               BNE SET_AND_EXIT         ;branch always !

;----

STORE_BYTE     LDY #0
               DEC 1                    ;page $D0 enabled
               STA (LOAD_ADDR),Y        ;Store recieved BYTE
               INC 1                    ;page $D0 disabled

               EOR CHECKSUM
               STA CHECKSUM             ;store Checksum

               INC LOAD_ADDR            ;bump the LOAD ADDRESS COUNTER
               BNE NO_CARRY
               INC LOAD_ADDR+1
               INC $D020

NO_CARRY       LDA LOAD_ADDR            ;have we finished yet ?
               CMP LOAD_END
               LDA LOAD_ADDR+1
               SBC LOAD_END+1
               BCC SET_AND_EXIT         ;no

               LDA #LOAD_COMPLETE-REFERENCE
               STA BRANCH_MOD_1+1
               BNE SET_AND_EXIT         ;branch always !

;----

LOAD_COMPLETE  STA VERIFY               ;store the verify BYTE
               LDA #$FF                 ;signal to FREELOAD that a load
               STA LOAD_FLAG            ;has completed
               LDA #LOAD_ADDR
               STA SET_LOAD_ADDR+1      ;reset low byte of load address

SET_HEADER     LDA #WAIT_HEADER-REFERENCE
               STA BRANCH_MOD_1+1       ;reset ready for the next file
               BNE SET_AND_EXIT         ;branch always !
AA


;
; Finito, all is now done ...... Sleep !
;

; **************  END OF LOADER **********************



