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.

14KB

Commodore 1541 Disk DOS — Complete Command Reference

Source: The Anatomy of the 1541 Disk Drive (Revised); Compute's Mapping the C64


Drive Addressing

  • Default device number: 8 (jumper-selectable; 8–11)
  • Drive number: always 0 for 1541 (single drive)
  • Commands sent to: secondary address 15 (command channel)
  • Errors read from: secondary address 15

BASIC Command Channel Wrapper

Use these BASIC patterns to send all DOS commands:

10 OPEN 1,8,15           : REM open error/command channel
20 PRINT#1,"I0:"         : REM send a command (initialize)
30 INPUT#1,EN,EM$,ET,ES  : REM read error (code,msg,track,sector)
40 CLOSE 1

Or for a reusable subroutine:

9000 REM --- DOS COMMAND ---
9010 OPEN 15,8,15,CMD$
9020 INPUT#15,EN,EM$,ET,ES
9030 IF EN>0 AND EN<20 THEN PRINT EN;EM$;ET;ES
9040 CLOSE 15
9050 RETURN

DOS Commands

Initialize — I0:

Resets the disk, reads BAM (Block Availability Map). Use after inserting a disk.

OPEN 15,8,15,"I0:":CLOSE 15

Validate — V0:

Repairs the BAM and removes “scratched” file entries. Like CHKDSK.

OPEN 15,8,15,"V0:":CLOSE 15

New (Format) — N0:diskname,id

Low-level format. Destroys all data. ID = 2-char disk identifier.

OPEN 15,8,15,"N0:MYDISK,A1":CLOSE 15
  • After first format, use N0:name (no ID) for a fast format that only rewrites the directory

Rename — R0:newname=oldname

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

Scratch (Delete) — S0:filename

Marks file as deleted; frees its blocks in BAM. Wildcards (*, ?) supported.

OPEN 15,8,15,"S0:MYFILE":CLOSE 15
OPEN 15,8,15,"S0:GAME*":CLOSE 15   : REM scratch all files starting with GAME

Copy — C0:newfile=0:sourcefile

Copies a file on the same drive.

OPEN 15,8,15,"C0:BACKUP=0:ORIGINAL":CLOSE 15

Duplicate (two-drive systems) — C1:dest=0:source

Copies between drives (not applicable to 1541 unless using a 1571/1581 in dual mode).

Memory Read — M-R + address (2 bytes, lo then hi)

Reads bytes from the 1541's internal RAM/ROM. Advanced use.

OPEN 15,8,15:PRINT#15,"M-R"CHR$(0)CHR$(0)CHR$(2):INPUT#15,A$:CLOSE 15

Memory Write — M-W + address + count + data

Writes bytes to the 1541's RAM. Used for patching drive code.

Memory Execute — M-E + address

Executes code in the 1541's 6502 processor at the given address.

Block-Read — B-R ch dn tr sc

Reads a raw sector. ch=channel, dn=drive(0), tr=track, sc=sector.

OPEN 2,8,2,"#"          : REM open buffer channel
OPEN 15,8,15
PRINT#15,"B-R 2 0 18 0" : REM read track 18, sector 0 (directory)
FOR I=1 TO 256:GET#2,A$:PRINT ASC(A$+CHR$(0));:NEXT
CLOSE 2:CLOSE 15

Block-Write — B-W ch dn tr sc

Writes the buffer to a raw sector.

Block-Allocate — B-A dn tr sc

Marks a sector as used in the BAM.

Block-Free — B-F dn tr sc

Marks a sector as free in the BAM.

Block-Execute — B-E ch dn tr sc

Loads sector into buffer and executes it in the 1541.

User Commands — U1 through U9, UAUJ

Command Equivalent Description
U1 B-R Read block to buffer
U2 B-W Write block from buffer
U3–U8 M-E Execute user subroutines in 1541
U9 Soft reset (preserves drive address)
U: UJ Hard reset (same as power cycle)

Error Channel Format

Read from secondary address 15 after any operation:

EN, EM$, ET, ES
  • EN = error number (0=OK)
  • EM$ = error message string
  • ET = track where error occurred (0 if not disk error)
  • ES = sector where error occurred

Complete Error Code Table

Code Message Meaning
00 OK No error
01 FILES SCRATCHED N files were deleted (N is track field)
20 READ ERROR (block header) Can't find sector header
21 READ ERROR (no sync character) No sync mark found (blank/damaged)
22 READ ERROR (data block) Data block not found
23 READ ERROR (checksum) Data block checksum failed
24 READ ERROR (byte decoding) GCR decoding error
25 WRITE ERROR (verify) Verify-after-write failed
26 WRITE PROTECT ON Write-protect tab covering notch
27 READ ERROR (checksum header) Header block checksum failed
28 WRITE ERROR (long data block) Data block too long
29 DISK ID MISMATCH Wrong disk inserted
30 SYNTAX ERROR (general) DOS command not recognized
31 SYNTAX ERROR (invalid command) Command letter not recognized
32 SYNTAX ERROR (long line) Command string > 58 characters
33 SYNTAX ERROR (invalid filename) Wildcard in wrong context, or bad name
34 SYNTAX ERROR (no file given) Missing filename
39 SYNTAX ERROR (invalid command) Command exists but not in this context
49 INVALID FORMAT (loading) Attempt to load incompatible format
50 RECORD NOT PRESENT Relative file record past EOF
51 OVERFLOW IN RECORD Data exceeds relative record length
52 FILE TOO LARGE Relative file: record length too large
60 WRITE FILE OPEN Tried to read a file opened for write
61 FILE NOT OPEN File not opened before read/write
62 FILE NOT FOUND Named file doesn't exist on disk
63 FILE EXISTS Tried to create file that already exists
64 FILE TYPE MISMATCH Wrong file type for operation
65 NO BLOCK Block-allocate failed (no free block nearby)
66 ILLEGAL TRACK AND SECTOR Bad T/S combination
67 ILLEGAL SYSTEM T&S Tried to access reserved directory sector
70 NO CHANNEL All 5 channels in use
71 DIRECTORY ERROR BAM doesn't match actual usage
72 DISK FULL No free sectors remaining
73 CBM DOS V2.6 1541 Power-on / reset message (not an error)
74 DRIVE NOT READY No disk inserted, or door open

File Types

Code Extension Type Description
$80 PRG Program BASIC or ML program (load address in header)
$81 SEQ Sequential Text/data, forward-only access
$82 USR User Application-defined format
$83 REL Relative Random-access by record number
$84 (Internal) Used by 1571/1581, not 1541

Bit 7 set = file is closed (normal). Bit 6 set = file was locked (scratch protected). If bit 7 is clear, file was not properly closed (“splat file” — *filename).


Disk Layout (1541)

  • 35 tracks, numbered 1–35
  • 683 sectors total (664 user-available, 19 reserved for directory/BAM)
  • Sector size: 256 bytes each
  • Sectors per track varies with track zone:
Tracks Sectors/Track Notes
1–17 21 Outermost (fastest)
18–24 19
25–30 18
31–35 17 Innermost (slowest)

Track 18, Sector 0 — Directory header and BAM (Block Availability Map) Track 18, Sectors 1–18 — Directory entries (8 entries per sector × 18 sectors = max 144 files)

BAM Structure (Track 18, Sector 0)

Offset Length Content
$00 2 T/S link to first directory sector (18/1)
$02 1 DOS version (‘A’ for 1541 format)
$03 1 Unused ($00)
$04 4×35 BAM entries for tracks 1–35 (4 bytes each)
$90 16 Disk name (padded with $A0)
$A0 2 $A0 $A0 (padding)
$A2 2 Disk ID
$A4 1 $A0
$A5 2 DOS type (“2A”)
$A7 4 $A0 $A0 $A0 $A0 (padding)

Each 4-byte BAM entry:

  • Byte 0: number of free sectors on this track
  • Bytes 1–3: bit map — bit=1 means sector is FREE, bit=0 means sector is USED

Directory Entry Structure (32 bytes each)

Offset Length Content
$00 2 T/S of next dir sector (or $00/$00 if last)
$02 1 File type byte (see File Types above)
$03 2 T/S of first sector of file data
$05 16 Filename (padded with $A0)
$15 2 T/S of first side-sector (REL files only)
$17 1 Record length (REL files only)
$18 6 Unused (internal use during write)
$1E 2 File size in sectors (low byte first)

Sector Chaining

Every sector (except the last in a file) uses its first 2 bytes as a T/S link:

Byte Meaning
0 Track of next sector (0 = this is last)
1 Sector of next sector; or last used byte #

When track byte = 0, sector byte = number of valid data bytes in this sector (1 to 255). Data starts at byte offset $02 in each sector (bytes $00–$01 are the link).

Usable data per sector: 254 bytes (all sectors except last), variable in last sector.


BASIC File Operations Reference

Sequential Write

10 OPEN 1,8,2,"0:MYDATA,S,W"  : REM write mode
20 PRINT#1,"HELLO WORLD"
30 PRINT#1,3.14159
40 CLOSE 1

Sequential Read

10 OPEN 1,8,2,"0:MYDATA,S,R"  : REM read mode
20 INPUT#1,A$
30 IF ST=0 THEN PRINT A$:GOTO 20
40 CLOSE 1

Relative File — Create

10 OPEN 1,8,3,"0:RELFILE,L,"+CHR$(32) : REM record length 32
20 FOR I=1 TO 100
30   PRINT#1,I;"RECORD";I   : REM write record
40 NEXT I
50 CLOSE 1

Relative File — Random Access

10 OPEN 1,8,3,"0:RELFILE,L,"+CHR$(32)
20 OPEN 15,8,15
30 INPUT "RECORD NUMBER";R
40 PRINT#15,"P"+CHR$(3)+CHR$(R MOD 256)+CHR$(R/256)+CHR$(1)
50 INPUT#1,A$
60 PRINT A$
70 GOTO 30

P command: channel, record low, record high, byte-within-record (1-based)

Load a Program File

LOAD "FILENAME",8        : REM load to original address
LOAD "FILENAME",8,1      : REM load relocate to BASIC start

Save a Program File

SAVE "FILENAME",8

Directory Listing

LOAD "$",8
LIST

Read Error Channel

OPEN 15,8,15
INPUT#15,EN,EM$,ET,ES
PRINT EN,EM$,ET,ES
CLOSE 15

ML Direct Block Access Example

; Read track 18, sector 0 (BAM) into buffer at $C000
OPEN_BUFFER:
    LDA #2
    LDX #8
    LDY #2
    JSR $FFBA       ; SETLFS
    LDA #1
    LDX #<BUFNAME
    LDY #>BUFNAME
    JSR $FFBD       ; SETNAM "#" opens a buffer
    JSR $FFC0       ; OPEN

    LDA #0
    LDX #15
    LDY #0
    JSR $FFBA
    LDA #0
    JSR $FFBD       ; SETNAM "" (empty name for cmd channel)
    JSR $FFC0       ; OPEN channel 15

    LDX #15
    JSR $FFC9       ; CKOUT to cmd channel

    ; Send U1 (block read) command: U1 ch drive track sector
    LDA #'U':JSR $FFD2
    LDA #'1':JSR $FFD2
    LDA #' ':JSR $FFD2
    LDA #'2':JSR $FFD2   ; channel 2
    LDA #' ':JSR $FFD2
    LDA #'0':JSR $FFD2   ; drive 0
    LDA #' ':JSR $FFD2
    LDA #'1':JSR $FFD2   ; track 18 = "18"
    LDA #'8':JSR $FFD2
    LDA #' ':JSR $FFD2
    LDA #'0':JSR $FFD2   ; sector 0
    LDA #$0D:JSR $FFD2   ; RETURN

    JSR $FFCC       ; CLRCH

    ; Read 256 bytes from buffer channel
    LDX #2
    JSR $FFC6       ; CHKIN channel 2
    LDY #0
RD: JSR $FFCF       ; CHRIN
    STA $C000,Y
    INY
    BNE RD

    JSR $FFCC
    LDA #2:JSR $FFC3     ; CLOSE 2
    LDA #15:JSR $FFC3    ; CLOSE 15
    RTS

BUFNAME: .BYTE "#"

Tips & Pitfalls

  1. Always read the error channel after any disk operation. Error 73 at power-on is normal (drive status, not an error).
  2. Scratched files are recoverable until VALIDATE runs — the data sectors are not zeroed, just unlinked in the BAM.
  3. Never pull a disk during a write — the directory entry is written last; if interrupted, you get a “splat file” (*) that won't OPEN or SCRATCH easily.
  4. Track 18 is sacred — it holds the directory and BAM. If corrupted, use a disk editor to repair.
  5. Maximum 144 files per disk — 18 directory sectors × 8 entries each.
  6. Relative files are the only random-access format; they require a “side sector” on the disk.
  7. The 1541 has only one read/write head — interleave is important for sequential speed. Original DOS uses interleave of 10.
  8. Use U9 to soft-reset the drive if it hangs without cycling power; U: (UJ) does a complete reset.

Powered by TurnKey Linux.