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: