User Tools

Site Tools


base:reading_the_error_channel_of_a_disk_drive

Reading the error channel of a disk drive

A simple example on how to read the error channel of a disk drive and print the error string to screen.

The error string has a very simple format: error number, error string, track, sector

A small warning: Both the BASIC and the Assembler versions will deadlock if the device is not present.

Examples:

00, OK,00,00 (no error)

21, READ ERROR,18,00 (read error on track 18, sector 0)

BASIC code like you should do it in BASIC:

10 OPEN 15,8,15
20 INPUT#15,F,E$,T,S
30 PRINT F;E$;T;S
40 CLOSE 15

BASIC code similar to the assembler code:

10 OPEN 15,8,15
20 IF ST<>0 THEN GOTO 40
30 GET#15,A$:PRINT A$;:GOTO 20
40 CLOSE 15

Assembler:

        LDA #$00      ; no filename
        LDX #$00
        LDY #$00
        JSR $FFBD     ; call SETNAM

        LDA #$0F      ; file number 15
        LDX $BA       ; last used device number
        BNE .skip
        LDX #$08      ; default to device 8
.skip   LDY #$0F      ; secondary address 15 (error channel)
        JSR $FFBA     ; call SETLFS

        JSR $FFC0     ; call OPEN
        BCS .error    ; if carry set, the file could not be opened

        LDX #$0F      ; filenumber 15
        JSR $FFC6     ; call CHKIN (file 15 now used as input)

.loop   JSR $FFB7     ; call READST (read status byte)
        BNE .eof      ; either EOF or read error
        JSR $FFCF     ; call CHRIN (get a byte from file)
        JSR $FFD2     ; call CHROUT (print byte to screen)
        JMP .loop     ; next byte

.eof
.close
        LDA #$0F      ; filenumber 15
        JSR $FFC3     ; call CLOSE

        JSR $FFCC     ; call CLRCHN
        RTS
.error
        ; Akkumulator contains BASIC error code

        ; most likely error:
        ; A = $05 (DEVICE NOT PRESENT)

        ... error handling for open errors ...
        JMP .close    ; even if OPEN failed, the file has to be closed

There is an easier method to read the error channel of a drive by avoiding the Kernal file API. This will limit you to IEC-bus devices but allows you to avoid the deadlock if a device is not present. In this version the status-byte is accessed directly which reduces the portability of the code. The LISTEN/SECLSN/UNLSN sequence is needed to detect the drive without deadlock:

        LDA #$00
        STA $90       ; clear STATUS flags

        LDA $BA       ; device number
        JSR $FFB1     ; call LISTEN
        LDA #$6F      ; secondary address 15 (command channel)
        JSR $FF93     ; call SECLSN (SECOND)
        JSR $FFAE     ; call UNLSN
        LDA $90       ; get STATUS flags
        BNE .devnp    ; device not present

        LDA $BA       ; device number
        JSR $FFB4     ; call TALK
        LDA #$6F      ; secondary address 15 (error channel)
        JSR $FF96     ; call SECTLK (TKSA)

.loop   LDA $90       ; get STATUS flags
        BNE .eof      ; either EOF or error
        JSR $FFA5     ; call IECIN (get byte from IEC bus)
        JSR $FFD2     ; call CHROUT (print byte to screen)
        JMP .loop     ; next byte
.eof
        JSR $FFAB     ; call UNTLK
        RTS
.devnp
        ... device not present handling ...
        RTS
base/reading_the_error_channel_of_a_disk_drive.txt · Last modified: 2015-04-17 04:33 (external edit)