From 2613553ef33ecf445324bd706309b4e7f8b93c63 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sat, 20 Jul 2019 16:30:58 +0200 Subject: [PATCH] added full protection against illegal IEC device numbers --- c64/kernal/iec_devnum_check.s | 24 ++++++++++++++++++++++++ c64/kernal/listen.s | 5 ++++- c64/kernal/load.s | 12 ++++++++++++ c64/kernal/lvs_helpers.s | 5 +++++ c64/kernal/talk.s | 5 ++++- 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 c64/kernal/iec_devnum_check.s diff --git a/c64/kernal/iec_devnum_check.s b/c64/kernal/iec_devnum_check.s new file mode 100644 index 00000000..8fffb64e --- /dev/null +++ b/c64/kernal/iec_devnum_check.s @@ -0,0 +1,24 @@ + +;; +;; Checks whether device numbe (in .A) is a correct IEC device number +;; +;; Preserves .A, .X and .Y +;; + +iec_devnum_check: + ;; 0, 1, 2, or 3 are illegal - reserved for non-IEC devices on Commodore + cmp #$03 + bpl + + bcs + + ;; FALLTROUGH +iec_devnum_check_failed: + sec + rts +* + ;; 30 and above are illegal too, due to IEC command encoding scheme, + ;; see https://www.pagetable.com/?p=1031 + cmp #$1E + bpl iec_devnum_check_failed + bcs iec_devnum_check_failed + clc + rts diff --git a/c64/kernal/listen.s b/c64/kernal/listen.s index 7f71c941..5e2c1bd1 100644 --- a/c64/kernal/listen.s +++ b/c64/kernal/listen.s @@ -12,7 +12,10 @@ listen: - and #$1F ; make sure bits encoding the command are cleared out + ;; First check whether device number is correct + jsr iec_devnum_check + bcs kernalerror_DEVICE_NOT_FOUND + ;; Encode and execute the command ora #$20 sta BSOUR jmp iec_tx_command diff --git a/c64/kernal/load.s b/c64/kernal/load.s index 131e987f..4a946263 100644 --- a/c64/kernal/load.s +++ b/c64/kernal/load.s @@ -38,6 +38,18 @@ load: ;; Allow platform-specific routine to takeover the flow `PLATFORM_HOOK_LOAD + ;; Check whether we support the requested device + lda current_device_number + and #$FC + beq 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 diff --git a/c64/kernal/lvs_helpers.s b/c64/kernal/lvs_helpers.s index 85329bf9..e39bb15e 100644 --- a/c64/kernal/lvs_helpers.s +++ b/c64/kernal/lvs_helpers.s @@ -114,6 +114,11 @@ lvs_device_not_found_error: jsr kernalstatus_DEVICE_NOT_FOUND jmp kernalerror_DEVICE_NOT_FOUND +lvs_illegal_device_number: + + jsr kernalstatus_DEVICE_NOT_FOUND + jmp kernalerror_ILLEGAL_DEVICE_NUMBER + .alias lvs_file_not_found_error kernalerror_FILE_NOT_FOUND lvs_load_verify_error: diff --git a/c64/kernal/talk.s b/c64/kernal/talk.s index 67a87bd9..3952ed0c 100644 --- a/c64/kernal/talk.s +++ b/c64/kernal/talk.s @@ -14,7 +14,10 @@ talk: - and #$1F ; make sure bits encoding the command are cleared out + ;; First check whether device number is correct + jsr iec_devnum_check + bcs kernalerror_DEVICE_NOT_FOUND + ;; Encode and execute the command ora #$40 sta BSOUR jmp iec_tx_command