; From: Sacred Armour of Antiriad, The ; Note: Assemble with 64tass ; ************** ; * CBM Header * ; ************** *=$0351 .byte $24 BOOT LDA #$08 STA $0288 LDA #$EA STA $0328 LDA #$03 STA T033C LDA #<$03E0 ; Override Load address in cassette buffer STA T033D LDA #>$03E0 STA T033E LDA #<$0586 ; Override End address in cassette buffer STA T033F LDA #>$0586 STA T0340 LDX #$03 ; Select a DATA block JSR $F564 ; Load a DATA block using the above overrides JMP J03E0 ; Execute the newly loaded code ; Unused incomplete copy of the orchestrator's code ; As the whole orchestrator does not fit in the cassette buffer, the full version ; is loaded from a second file, along with the main loader, and stored at $03E0 SEI LDA $D011 ; VIC-II Vertical Fine Scrolling and Control Register AND #$EF STA $D011 ; VIC-II Vertical Fine Scrolling and Control Register LDA $DD02 ; CIA #2 Data Direction Register A ORA #$03 STA $DD02 ; CIA #2 Data Direction Register A LDA $DD00 ; CIA #2 Data Port A AND #$FC ORA #$02 STA $DD00 ; CIA #2 Data Port A LDA #$00 LDA $D018 ; VIC-II Memory Control Register LDA #$00 STA $0080 LDA #$10 STA $0081 LDA #$09 STA $0101 JSR S047F LDA #$00 STA $00FB STA $00FD STA $01 LDA #$10 STA $00FC LDA #$D0 STA $00FE LDX #$08 B03C5 LDY #$00 LDA ($FB),Y STA ($FD),Y INY BNE *-5 INC $00FC INC $00FE DEX BPL B03C5 LDA #$05 STA $01 LDA #$A0 STA $0080 J03E0 LDA #$06 STA $0081 LDA #$7B STA $0101 JSR S047F LDA #$00 STA $0080 LDA #$80 STA $0081 LDA #$4F STA $0101 ; *************** ; * CBM Data #1 * ; *************** *=$02A7 ; Overwrite BASIC vectors in RAM for autostarting .align $0300, $00 .word $E38B ; Leave IERROR unchanged .word BOOT ; Autostart the turbo loader, once loaded, by overwriting IMAIN ; *************** ; * CBM Data #2 * ; *************** *=$03E0 ; Load orchestrator: provides the loader with details of files to load and actions ; to perform once each is loaded SEI LDA $D011 ; VIC-II Vertical Fine Scrolling and Control Register AND #$EF STA $D011 ; VIC-II Vertical Fine Scrolling and Control Register LDA $DD02 ; CIA #2 Data Direction Register A ORA #$03 STA $DD02 ; CIA #2 Data Direction Register A LDA $DD00 ; CIA #2 Data Port A AND #$FC ORA #$02 STA $DD00 ; CIA #2 Data Port A LDA #$00 LDA $D018 ; VIC-II Memory Control Register LDA #$00 ; Set Load address STA $0080 LDA #$10 STA $0081 LDA #$09 ; Set number of sub-blocks STA $0101 JSR S047F ; Load turbo file LDA #$00 ; Copy 9 pages from $1000 to $D000 STA $00FB STA $00FD STA $01 LDA #$10 STA $00FC LDA #$D0 STA $00FE LDX #$08 B0428 LDY #$00 LDA ($FB),Y STA ($FD),Y INY BNE *-5 INC $00FC INC $00FE DEX BPL B0428 LDA #$05 STA $01 LDA #$A0 ; Set Load address STA $0080 LDA #$06 STA $0081 LDA #$7B ; Set number of sub-blocks STA $0101 JSR S047F ; Load turbo file LDA #$00 ; Set Load address STA $0080 LDA #$80 STA $0081 LDA #$4F ; Set number of sub-blocks STA $0101 JSR S047F ; Load turbo file LDA #$00 ; Set Load address STA $0080 LDA #$E0 STA $0081 LDA #$20 ; Set number of sub-blocks STA $0101 JSR S047F ; Load turbo file LDA $D011 ; VIC-II Vertical Fine Scrolling and Control Register ORA #$10 STA $D011 ; VIC-II Vertical Fine Scrolling and Control Register JMP $8009 ; Start game ; -------------------------------- ; Core loader (in video RAM) S047F LDA #$04 STA $0103 ; Initialise for 4-byte signatures SEI LDA #$00 STA $D015 ; VIC-II Sprite Enable Register STA $D020 ; VIC-II Border Color Register JSR S0571 ; Loop until a datassette key is pressed JSR S057F ; Turn datassette motor on JSR S053E ; Delay loop JSR S053E ; Delay loop JSR S04AD ; Sync with the start of file data JSR S04CF ; Load turbo file LDX #$00 JSR S053E ; Delay loop JSR S0578 ; Turn the datassette motor off LDA #$00 STA $D020 ; VIC-II Border Color Register RTS ; -------------------------------- ; Sync with the start of file data ; Byte-align with the incoming stream by shifting bits in until the first pilot byte is read S04AD JSR S0521 ; Read a bit BCC S04AD ; Loop until it is bit 1 ; Read at least 15 pilot bytes LDY #$0F ; Expect at least 15 pilot bytes JSR S050D ; Read a byte CMP #$01 ; Pilot byte? BNE S04AD DEY BNE *-8 ; Check that the block signature is as expected LDY #$00 B04C0 JSR S050D ; Read a byte CMP T054C,Y ; Compare with the expected signature byte BNE *-8 INY CPY $0103 BCC B04C0 RTS ; -------------------------------- ; Load and validate all sub-blocks S04CF LDY #$00 STY T0547+4 ; Initialise sub-block ID ; Check that the sub-block signature is as expected B04D4 JSR S050D ; Read a byte CMP T0547,Y BNE B04D4 INY CPY #$05 BCC B04D4 ; Load current sub-block into RAM LDY #$00 STY $0100 ; Zero sub-block checkbyte B04E6 JSR S050D ; Read a byte STA ($80),Y ; Store in RAM EOR $0100 STA $0100 ; Update checkbyte value INY BNE B04E6 ; Loop until a whole sub-block is done JSR S050D ; Load checkbyte CMP $0100 ; Compare with calculated one BNE B055A ; Invoke a soft-reset if they don't match JSR S050D ; Load an extra byte (and ignore it) INC $0081 ; Bump MSB of destination address INC T0547+4 ; Bump ID for next sub-block DEC $0101 ; Decrease the number of sub-blocks to load BNE B04D4 ; Loop unless all were loaded LDX #$00 RTS ; -------------------------------- ; Read byte: read 8 bits from tape, grouping them MSbF ; ; Returns: the read byte in A S050D LDX #$01 STX $0102 JSR S0521 ; Load a bit ROL $0102 ; Shift bit into byte storage, MSbF BCC *-6 INC $D020 ; VIC-II Border Color Register LDA $0102 RTS ; -------------------------------- ; Read bit: loops until a falling edge is received on the read line and uses ; the read bit timer/counter to discriminate the current bit value ; ; Returns: the read bit in the Carry flag S0521 LDX #$FF LDA #$10 INX ; Bump bit duration counter BIT $DC0D BEQ *-4 ; Loop unless an edge was received CPX #$28 ; Compare counter to the threshold value JMP J0530 ; Perform an inter-bit delay and return with bit in C J0530 PHP PHA TXA PHA LDX #$08 DEX BPL *-1 PLA TAX PLA PLP RTS ; -------------------------------- ; Delay loop S053E LDY #$00 INY BNE *-1 INX BNE *-4 RTS ; -------------------------------- ; Sub-block signature (last value is incremental) T0547 .byte $4A,$50,$47,$10,$00 ; "JPGp_" ; -------------------------------- ; Block signature T054C .byte $4A,$50,$47,$29 ; "JPG)" ; -------------------------------- ; Padding T0550 .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; -------------------------------- ; Soft-reset in case of load error B055A JSR S0578 ; Datassette motor off LDA #$00 ; Zero start vectors and autostart key TAX STA $8000,X DEX BNE *-4 LDA #$2F STA $00 ; Restore default DDR value LDA #$27 STA $01 ; Restore default $01 value JMP $FCE2 ; Reset ; -------------------------------- ; Loop until a datassette key is pressed S0571 LDA #$10 BIT $01 BNE S0571 RTS ; -------------------------------- ; Turn the datassette motor off S0578 LDA $01 ORA #$20 STA $01 RTS ; -------------------------------- ; Turn the datassette motor on S057F LDA $01 AND #$1F STA $01 RTS