145 lines
3.7 KiB
ArmAsm
145 lines
3.7 KiB
ArmAsm
//
|
|
// Official Kernal routine, described in:
|
|
//
|
|
// - [RG64] C64 Programmer's Reference Guide - page 286
|
|
// - [CM64] Compute's Mapping the Commodore 64 - page 231
|
|
// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
|
//
|
|
// CPU registers that has to be preserved (see [RG64]): none
|
|
//
|
|
|
|
|
|
// Expects that SETLFS and SETNAM are called before hand.
|
|
// $YYXX = load address.
|
|
// (ignored if SETLFS channel = 1, i.e., like ,8,1)
|
|
// If A=1 then VERIFY instead of LOAD.
|
|
// On exit, $YYXX is the highest address into which data
|
|
// will have been placed.
|
|
|
|
// XXX honor MSGFLG bit 6
|
|
// XXX add VERIFY support
|
|
|
|
LOAD:
|
|
|
|
// Are we loading or verifying?
|
|
sta VERCKK
|
|
|
|
// Store start address of LOAD
|
|
stx STAL+0
|
|
sty STAL+1
|
|
|
|
// Reset status
|
|
jsr kernalstatus_reset
|
|
|
|
#if CONFIG_MEMORY_MODEL_60K
|
|
// We need our helpers to get to filenames under ROMs or IO area
|
|
jsr install_ram_routines
|
|
#endif
|
|
|
|
// Check whether we support the requested device
|
|
lda FA
|
|
and #$FC
|
|
bne !+
|
|
jmp lvs_illegal_device_number // device number below 4, not an IEC device
|
|
!:
|
|
// Device numbers above 30 are also illegal (see https://www.pagetable.com/?p=1031),
|
|
// as the protocol combines device number with command code int one byte,
|
|
// above 30 it is no longer possible (UNLISTEN and UNTALK codes prevent using
|
|
// number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only
|
|
// for devices 0-3; in our implementation LISTEN / TALK will cause device
|
|
// not present detected for numbers above 30
|
|
|
|
// Display SEARCHING FOR + filename
|
|
jsr lvs_display_searching_for
|
|
|
|
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
|
// p13, 16; also p16 tells us this routine doesn't mess with the file table
|
|
// in the C64, only in the drive.
|
|
|
|
// Call device to LISTEN (p16)
|
|
lda FA
|
|
jsr LISTEN
|
|
bcc !+
|
|
jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
// Open channel 0 (reserved for file reading)
|
|
lda #$00
|
|
jsr iec_cmd_open
|
|
bcc !+
|
|
jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
// Send file name
|
|
jsr lvs_send_file_name
|
|
bcc !+
|
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
// Now command device to talk (p16)
|
|
lda FA
|
|
jsr TALK
|
|
bcc !+
|
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
lda #$60 // open channel / data (p3) , required according to p13
|
|
sta TBTCNT
|
|
jsr iec_tx_command
|
|
bcc !+
|
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
// We are currently talker, so do the IEC turn around so that we
|
|
// are the listener (p16)
|
|
jsr iec_turnaround_to_listen
|
|
bcc !+
|
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
// Get load address and store it if secondary address is zero
|
|
jsr iec_rx_byte
|
|
bcc !+
|
|
jmp kernalerror_FILE_NOT_FOUND // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
ldx SA
|
|
beq !+
|
|
sta STAL+0
|
|
!:
|
|
jsr iec_rx_byte
|
|
bcc !+
|
|
jmp kernalerror_FILE_NOT_FOUND // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
ldx SA
|
|
beq !+
|
|
sta STAL+1
|
|
!:
|
|
// Display start address
|
|
jsr lvs_display_loading_verifying
|
|
|
|
load_loop:
|
|
// We are now ready to receive bytes
|
|
jsr iec_rx_byte
|
|
bcc !+
|
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
// Handle the byte (store in memory / verify)
|
|
jsr lvs_handle_byte_load_verify
|
|
bcc !+
|
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
|
!:
|
|
// Advance pointer to data
|
|
jsr lvs_advance_pointer
|
|
bcc !+
|
|
jmp lvs_wrap_around_error
|
|
!:
|
|
// Check for EOI - if so, this was the last byte
|
|
lda IOSTATUS
|
|
and #K_STS_EOI
|
|
beq load_loop
|
|
|
|
// Display end address
|
|
jsr lvs_display_done
|
|
|
|
// Close file on drive
|
|
|
|
lda FA
|
|
jsr close_load
|
|
|
|
// Return last address
|
|
jmp lvs_return_last_address
|