User Tools

Site Tools


base:reading_the_error_channel_of_a_disk_drive

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
base:reading_the_error_channel_of_a_disk_drive [2014-07-19 13:05] grahambase:reading_the_error_channel_of_a_disk_drive [2015-04-17 04:33] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +====== 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:
 +<code>
 +10 OPEN 15,8,15
 +20 INPUT#15,F,E$,T,S
 +30 PRINT F;E$;T;S
 +40 CLOSE 15
 +</code>
 +BASIC code similar to the assembler code:
 +<code>
 +10 OPEN 15,8,15
 +20 IF ST<>0 THEN GOTO 40
 +30 GET#15,A$:PRINT A$;:GOTO 20
 +40 CLOSE 15
 +</code>
 +Assembler:
 +<code>
 +        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
 +</code>
 +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:
 +<code>
 +        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
 +</code>