User Tools

Site Tools


base:reading_a_sector_from_disk

Reading a sector from disk

For reading a sector from disk, the Commodore DOS offers the block read command. Due to heavy bugs in the B-R command, Commodore has sacrificed one of the user commands as a bugfix replacement. So instead of B-R you simply use U1.

The format of this DOS command is: “U1 <channel> <drive> <track> <sector>”

The drive parameter is only used for dual disk drives, so for all common C64/C128/C16 drives this parameter will always be 0.

Parameters track and sector explain themselves. They are sent in PETSCII format, so in assembler often a binary to PETSCII conversion is needed.

A speciality of this command is the channel parameter. Actually you can't simply send this command to the drive and then start to receive sector bytes. For the receiving of the bytes you have to open another file which is adressed by this parameter.

BASIC code:

10 SA=8192
20 OPEN 2,8,2,"#"
30 OPEN 15,8,15,"U1 2 0 18 0"
40 FOR I=0 TO 255
50 GET#2,A$:IF A$="" THEN A$=CHR$(0)
60 POKE SA,ASC(A$):SA=SA+1
70 NEXT I
80 CLOSE 15:CLOSE 2

Assembler code:

sector_address = $2000  ; just an example

        ; open the channel file

        LDA #cname_end-cname
        LDX #<cname
        LDY #>cname
        JSR $FFBD     ; call SETNAM

        LDA #$02      ; file number 2
        LDX $BA       ; last used device number
        BNE .skip
        LDX #$08      ; default to device 8
.skip   LDY #$02      ; secondary address 2
        JSR $FFBA     ; call SETLFS

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

        ; open the command channel

        LDA #uname_end-uname
        LDX #<uname
        LDY #>uname
        JSR $FFBD     ; call SETNAM
        LDA #$0F      ; file number 15
        LDX $BA       ; last used device number
        LDY #$0F      ; secondary address 15
        JSR $FFBA     ; call SETLFS

        JSR $FFC0     ; call OPEN (open command channel and send U1 command)
        BCS .error    ; if carry set, the file could not be opened

        ; check drive error channel here to test for
        ; FILE NOT FOUND error etc.

        LDX #$02      ; filenumber 2
        JSR $FFC6     ; call CHKIN (file 2 now used as input)

        LDA #<sector_address
        STA $AE
        LDA #>sector_address
        STA $AF

        LDY #$00
.loop   JSR $FFCF     ; call CHRIN (get a byte from file)
        STA ($AE),Y   ; write byte to memory
        INY
        BNE .loop     ; next byte, end when 256 bytes are read
.close
        LDA #$0F      ; filenumber 15
        JSR $FFC3     ; call CLOSE

        LDA #$02      ; filenumber 2
        JSR $FFC3     ; call CLOSE

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

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

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

cname:  .TEXT "#"
cname_end:

uname:  .TEXT "U1 2 0 18 0"
uname_end:
base/reading_a_sector_from_disk.txt · Last modified: 2015-04-17 04:33 (external edit)