Assembly Disc Access Primer, a TatungBytes course: DISKMON reading the hidden sector IDs of the course's own practice disc, on a rainbow sunburst
← Back to Modules
module
10

Writing a File

Introduction

Reading is half the story. A game saves a position; an editor saves your work; DISKMON is about to save a note. Through the BDOS, writing a file is three calls - but the third is the one people forget.

Make, Write, Close

  1. Make - function 22, the FCB in DE - writes a new, empty entry in the directory and opens it. A comes back 0-3, as with open.
  2. Write sequential - function 21 - writes 128 bytes from the DMA address as the next record. A = 0.
  3. Close - function 16 - writes the record count and block numbers into the directory entry.

Leave out the close and the name is in the directory, but the entry says the file has no records and no blocks: DIR lists it, and it is empty. For a short file the data does not even reach the disc. Always close a file you have written.

Make does not look for an older file of the same name, so W deletes one first with function 19 (S11), which returns FFh if there was nothing to delete - here that is fine either way.

DISKMON's file is one record: the text from the command line, then CR and LF, then 1Ah to the end of the 128 bytes, so that XtalDOS stops showing it at the right place.

A Disc That Keeps What You Write

In MAME, a .dsk image cannot be written to: the BDOS's first write fails with Bad Data 1: and Try Again(Y/N)?. MAME keeps writes in its own .mfi format. The Einstein disc tools from the website convert both ways:

python3 dsk2mfi.py work.dsk           (makes work.mfi)
python3 mfi2dsk.py work.mfi after.dsk (back again, for edisc.py)

From now on, whenever DISKMON writes, drive 1 is an .mfi.

The Code

After the line JP Z,CMDR, add:

        CP 'W'
        JP Z,CMDW

After the line JP CRMAIN, add:

; W name text: make a new file holding one record: the text, then
; CR LF, then 1Ah to the end of the record.
CMDW:   CALL NEEDDOS
        LD DE,FCB
        CALL GETNAME
        JP C,WHAT
        CALL TEXTREC            ; the rest of the line into RECBUF
        LD DE,FCB
        LD C,19                 ; delete any old file of this name
        CALL 5
        LD DE,FCB
        LD C,22                 ; make
        CALL 5
        CP 0FFH
        LD HL,NOMAKEM
        JP Z,DONE
        LD DE,RECBUF
        LD C,26
        CALL 5
        LD DE,FCB
        LD C,21                 ; write the record
        CALL 5
        LD DE,FCB
        LD C,16                 ; close: now the directory knows
        CALL 5
        LD HL,WROTEM
        JP DONE

; TEXTREC: RECBUF = the rest of the command line, CR, LF, then 1Ah.
TEXTREC: LD HL,RECBUF
        LD B,128
TR1:    LD (HL),1AH
        INC HL
        DJNZ TR1
        CALL SKIPSP
        LD DE,RECBUF
        LD B,125
TR2:    LD A,(HL)
        OR A
        JR Z,TR3
        LD (DE),A
        INC HL
        INC DE
        DJNZ TR2
TR3:    LD A,13
        LD (DE),A
        INC DE
        LD A,10
        LD (DE),A
        RET

After the line AM: DEFB 'A=',0, add:

NOMAKEM: DEFB 'CANNOT MAKE IT',13,10,0
WROTEM: DEFB 'WRITTEN',13,10,0

Run it

z80asm -o diskmon.com diskmon.asm
cp PRIMER.DSK work.dsk
python3 edisc.py add work.dsk diskmon.com DISKMON.COM
python3 dsk2mfi.py work.dsk
mame -rompath ~/roms einstein -window -nomaximize -ui_active -skip_gameinfo -flop1 XTALDOS.DSK -flop2 work.mfi
1:DISKMON
W 1:NOTE.TXT HELLO FROM DISKMON
T 1:NOTE.TXT
Q

What you should see

> W 1:NOTE.TXT HELLO FROM DISKMON
WRITTEN
> T 1:NOTE.TXT
HELLO FROM DISKMON

1 RECORDS
>

That is DISKMON reading back its own file, which proves only that it agrees with itself. Quit MAME, start it again with the same work.mfi, and ask XtalDOS:

0:DIR 1:
1: POEM    .TXT : ROOMS   .DAT
1: DISKMON .COM : NOTE    .TXT
32k Size, 156k Free, 190k Total
0:DISP 1:NOTE.TXT
HELLO FROM DISKMON

0:

Change One Thing

  • Take out the close (the three lines with LD C,16). Run W again with a new name, quit, and look with DIR 1:. What will it list - and what size will it give?
  • Run the same W on work.dsk instead of work.mfi. What will appear on the screen, and will DISKMON print WRITTEN?

Summary

Make, write, close: function 22 creates the entry, 21 writes records, 16 puts the size into the directory. MAME keeps the writes in an .mfi.

Next

S11: deleting, renaming, and writing into the middle of a file.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.