Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

9.1KB


name: disk-io-1541 description: > Use this skill for all 1541 disk drive programming on the Commodore 64. Covers DOS commands, file types (sequential, relative, program), direct access, error handling, the BAM, directory structure, and disk utilities. Sources: The Anatomy of the 1541 Disk Drive (Revised Edition), COMPUTE!‘s Mapping the C64.

1541 Disk Drive Programming

Overview

The VIC-1541 disk drive is a single-sided, single-density (SS/SD) 5.25” floppy drive connected to the C64 via the serial bus (IEC bus). It contains its own 6502 CPU and 2KB of RAM.

  • Device number: Default 8 (configurable 8-11)
  • Disk capacity: 170KB (664 blocks free on a formatted disk)
  • Tracks: 35 (numbered 1-35)
  • Sectors per track: 17-21 (varies by zone)
  • Block size: 254 usable bytes per sector (2 bytes used as track/sector link)
  • Communication: Via Kernal's serial bus routines

Track/Sector Layout

Tracks Sectors/Track Cumulative Sectors
1-17 21 0-356
18-24 19 357-490
25-30 18 491-598
31-35 17 599-682
  • Directory track: Track 18 (always)
  • BAM: Track 18, Sector 0

Logical File Model

Every disk operation goes through logical files. The steps are:

  1. SETLFS — assign logical file number, device, secondary address
  2. SETNAM — assign filename
  3. OPEN — open the file
  4. CHKIN/CHKOUT — redirect input/output to the file
  5. BASIN/BSOUT — read/write data
  6. CLOSE — close the file

From BASIC, use: OPEN LFN, DEV, SA, "FILENAME"


File Types

Type SA Range Description
Program 0-1 Machine language or BASIC programs
Sequential 2 Sequential data files (read/write, not both at once)
Relative any+SA Fixed-length record random-access files
Command 15 Command channel (send DOS commands, read error)

BASIC Disk Operations

Load and Save Programs

LOAD "FILENAME",8         ' Load BASIC program
LOAD "FILENAME",8,1       ' Load at original address (ML programs)
SAVE "FILENAME",8         ' Save BASIC program
SAVE "@:FILENAME",8       ' Save and overwrite existing file
VERIFY "FILENAME",8       ' Verify saved file matches memory

Directory

LOAD "$",8               ' Load directory as BASIC program
LIST                     ' Display directory

Sending DOS Commands

OPEN 15,8,15,"COMMAND"  ' Open command channel with command
CLOSE 15                 ' Close command channel

Reading the Error Channel

10 OPEN 15,8,15          : REM Open command channel
20 INPUT#15,EN,EM$,ET,ES : REM Read error: number,message,track,sector
30 PRINT EN;EM$;ET;ES
40 CLOSE 15

The error channel should be read after every disk operation.


DOS Commands

Formatting

OPEN 15,8,15,"N0:DISKNAME,ID" : CLOSE 15
' N0: = NEW on drive 0; ID = 2-char disk ID (e.g., "A1")
' WARNING: Destroys all data on disk

Scratching (Deleting) Files

OPEN 15,8,15,"S0:FILENAME" : CLOSE 15
' Wildcards supported: S0:TEST* deletes all files starting with TEST

Renaming Files

OPEN 15,8,15,"R0:NEWNAME=OLDNAME" : CLOSE 15

Copying Files

OPEN 15,8,15,"C0:DEST=0:SOURCE" : CLOSE 15

Validating Disk (clean up)

OPEN 15,8,15,"V0:" : CLOSE 15
' Reclaims space from improperly closed files

Initializing Disk

OPEN 15,8,15,"I0:" : CLOSE 15
' Re-reads BAM; use after swapping disks

Wildcards

  • * — matches any sequence of characters
  • ? — matches any single character
OPEN 15,8,15,"S0:TEST*"   : CLOSE 15  ' scratch all TEST files

Sequential File Access

Sequential files are read or written in order only (not random access).

Writing a Sequential File

10 OPEN 1,8,2,"MYDATA,S,W"   ' LFN=1, DEV=8, SA=2, write sequential
20 PRINT#1,"LINE 1 DATA"
30 PRINT#1,"LINE 2 DATA"
40 PRINT#1,NUMBER            ' Numbers also work
50 CLOSE 1

Reading a Sequential File

10 OPEN 1,8,2,"MYDATA,S,R"   ' SA=2, read sequential
20 IF ST<>0 THEN 60           ' ST = status byte; non-zero = EOF/error
30 INPUT#1,LINE$
40 PRINT LINE$
50 GOTO 20
60 CLOSE 1

Appending to a Sequential File

OPEN 1,8,2,"MYDATA,S,A"      ' SA=2 with ,A flag appends

Relative File Access

Relative files provide random access to fixed-length records.

Creating a Relative File

10 OPEN 2,8,2,"MYREL,L," + CHR$(RECLEN)
' RECLEN = record length in bytes (1-254)

Positioning the Record Pointer

20 OPEN 15,8,15
30 RN = 5                    ' desired record number (1-based)
40 LO = (RN-1) AND 255
50 HI = INT((RN-1)/256)
60 PRINT#15,"P" CHR$(2) CHR$(LO) CHR$(HI) CHR$(0)
' Channel 2 (the data file's SA), then record# low, high, byte offset

Reading/Writing Records

' After positioning:
PRINT#2, FIELD1$, FIELD2$   ' write
INPUT#2, FIELD1$, FIELD2$   ' read (re-position first)

Error Codes

Code Message Meaning
00 OK No error
01 FILES SCRATCHED Normal after SCRATCH
20 READ ERROR Block header not found
21 READ ERROR No sync character found
22 READ ERROR Data block not found
23 READ ERROR Checksum error in data
24 READ ERROR Byte decoding error
25 WRITE ERROR Write verify error
26 WRITE PROTECT ON Write-protect tab covered
27 READ ERROR Checksum error in header
28 WRITE ERROR Long data block
29 DISK ID MISMATCH Wrong disk in drive
30 SYNTAX ERROR DOS command syntax error
31 SYNTAX ERROR Invalid command
32 SYNTAX ERROR Long line
33 SYNTAX ERROR Invalid filename
34 SYNTAX ERROR No file given
39 SYNTAX ERROR Invalid command
50 RECORD NOT PRESENT Past end of relative file
51 OVERFLOW IN RECORD Wrote past end of record
52 FILE TOO LARGE Relative file too large
60 WRITE FILE OPEN File still open for writing
61 FILE NOT OPEN File not open
62 FILE NOT FOUND File does not exist
63 FILE EXISTS File already exists (overwrite with @)
64 FILE TYPE MISMATCH Wrong file type for operation
65 NO BLOCK Block already allocated
66 ILLEGAL TRACK OR SECTOR Bad T/S reference
67 ILLEGAL SYSTEM T OR S Bad system track/sector
70 NO CHANNEL No free logical channel
71 DIR ERROR Directory error (use VALIDATE)
72 DISK FULL No free blocks
73 CBM DOS Vxx.x Power-on/INITIALIZE message
74 DRIVE NOT READY No disk or drive error

Direct Block Access

The 1541 allows reading/writing individual sectors directly.

Block-Read

OPEN 15,8,15
OPEN 2,8,2,"#"             ' open direct-access channel
PRINT#15,"B-R:2 0 " TRACK " " SECTOR
' Read into drive buffer; then read bytes via GETIN or INPUT#

Block-Write

' Write buffer to disk after filling via BSOUT:
PRINT#15,"B-W:2 0 " TRACK " " SECTOR

Block-Pointer (set position within buffer)

PRINT#15,"B-P:2 " POS     ' set byte position in buffer (0-255)

Directory Structure on Disk

Track 18, Sector 0 = BAM (Block Availability Map)

BAM format:

  • Bytes 0-1: Track/sector of first directory block (18/1)
  • Byte 2: DOS version (‘A’)
  • Byte 3: unused
  • Bytes 4-143: BAM entries for each track (4 bytes per track × 35 tracks):
    • Byte 0: free sector count for this track
    • Bytes 1-3: bit map of free sectors (1=free, 0=used)
  • Bytes 144-161: Disk name (padded with $A0)
  • Bytes 162-163: Disk ID
  • Byte 164: $A0
  • Bytes 165-166: DOS version bytes (“2A”)

Track 18, Sectors 1-18 = Directory

Each directory sector holds 8 directory entries (32 bytes each):

  • Byte 0: Track link to next directory sector (0 if none)
  • Byte 1: Sector link to next directory sector
  • For each of 8 entries starting at byte 2 (or 0 for entry 0):
    • Byte 0: File type ($80=DEL, $81=SEQ, $82=PRG, $83=USR, $84=REL; OR $40=locked, $60=opened)
    • Bytes 1-2: Starting track/sector
    • Bytes 3-18: Filename (padded with $A0)
    • Bytes 19-20: Side-sector block track/sector (relative files only)
    • Byte 21: Record length (relative files only)
    • Bytes 22-25: Unused
    • Bytes 26-27: Track/sector of replacement file (during @-SAVE)
    • Bytes 28-29: File size in blocks (low, high)

Assembly Language Disk I/O

; Open logical file 1 to disk drive 8, secondary address 2, filename "DATA"
        LDA #1          ; logical file number
        LDX #8          ; device (disk)
        LDY #2          ; secondary address
        JSR $FFBA       ; SETLFS
        
        LDA #4          ; filename length
        LDX #<FNAME
        LDY #>FNAME
        JSR $FFBD       ; SETNAM
        
        JSR $FFC0       ; OPEN
        BCS error       ; carry set = error
        
        LDX #1          ; logical file number
        JSR $FFC9       ; CHKOUT - redirect output to file
        
        LDA #65         ; character 'A'
        JSR $FFD2       ; BSOUT - write to file
        
        JSR $FFCC       ; CLRCH - restore default channels
        
        LDA #1
        JSR $FFC3       ; CLOSE

FNAME   .TEXT "DATA"

Powered by TurnKey Linux.