
In S7 and S8 the BDOS found POEM.TXT and fed it to you a record at a time. Here is what it did, done by DISKMON with nothing but MOS calls.
FINDSET reads the drive and name, builds the name into the FCB (only bytes 1-11 matter - they line up with an entry's bytes 1-11), and reads the directory. FINDEXT looks through the 64 entries for one that is in use, has the right extent number in byte 12, and the same eleven name bytes (with bit 7 cleared, so a locked file still matches). L asks for extent 0, then 1, and so on until there are no more.
Each entry has up to eight block numbers, two bytes each, low byte first; a 0 means no more. For each block, BLKSEC works out each of its four sectors from S3's rule: logical sector 4 × block + i; track = logical ÷ 10 + 2; sector = the remainder. DIV10 does the dividing.
The entry's byte 15 says how many records of the extent are used. L keeps the count in RLEFT and shows only that many: four records from a full sector, fewer from the last. And TYPEOUT stops at the 1Ah that ends the text.
After the line JP Z,CMDD, add:
CP 'L'
JP Z,CMDL
After the last line of PNAME (RET), add:
; L d name: find a file in drive d's directory and type it, following
; its blocks to the sectors - what the BDOS's open and read did for you.
CMDL: CALL FINDSET
XOR A
LD (EXTENT),A
CMDL1: CALL FINDEXT
JR NZ,CMDL9
LD A,(IX+15) ; records in this extent
LD (RLEFT),A
LD B,8
PUSH IX
POP HL
LD DE,16
ADD HL,DE ; HL -> the block numbers
CMDL2: PUSH BC
LD E,(HL)
INC HL
LD D,(HL)
INC HL
PUSH HL
LD A,D
OR E
JR Z,CMDL8 ; block 0: no more blocks
LD B,4 ; four sectors to a block
LD C,0
CMDL3: PUSH BC
PUSH DE
LD A,(RLEFT)
OR A
JR Z,CMDL7
CALL BLKSEC ; block DE, sector C -> STRK, SSEC
CALL READSEC
JP NZ,DISCERR
LD A,(RLEFT) ; up to four records from this sector
LD B,4
CP B
JR NC,CMDL4
LD B,A
CMDL4: LD A,(RLEFT)
SUB B
LD (RLEFT),A
LD HL,0
LD DE,128
CMDL5: ADD HL,DE
DJNZ CMDL5 ; HL = 128 x records
LD B,H
LD C,L
LD HL,SECBUF
CALL TYPEOUT
JR C,CMDL6 ; 1Ah: the text has ended
POP DE
POP BC
INC C
DJNZ CMDL3
POP HL
POP BC
DJNZ CMDL2
JR CMDLX
CMDL6: JP CRMAIN
CMDL7: POP DE
POP BC
CMDL8: POP HL
POP BC
CMDLX: LD HL,EXTENT
INC (HL)
JR CMDL1
CMDL9: LD A,(EXTENT)
OR A
LD HL,NOTFM
JP Z,DONE
JP CRMAIN
; FINDSET: drive and name from the line; read the directory.
FINDSET: CALL GETNUM
JP C,WHAT
LD (SDRV),A
LD DE,FCB
CALL GETNAME
JP C,WHAT
CALL READDIR
JP NZ,DISCERR
RET
; FINDEXT: IX -> the entry for FCB's name with extent EXTENT. Z if found.
FINDEXT: LD IX,DIRBUF
LD B,64
FE1: LD A,(IX+0)
CP 0E5H
JR Z,FE3
LD A,(EXTENT)
CP (IX+12)
JR NZ,FE3
PUSH BC
PUSH IX
POP HL
INC HL
LD DE,FCB+1
LD B,11
FE2: LD A,(HL)
AND 7FH ; ignore the locked bit
LD C,A
LD A,(DE)
CP C
JR NZ,FE4
INC HL
INC DE
DJNZ FE2
POP BC
XOR A ; Z: found
RET
FE4: POP BC
FE3: LD DE,32
ADD IX,DE
DJNZ FE1
OR 1 ; NZ: not there
RET
; BLKSEC: block DE's sector C (0-3) -> STRK, SSEC.
; Logical sector 4 x block + C, counted from track 2 sector 0;
; track = logical / 10 + 2, sector = logical mod 10.
BLKSEC: EX DE,HL
ADD HL,HL
ADD HL,HL
LD B,0
ADD HL,BC
CALL DIV10
LD (SSEC),A
LD A,L
ADD A,2
LD (STRK),A
RET
After the line RECM: DEFB ' RECORDS ',0, add:
EXTENT: DEFB 0
RLEFT: DEFB 0
Run it on a copy of PRIMER.DSK:
L 1 POEM.TXT
What you should see
> L 1 POEM.TXT
THE DISC
Forty tracks go round and round,
ten sectors on each one;
the directory shows what can be found,
and blocks say where they've gone.
Ask the DOS and it will look
the name up for you, line by line;
or read the sectors like a book
and all the work is yours and mine.
>
The same poem T showed in S8, read without the BDOS.
L show only extent 0 of a file. What does L 1 ROOMS.DAT stop at then - and how many records is that?RLEFT checks so that every sector of every block is shown. On which file would you see the difference?Directory entry, block numbers, tracks and sectors, record count: DISKMON now does everything the BDOS's open and read did, with the MOS alone.
S18 writes a sector - and changes a file's name without the DOS.
This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.