base:reading_the_error_channel_of_a_disk_drive
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
base:reading_the_error_channel_of_a_disk_drive [2014-07-19 13:41] – graham | base: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: | ||
+ | < | ||
+ | 10 OPEN 15,8,15 | ||
+ | 20 INPUT# | ||
+ | 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# | ||
+ | 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 | ||
+ | |||
+ | 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 | ||
+ | </ | ||
+ | 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/ | ||
+ | < | ||
+ | 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 | ||
+ | |||
+ | 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 | ||
+ | </ | ||