AppleIIAsm-Collection/documentation/AppleIIAsm Library Collecti.../0.6.1/35.0 Detailed_Reference_D6_...

164 KiB

Disk 6: Apple DOS


Part I: The DOS Collection

The sixth disk of the AppleIIAsm library is dedicated to DOS operations. For the most part, the macros and subroutines here act as an abstraction layer between the lower level functions of DOS and the programmer. Unfortunately, this does carry with it some substantial overhead in terms of bytes used, but the ease of functionality is usually worth it unless memory is an extreme concerned. In such a case, the DOS collection can be narrowed to only the functions that are needed.

There are a number of macros and subroutines that are likely to go unused by most programmers, as they are mostly meant for internal use by the collection. These are covered as part of this documentation, but are not the primary focus of functionality. Those macros and subroutines that are the primary focus includes functions for the following:

  • Disk Catalog
  • File Locking and Unlocking
  • File Deletion
  • File Verification
  • File Renaming
  • File Opening and Closing
  • Binary File Loading and Saving
  • DOS Version Checking
  • Integer and Applesoft Runtime Checking
  • RWTS Access

DOS Components

The DOS Collection contains the following components:

  • A head file that includes a number of hooks, vectors and subroutines that are necessary for the operation of the whole collection.
  • A macro library that is required to be included for using the rest of the collection.
  • Two further sets of macro files, MAC.DOSFM.ASM and MAC.DOSMORE.ASM. The former contains macros used for managing files while the latter contains miscellaneous macros related to DOS.
  • Two demo files that illustrate how all of the major macros are used. Note that this does not include macros that are meant for internal use.

DOS Collection Header File

Condition Value
Name File: HEAD.DOS.ASM
Type Header File
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin 8 Pro
OS Apple DOS 3.3
Purpose Provide appropriate hooks and routines for the DOS collection
Dependencies none
Bytes 584
Notes none
See Also none

DETAILS

The DOS Header file includes a number of required subroutines that are detailed later in this section.

LISTING 6.00: HEAD.DOS.ASM Hooks & Vectors Source

*
*``````````````````````````````*
* HEAD.DOS.ASM                 *
*                              *
* THIS HEADER FILE IS USED BY  *
* THE DOS COLLECTION AS A      *
* REPOSITORY FOR VARIABLE      *
* SPACE, HOOKS, SUBROUTINES    *
* NECESSARY FOR THE REST OF    *
* THE COLLECTION AND OTHER     *
* MISCELLANEOUS TASKS.         *
*                              *
* CURRENTLY, THIS COLLECTION   *
* HAS QUITE A BIT OF OVERHEAD  *
* IN TERMS OF BYTES. THIS WILL *
* HOPEFULLY BE REDUCED IN      *
* FUTURE REVISIONS.            *
*                              *
* NOTE THAT THE METHOD USED    *
* FOR FINDING AN EMPTY FILE    *
* BUFFER IS ADAPTED FROM A     *
* LISTING IN DON WORTH'S AND   *
* PETER LECHNER'S /BENEATH     *
* APPLE DOS AND BENEAT APPLE   *
* PRODOS 2020/. AS SUCH, THE   *
* LICENSE MAY VARY.            *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      07-MAY-2021       *
* ASSEMBLER: MERLIN PRO 8      *
* OS:        DOS 3.3           *
*                              *
* SIZE: 584 BYTES (OVERHEAD)   *
*                              *
* SUBROUTINES:                 *
*                              *
*  _SETRWTS                    *
*  _FMGETPARM                  *
*  _FMBUFSCAN                  *
*  _SETPBUFFS                  *
*  _NAMESTR                    *
*  _NAMESTR2                   *
*  _FN2BUFF                    *
*  _FMNM2                      *
*  _BUFFCLEAR                  *
*  _FMPSET                     *
*  _FMPSETA                    *
*  _FMPGET                     *
*  _FMPGETA                    *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*``````````````````````````````*
* RWTS EQUATES                 *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]RWTSPTR EQU   ADDR4      ; WORK POINTER FOR RWTS ROUTINES
]RWTSRD  EQU   1          ; READ CODE FOR RWTS
]RWTSWR  EQU   1          ; WRITE CODE FOR RWTS
]LOCRPL  EQU   $3E3       ; LOCATE RWTS PARAMLIST
]RWTS    EQU   $3D9       ; RWTS ROUTINE
*
]RPLIOB  EQU   $0         ; IOB TYPE, ALWAYS $01
]RPLSLT  EQU   $1         ; IOB SLOT * 16
]RPLDRV  EQU   $2         ; IOB DRIVE
]RPLVOL  EQU   $3         ; IOB VOLUME (#0 FOR ANY)
]RPLTRK  EQU   $4         ; IOB TRACK
]RPLSEC  EQU   $5         ; IOB SECTOR
]RPLDCT  EQU   $6         ; IOB ADDR TO DCT ($6,$7)
]RPLBUF  EQU   $8         ; IOB ADDR TO BUFFER ($8,$9)
]RPLSIZ  EQU   $A         ; IOB SIZE ($A,$B)
]RPLCMD  EQU   $C         ; IOB COMMAND
]RPLCNL  EQU   $00        ;     NULL COMMAND
]RPLCRD  EQU   $01        ;     READ COMMAND
]RPLCWR  EQU   $02        ;     WRITE COMMAND
]RPLCFM  EQU   $04        ;     FORMAT COMMAND
]RPLRCD  EQU   $D         ; IOB RETURN CODE
]RPLRWP  EQU   $10        ;     WRITED PROTECTED ERROR
]RPLRVM  EQU   $20        ;     VOLUME MISMATCH ERROR
]RPLRDE  EQU   $40        ;     DRIVE ERROR
]RPLRRE  EQU   $80        ;     READ ERROR
]RPLTVL  EQU   $E         ; IOB TRUE VOLUME
]RPLPSL  EQU   $F         ; IOB PREVIOUS SLOT
]RPLPDR  EQU   $10        ; IOB PREVIOUS DRIVE
*
*``````````````````````````````*
* FILE PARAMETER LIST EQUATES  *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]FMPADDR EQU   $3DC       ; FILE MGR PARAM ADDR GET
]FMRUN   EQU   $3D6       ; RUN FILE MAMAGER ROUTINE
]DOSWARM EQU   $3D0       ; DOS WARM START
*
]TYP_TXT EQU   $00        ; FILE TYPE TEXT VALUE
]TYP_INT EQU   $01        ; FILE TYPE INT VALUE
]TYP_APP EQU   $02        ; FILE TYPE APPLESOFT VALUE
]TYP_BIN EQU   $04        ; FILE TYPE BINARY VALUE
]TYP_REL EQU   $08        ; FILE TYPE REL VALUE
]TYP_S   EQU   $10        ; FILE TYPE S VALUE
]TYP_A   EQU   $20        ; FILE TYPE A VALUE
]TYP_B   EQU   $40        ; FILE TYPE B VALUE
*
]SC_NON  EQU   $00        ; SUBCODE NOTHING VALUE
]SC_RWB  EQU   $01        ; SUBCODE READ OR WRITE A BYTE VALUE
]SC_RWR  EQU   $02        ; SUBCODE READ OR WRITE RANGE VALUE
]SC_PRWB EQU   $03        ; SUBCODE POSITION THEN RW 1 BYTE VAL
]SC_PRWR EQU   $04        ; SUBCODE POSITION THEN RW RANGE VAL
*
]FC_OPEN EQU   $01        ; COMMAND CODE FOR OPEN
]FC_CLOS EQU   $02        ; COMMAND CODE FOR CLOSE
]FC_READ EQU   $03        ; COMMAND CODE FOR READ
]FC_WRIT EQU   $04        ; COMMAND CODE FOR WRITE
]FC_DEL  EQU   $05        ; COMMAND CODE FOR DELETE
]FC_CAT  EQU   $06        ; COMMAND CODE FOR CATALOG
]FC_LOCK EQU   $07        ; COMMAND CODE FOR LOCK
]FC_UNLK EQU   $08        ; COMMAND CODE FOR UNLOCK
]FC_REN  EQU   $09        ; COMMAND CODE FOR RENAME
]FC_POS  EQU   $0A        ; COMMAND CODE FOR POSITION
]FC_INIT EQU   $0B        ; COMMAND CODE FOR INIT
]FC_VFY  EQU   $0C        ; COMMAND CODE FOR VERIFY
*
]P_CMD   EQU   $00        ; PARAM COMMAND OFFSET
]P_REC   EQU   $02        ; PARAM RECORD OFFSET
]P_VOL   EQU   $04        ; PARAM VOLUME OFFSET
]P_DRV   EQU   $05        ; PARAM DRIVE OFFSET
]P_SLOT  EQU   $06        ; PARAM SLOT OFFSET
]P_TYPE  EQU   $07        ; PARAM TYPE OFFSET
]P_NAMAD EQU   $08        ; PARAM NAME BUFFER ADDRESS OFFSET
]P_WORK  EQU   $0C        ; PARAM WORKAREA BUFFER ADDRESS OFFSET
]P_TSLS  EQU   $0E        ; PARAM TSLS BUFFER ADDRESS OFFSET
]P_DATA  EQU   $10        ; PARAM DATA BUFFER ADDRESS OFFSET
]P_RETC  EQU   $0A        ; PARAM RETURN CODE OFFSET
]P_RDWR  EQU   $00        ; READ OR WRITE OFFSET
]P_SUBC  EQU   $01        ; PARAM SUBCODE OFFSET
]P_BOFF  EQU   $04        ; PARAM BYTE OFFSET OFFSET
]P_RLEN  EQU   $06        ; PARAM RANGE LENGTH OFFSET
]P_RADDR EQU   $08        ; PARAM RANGE ADDRESS OFFSET
]P_BYTE  EQU   $08        ; PARAM SINGLE WRITE BYTE OFFSET
]P_DPAGE EQU   $01        ; PARAM 1ST DOS PAGE ADDR OFFSET
*
         JMP   __DHEXIT   ; {6C3B} PASS OVER ROUTINES
*
MSLOT    DFB   $60        ; {0C1B} MASTER SLOT
MDRIVE   DFB   $2         ; {0C1B} MASTER DRIVE
MTRACK   DFB   $11        ; {0C1B} MASTER TRACK FOR RWTS
MSECTOR  DFB   $0         ; {0C1B} MASTER SECTOR FOR RWTS
MBUFFER  DFB   $9000      ; {0C1B} MASTER BUFFER ADDRESS FOR RWTS
         DFB   $9000/$100 ; {0C1B}
MCMD     DFB   $1         ; {0C1B} MASTER COMMAND FOR RWTS
MVOL     DFB   $0         ; {0C1B} MASTER VOLUME FOR RWTS
*
]TEMP    HEX   0000       ; {0C2B}
]TEMP2   HEX   0000       ; {0C2B}
]FPARM   HEX   0000       ; {0C2B} FILE MGR PARAM ADDRESS
]FNBUF   HEX   0000       ; {0C2B} FILE NAME BUFFER
]FWORK   HEX   0000       ; {0C2B} FILE WORKAREA BUFFER
]FDATA   HEX   0000       ; {0C2B} FILE DATA BUFFER
]FTSLS   HEX   0000       ; {0C2B} FILE TRACK/SECTOR LIST BUFFER
]FNAME   DS    30         ; {0C30B} FILENAME TEMP STORAGE
]FNAME2  DS    30         ; {0C30B} SECOND FILENAME BUFFER


THE _SETRWTS SUBROUTINE

SUMMARY

Condition Value
Name _SETRWTS
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Set common RWTS parameters
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 142+
Bytes 78
Notes none
See Also none

DETAILS

The _SETRWTS routine sets the parameters for the Input/Output Control Block (IOB) before calling the Read/Write Track/Sector (RWTS) Routine. For the most part, this is used internally, and is not meant to be used by the end programmer. The following parameters are set in the IOB via the values given in global variables, which are set via another routine:

  • Slot
  • Drive
  • Volume
  • Track
  • Sector
  • Buffer
  • Command

While the DOS collection makes knowing the format of the Input/Output Control Block unnecessary, there may be cases where one needs to access DOS at a lower level. Thus, the format of the IOB is listed here:

INPUT / OUTPUT CONTROL BLOCK

Byte Description
00 Table type, must always be #00
01 Slot number * 16 ($10, $20, $30, $40, $50, $60, $70)
02 Drive number
03 Volume number (#00 for any)
04 Track number
05 Sector number
06-07 Address of the Device Characteristics Table (DCT)
08-09 Address of the 256 byte buffer for READ/WRITE
0A Unused
0B Byte count for partial sector
0C Command Code:
#$00 = SEEK
#$01 = READ
#$02 = WRITE
#$04 = FORMAT
0D Return Code. The CARRY flag is set upon returning from RWTS to indicate that an error has occurred. The following values are passed here to communicate the type of error:
#$00 = No error
#$08 = Initialization error
#$10 = Write protect error
#$20 = Volume mismatch
#$40 = Drive error
#$80 = Read error
0E Volume number last accessed
0F Slot number last accessed * 16
10 Drive number last accessed

While the Device Characteristics Table (DCT) is almost always the same and should remain unchanged (for a Disk II drive), its format is also listed here for reference:

DEVICE CHARACTERISTICS TABLE

Byte Description
00 Device Type (should be #$00)
01 Phases per track (should be #$01)
02-03 Motor on time count (should be #$EFD8)

LISTING 6.01: HEAD.DOS.ASM _SETRWTS Routine Source

*
*``````````````````````````````*
* _SETRWTS                     *
*                              *
* SET THE RWTS IOB PARAMETERS  *
*                              *
* INPUT                        *
*                              *
*  NONE.                       *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 142+                 *
* SIZE: 78 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_SETRWTS
         JSR   ]LOCRPL    ; {6C3B} LOCATE RWTS PARAMETER LIST
         STY   ]RWTSPTR   ; {4C3B} SAVE POINTER LOW AND HIGH
         STA   ]RWTSPTR+1 ; {4C3B}
         LDA   MSLOT      ; {4C3B} GET DEFAULT SLOT
         ASL              ; {2C1B} MULTIPLY BY 16
         ASL              ; {2C1B} TO GET APPROPRIATE VALUE
         ASL              ; {2C1B}
         ASL              ; {2C1B}
         LDY   #]RPLSLT   ; {3C2B} LOAD IOB SLOT OFFSET
         STA   (]RWTSPTR),Y ; {6C2B} STORE SLOT VAL AT OFFSET
         LDA   MDRIVE     ; {4C3B} LOAD DEFAULT DRIVE
         LDY   #]RPLDRV   ; {3C2B} GET IOB DRIVE OFFSET
         STA   (]RWTSPTR),Y ; {6C2B} STORE DRIVE IN IOB
         LDA   MTRACK     ; {4C3B} GET MASTER TRACK
         LDY   #]RPLTRK   ; {3C2B} OFFSET IN PARAM LIST
         STA   (]RWTSPTR),Y ; {6C2B} STORE TRACK IN IOB
         LDA   MSECTOR    ; {4C3B} GET MASTER SECTOR
         CMP   #16        ; {3C2B} BIGGER THAN 16?
         BCC   :SOK       ; {3C2B} NOPE, IT'S OKAY
         LDA   #0         ; {3C2B} ELSE YES, SO CLEAR
         STA   MSECTOR    ; {4C3B} MASTER SECTOR
:SOK     LDY   #]RPLSEC   ; {3C2B} OFFSET IN PARMLIST
         STA   (]RWTSPTR),Y ; {6C2B} STORE SECTOR IN IOB
         LDY   #]RPLBUF   ; {3C2B} OFFSET IN PARAMLIST
         LDA   MBUFFER    ; {4C3B} GET LOW BYTE OF BUFFER ADDR
         STA   (]RWTSPTR),Y ; {6C2B} STORE LOW BYTE OF BUFF IN IOB
         INY              ; {2C1B} INCREASE OFFSET
         LDA   MBUFFER+1  ; {4C3B} GET HIGH BYTE
         STA   (]RWTSPTR),Y ; {6C2B} STORE HIGH BYTE IN IOB
         LDA   MCMD       ; {4C3B} GET RWTS MASTER COMMAND
         LDY   #]RPLCMD   ; {3C2B} OFFSET OF PARMLIST
         STA   (]RWTSPTR),Y ; {6C2B} STORE COMMAND IN IOB
         LDA   MVOL       ; {4C3B} GET RWTS MASTER VOLUME
         LDY   #]RPLVOL   ; {3C2B} OFFSET
         STA   (]RWTSPTR),Y ; {6C2B} STORE VOLUME IN IOB
         RTS              ; {6C1B}

THE _FMGETPARM SUBROUTINE

SUMMARY

Condition Value
Name _FMGETPARM
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Get the FPL Address
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 20+
Bytes 10
Notes none
See Also _SETPBUFFS

DETAILS

The _FMGETPARM subroutine gets the address of the File Manager Parameter List (FPL) and returns it in .Y (low byte) and .A (high byte), with the addition of storing it in the ]FPARM variable space. This is different from the usual passing of addresses in .A and .X due to the nature of how DOS was programmed; since this is used internally, however, this should not present a problem.

If the format of the File Manager Parameter List (FPL) is needed, it is available under the SETPBUFFS entry.

LISTING 6.02: HEAD.DOS.ASM _FMGETPARM Routine Source

*
*``````````````````````````````*
* _FMGETPARM    (NATHAN RIGGS) *
*                              *
* GET THE ADDRESS OF THE FILE  *
* PARAMETER LIST.              *
*                              *
* INPUT                        *
*                              *
*  NONE.                       *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 20+                  *
* SIZE: 10 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_FMGETPARM
*
         JSR   ]FMPADDR   ; {6C3B} GET PARAM ADDRESS
         STA   ]FPARM+1   ; {4C3B} STORE HIGH BYTE
         STY   ]FPARM     ; {4C3B} STORE LOW BYTE
         RTS              ; {6C1B}
*


THE _FMBUFSCAN SUBROUTINE

SUMMARY

Condition Value
Name _FMBUFSCAN
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Find a free file buffer
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 211+
Bytes 117
Notes none
See Also _BUFFCLEAR

DETAILS

The _FMBUFSCAN subroutine finds an open file buffer and stores the addresses to various necessary sections in the appropriate memory locations. Primarily, this includes the File Workarea, the Filename Buffer, the Data Sector Buffer, and the T/S List Sector (TSLS) Buffer. If no file buffers are available then the carry is set to indicate an error, and the memory locations are all cleared to zero. A file buffer is considered clear if the first byte of the filename buffer carries a value of #0.

While the DOS collection makes it unnecessary to know the inner workings of DOS, it may be useful for the programmer to know the format of each file buffer. The format is as follows:

BYTE DESCRIPTION
000-0FF Data Sector Buffer (256 bytes)
100-1FF T/S List Sector Buffer (256 bytes)
200-22C File Manager Workarea Buffer (45 bytes)
22D-24A File Name Buffer (30 bytes)
24B-24C Address of File Manager Work Area Buffer
24D-24E Address of T/S List Sector Buffer
24F-250 Address of Data Sector Buffer
251-252 Address of the File Name Buffer in the next File Buffer. If this is the last buffer available, then the value is #0000.

LISTING 6.03: HEAD.DOS.ASM _FMBUFSCAN Routine Source

*
*``````````````````````````````*
* _FMBUFSCAN    (NATHAN RIGGS) *
*                              *
* FIND A FREE FILE BUFFER. IF  *
* NONE EXISTS, RETURN #0.      *
*                              *
* INPUT                        *
*                              *
*  NONE.                       *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 211+                 *
* SIZE: 117 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_FMBUFFSCAN
*
         LDA   $3D2       ; {4C3B} LOCATE DOS LOAD POINT
         STA   ADDR1+1    ; {3C2B} STORE THIS AS FIRST FNAME BUFF
         LDY   #0         ; {3C2B} LOW BYTE SHOULD START AT 0
         STY   ADDR1      ; {3C2B}
:GBUF0
         LDA   (ADDR1),Y  ; {6C2B} LOCATE NEXT DOS BUFFER
         PHA              ; {3C1B} TEMPORARILY HOLD
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   (ADDR1),Y  ; {6C2B} LOAD HIGH BYTE OF ADDRESS
         STA   ADDR1+1    ; {3C2B} STORE HIGH BYTE IN ZERO PAGE
         PLA              ; {3C1B} PULL BACK EARLIER VALUE
         STA   ADDR1      ; {3C2B} STORE AS LOW BYTE ON ZERO
         BNE   :GBUF      ; {4C3B} FOUND A BUFFER
         LDA   ADDR1+1    ; {3C2B} ELSE LOAD HIGH BYTE
         BEQ   :NBUF      ; {4C3B} IF ZERO, NO BUFFER
:GBUF
         LDY   #0         ; {3C2B} GET FILENAME FIRST CHAR
         LDA   (ADDR1),Y  ; {6C2B} FROM THE BUFFER
         BEQ   :GOTBUF    ; {3C2B} IF 0, THEN BUFFER IS UNUSED
         LDY   #36        ; {3C2B} IF NOT, SKIP TO NEXT LINK
         BNE   :GBUF0     ; {3C2B} AND RERUN THE SEARCH LOOP
:GOTBUF
         LDA   ADDR1      ; {3C2B} LOAD FNAME BUFFER LOW BYTE
         STA   ]FNBUF     ; {4C3B} STORE FILENAME BUFFER ADDRESS
         LDA   ADDR1+1    ; {3C2B} READ THE HIGH BYTE
         STA   ]FNBUF+1   ; {4C3B} AND STORE AS POINTER ADDRESS
         LDY   #30        ; {3C2B} INDEX TO FILE MANAGER WORKAREA
         LDA   (ADDR1),Y  ; {6C2B} FOR CONVENIENT STORAGE
         STA   ]FWORK     ; {4C3B} STORE WORKAREA POINTER
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   (ADDR1),Y  ; {6C2B} LOAD THE HIGH BYTE
         STA   ]FWORK+1   ; {4C3B} AND HOLD IT IN ]FWORK
         INY              ; {2C1B} POINTER TO T/S LIST SECTOR BUFF
         LDA   (ADDR1),Y  ; {6C2B} LOAD LOW BYTE OF TS BUFFER
         STA   ]FTSLS     ; {4C3B} HOLD POINTER IN MEMORY
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   (ADDR1),Y  ; {6C2B} LOAD HIGH BYTE
         STA   ]FTSLS+1   ; {4C3B} AND HOLD
         INY              ; {6C2B} INC POINTER TO DATA BUFFER
         LDA   (ADDR1),Y  ; {6C2B} LOAD LOW BYTE OF ADDRESS
         STA   ]FDATA     ; {4C3B} STORE IN MEMORY
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   (ADDR1),Y  ; {6C2B} LOAD THE HIGH BYTE
         STA   ]FDATA+1   ; {4C3B} AND STORE AS WELL
         CLC              ; {2C1B} CLR CARRY TO INDICATE NO ERR
         RTS              ; {6C1B}
:NBUF
         LDA   #0         ; {4C3B} LOAD #0 AND CLEAR OUT
         STA   ]FNBUF     ; {4C3B} ALL OF THE ADDRESS POINTERS
         STA   ]FNBUF+1   ; {4C3B}
         STA   ]FWORK     ; {4C3B}
         STA   ]FWORK+1   ; {4C3B}
         STA   ]FTSLS     ; {4C3B}
         STA   ]FTSLS+1   ; {4C3B}
         STA   ]FDATA     ; {4C3B}
         STA   ]FDATA+1   ; {4C3B}
         SEC              ; {2C1B} SET CARRY TO INDICATE ERR
         RTS              ; {6C1B}
*


THE _SETPBUFFS SUBROUTINE

SUMMARY

Condition Value
Name _SETPBUFFS
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Set the buffers in the File Manager Parameter List (FPL)
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 119+
Bytes 64
Notes none
See Also _FMBUFSCAN

DETAILS

The _SETPBUFFS subroutine sets the buffer addresses in the File Manager Parameter List (FPL) to the appropriate addresses in an open file buffer, as set by _FMBUFSCAN. The buffers set include the Filename Buffer, the TS/LS Buffer, Data Sector Buffer and the File Workarea Buffer.

The format of the FPL slightly changes depending on the command being called, and the number of minor differences are too many to list here for any useful purposes. For a detailed list of how the FPL is formatted according to call type, see Don Worth's and Pieter Lechner's Beneath Apple DOS. However, there is a general format to the FPL, as follows:

File Manager Parameter List (FPL)

Byte Description
00 Command/Call Type:
$01 = OPEN
$02 = CLOSE
$03 = READ
$04 = WRITE
$05 = DELETE
$06 = CATALOG
$07 = LOCK
$08 = UNLOCK
$09 = RENAME
$0A = POSITION
$0B = INIT
$0C = VERIFY
01 Sub-command/Sub-Call Type for READ or WRITE
$00 = No operation
$01 = READ or WRITE a byte
$02 = READ or WRITE a range of bytes
$03 = POSITION then READ or WRITE a byte
$04 = POSITION then READ or WRITE a range of bytes
02-09 Parameters change based on call type.
0A Return Code. Upon returning from the file manager, the CARRY flag is set to indicate a non-zero return code is present. The number here can then be accessed to further understand the return status.
$00 = No errors
$01 = Language Not Available
$02 = Bad call type
$03 = Bad sub-call type
$04 = Write protected
$05 = End of Data
$06 = File not found
$07 = Volume mismatch
$08 = Disk I/O error
$09 = Disk full
$0A = File locked
0B Unused
0C-0D Address of File Manager Workarea Buffer
0E-0F Address of the TS/LS Buffer
10-11 Address of the Data Sector Buffer

LISTING 6.04: HEAD.DOS.ASM _SETPBUFFS Routine Source

*
*``````````````````````````````*
* _SETPBUFFS    (NATHAN RIGGS) *
*                              *
* SET THE FILENAME BUFFER,     *
* TS/LS BUFFER, DATA BUFFER    *
* AND THE FILE WORKAREA        *
* BUFFER.                      *
*                              *
* INPUT                        *
*                              *
*  NONE.                       *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 119+                 *
* SIZE: 64 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_SETPBUFFS
*
         LDA   ]FPARM     ; {4C3B} GET PARAMATER ADDRESS LOW BYTE
         STA   ADDR1      ; {3C2B} AND HOLD IN ZERO PAGE
         LDA   ]FPARM+1   ; {4C3B} LOAD HIGH BYTE
         STA   ADDR1+1    ; {3C2B} INTO ZERO PAGE TOO
         LDY   #$10       ; {3C2B} POINT TO DATA BUFFER POINTER
         LDA   ]FDATA     ; {4C3B} LOAD DATA BUFFER ADDRESS LOW
         STA   (ADDR1),Y  ; {6C2B} COPY POINTER TO PARAM LOCATION
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   ]FDATA+1   ; {4C3B} LOAD DATA BUFFER ADDR HIGH BYTE
         STA   (ADDR1),Y  ; {6C2B} COPY TO PARAM LOCATION
         LDY   #$08       ; {3C2B} POINT TO FILENAME BUFFER
         LDA   ]FNBUF     ; {4C3B} LOAD FILENAME BUFFER POINTER ADDR
         STA   (ADDR1),Y  ; {6C2B} AND COPY TO PARAM LOCATION
         INY              ; {2C1B} INCREASE .Y POINTER
         LDA   ]FNBUF+1   ; {4C3B} LOAD THE HIGH BYTE
         STA   (ADDR1),Y  ; {6C2B} AND COPY AS WELL
         LDY   #$0E       ; {3C2B} T/S LIST SECTOR BUFFER POINTER
         LDA   ]FTSLS     ; {4C3B} LOAD CURRENT POINTER LOW BYTE
         STA   (ADDR1),Y  ; {6C2B} AND COPY TO PARAM LOCATION
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   ]FTSLS+1   ; {3C2B} LOAD THE HIGH BYTE
         STA   (ADDR1),Y  ; {6C2B} AND COPY TO PARAM LOCATION
         LDY   #$0C       ; {3C2B} WORKAREA BUFFER OFFSET IN PARAM
         LDA   ]FWORK     ; {4C3B} LOAD CURRENT WORKAREA POINTER
         STA   (ADDR1),Y  ; {6C2B} COPY TO PARAMETER LIST
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   ]FWORK+1   ; {4C3B} LOAD HIGH BYTE
         STA   (ADDR1),Y  ; {6C2B} AND COPY AS WELL
*
         RTS              ; {6C3B}
*

THE _NAMESTR SUBROUTINE

SUMMARY

Condition Value
Name _NAMESTR
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Copy filename from standard string format to the 30-byte string expected by DOS
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 64+
Bytes 42
Notes none
See Also _NAMESTR2 _FN2BUFF _FMNM2

DETAILS

The _NAMESTR subroutine is an internal procedure for transferring a standard preceding length-byte string to a temporary fixed 30-byte memory address that fills the empty bytes with spaces (this is determined by subtracting the string length from 30, which equals the number of trailing spaces needed). This subroutine should be called prior to calling the File Manager, given that the filename is not the same as the previous call.

LISTING 6.05: HEAD.DOS.ASM _NAMESTR Routine Source

*
*``````````````````````````````*
* _NAMESTR      (NATHAN RIGGS) *
*                              *
* COPY FILENAME FROM STANDARD  *
* STRING TO THE 30-BYTE STRING *
* EXPECTED BY DOS IN A TEMP    *
* MEMORY AREA.                 *
*                              *
* INPUT                        *
*                              *
*  .A = FILENAME STR ADDR LOW  *
*  .X = HIGH BYTE              *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 64+                  *
* SIZE: 42 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_NAMESTR
*
         LDY   #0         ; {3C2B}
         STA   ADDR1      ; {3C2B} CLEAR OUT ZERO LOCATION
         STX   ADDR1+1    ; {3C2B}
         LDA   (ADDR1),Y  ; {6C2B} GET STRING LENGTH
         STA   BPAR1      ; {3C2B} HOLD TEMP IN ZERO PAGE
         LDY   #0         ; {3C2B} RESET .Y INDEX
         LDX   #255       ; {3C2B} SET .X INDEX TO -1
:_NSLP1
         INX              ; {2C1B} INCREASE .X INDEX
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   (ADDR1),Y  ; {6C2B} GET CHARACTER
         STA   ]FNAME,X   ; {5C3B} STORE AT Y-1 LOC IN HOLD AREA
         CPX   #29        ; {3C2B} COMPARE TO MAX STRING LENGTH
         BEQ   :_NSEXIT   ; {3C2B} IF MAX IS REACHED, EXIT
         CPY   BPAR1      ; {3C2B} OTHERWISE COMPARE TO STRING LENGTH
         BNE   :_NSLP1    ; {3C2B} IF NOT EQUAL, RELOOP TO NEXT CHAR
:_NSLP2
         INX              ; {2C1B} STILL INCREASE .X INDEX
         LDA   #" " ; {4C3B} NEXT CHAR IS SPACE
         STA   ]FNAME,X   ; {5C3B} STORE IN NAME AREA AT .X
         CPX   #29        ; {3C2B} CHECK NEW STRING LENGTH
         BNE   :_NSLP2    ; {3C2B} IF < 30, KEEP LOOPING
:_NSEXIT
         RTS              ; {6C1B}
*

THE _NAMESTR2 SUBROUTINE

SUMMARY

Condition Value
Name _NAMESTR2
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Copy second filename from standard string
format to the 30-byte string expected by DOS
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 64+
Bytes 42
Notes none
See Also _NAMESTR _FN2BUFF _FMNM2

DETAILS

The _NAMESTR2 subroutine accomplishes the same task as _NAMESTR, but does so for a second filename that is needed for procedures like renaming a file. This subroutine will likely be merged with the _NAMESTR subroutine in future revisions.

LISTING 6.06: HEAD.DOS.ASM _NAMESTR2 Routine Source

*
*``````````````````````````````*
* _NAMESTR2     (NATHAN RIGGS) *
*                              *
* FULFILLS THE SAME FUNCTION   *
* AS _NAMESTR, EXCEPT FOR A    *
* SECOND STRING USED BY CMDS   *
* LIKE RENAME.                 *
*                              *
*  .A = STRING ADDR LOW BYTE   *
*  .X = STRING ADDR HIGH BYTE  *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 64+                  *
* SIZE: 42 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_NAMESTR2
*
         LDY   #0         ; {3C2B}
         STA   ADDR1      ; {3C2B} CLEAR OUT ZERO LOCATION
         STX   ADDR1+1    ; {3C2B}
         LDA   (ADDR1),Y  ; {6C3B} GET STRING LENGTH
         STA   BPAR1      ; {3C2B} HOLD TEMP IN ZERO PAGE
         LDY   #0         ; {3C2B} RESET .Y INDEX
         LDX   #255       ; {3C2B} SET .X INDEX TO -1
:_NSLP1
         INX              ; {2C1B} INCREASE .X INDEX
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   (ADDR1),Y  ; {6C2B} GET CHARACTER
         STA   ]FNAME2,X  ; {5C2B} STORE AT Y-1 LOC IN HOLD AREA
         CPX   #29        ; {3C2B} COMPARE TO MAX STRING LENGTH
         BEQ   :_NSEXIT   ; {3C2B} IF MAX IS REACHED, EXIT
         CPY   BPAR1      ; {3C2B} OTHERWISE COMPARE TO STRING LENGTH
         BNE   :_NSLP1    ; {3C2B} IF NOT EQUAL, RELOOP TO NEXT CHAR
:_NSLP2
         INX              ; {2C1B} STILL INCREASE .X INDEX
         LDA   #" " ; {4C3B} NEXT CHAR IS SPACE
         STA   ]FNAME2,X  ; {5C2B} STORE IN NAME AREA AT .X
         CPX   #29        ; {2C2B} CHECK NEW STRING LENGTH
         BNE   :_NSLP2    ; {3C2B} IF < 30, KEEP LOOPING
:_NSEXIT
         RTS              ; {6C1B}
*

THE _FN2BUFF SUBROUTINE

SUMMARY

Condition Value
Name _FN2BUFF
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Copy temporary 30-byte filename to the filename buffer.
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 41+
Bytes 22
Notes none
See Also _NAMESTR _NAMESTR2 _FMNM2

DETAILS

The _FN2BUFF subroutine simply copies the 30-byte filename created by _NAMESTR to the filename buffer for use by the File Manager.

LISTING 6.07: HEAD.DOS.ASM _FN2BUFF Routine Source

*
*``````````````````````````````*
* _FN2BUFF      (NATHAN RIGGS) *
*                              *
* MOVE THE TEMPORARY 30-BYTE   *
* FILENAME STRING INTO THE     *
* FILENAME BUFFER OF THE FILE  *
* BUFFER IN USE.               *
*                              *
* INPUT                        *
*                              *
*  NONE.                       *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
* CYCLES: 41+                  *
* SIZE: 22 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_FN2BUFF
*
         LDA   ]FNBUF     ; {4C3B} LOAD FILENAME BUFFER ADDR
         STA   ADDR2      ; {3C2B} STORE LOW IN ZERO
         LDA   ]FNBUF+1   ; {4C3B}
         STA   ADDR2+1    ; {3C2B} STORE HIGH IN ZERO
         LDY   #255       ; {3C2B} SET .Y INDEX TO -1
:_LPC1
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   ]FNAME,Y   ; {5C2B} GET CHAR STORED IN NAME AREA
         STA   (ADDR2),Y  ; {6C2B} STORE IN FILENAME BUFFER
         CPY   #29        ; {2C2B} IS THE END OF STRING REACHED?
         BNE   :_LPC1     ; {3C2B} IF NO, KEEP LOOPING
         RTS              ; {6C1B}
*

THE _FMNM2 SUBROUTINE

SUMMARY

Condition Value
Name _FMNM2
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Register the address of the second filename
to be used by the File Manager.
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 55+
Bytes 30
Notes none
See Also _NAMESTR _NAMESTR2 _FN2BUFF

DETAILS

The _FMNM2 subroutine is functionally equivalent to the _FN2BUFF subroutine except for a second filename, which is usually a destination filename. Although equivalent, the process for _FMNM2 is different than _FN2BUFF and therefore cannot be merged into a single subroutine.

LISTING 6.08: HEAD.DOS.ASM _FMNM2 Routine Source

*
*``````````````````````````````*
* _FMNM2        (NATHAN RIGGS) *
*                              *
* REGISTER THE ADDRESS OF THE  *
* SECOND FILENAME IN THE FILE  *
* PARAMETER LIST.              *
*                              *
* INPUT                        *
*                              *
*  NONE.                       *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
* CYCLES: 55+                  *
* SIZE: 30 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_FMNM2
         LDA   #]FNAME2   ; {3C2B}
         LDX   #>]FNAME2  ; {3C2B}
         STA   ADDR2      ; {3C2B} LOW BYTE OF REC ADDRESS IN .A
         STX   ADDR2+1    ; {3C2B} HIGH BYTE IN .X
         LDA   ]FPARM     ; {4C3B} LOAD PARAM ADDRESS
         STA   ADDR1      ; {3C2B} AND HOLD IN ZERO PAGE
         LDA   ]FPARM+1   ; {4C3B} ALSO DO FOR HIGH BYTE
         STA   ADDR1+1    ; {3C2B}
         LDY   #$02       ; {3C2B} OFFSET TO THE RECORD VARIABLE
         LDA   ADDR2      ; {3C2B} LOAD LOW BYTE
         STA   (ADDR1),Y  ; {6C2B} AND STORE IN PARAM LIST
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   ADDR2+1    ; {3C2B} LOAD HIGH BYTE
         STA   (ADDR1),Y  ; {6C2B} AND STORE IN PARAM LIST
         RTS              ; {6C1B}
*

THE _BUFFCLEAR SUBROUTINE

SUMMARY

Condition Value
Name _BUFFCLEAR
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Clear the current file buffer for use again.
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 31+
Bytes 17
Notes none
See Also _FMBUFFSCAN

DETAILS

The _BUFFCLEAR subroutine clears out the last used file buffer for use again in the future. It does this by replacing the first byte in the filename buffer with the value #$00, which indicates to DOS that the buffer is free. This subroutine should be called whenever a program is finished using a file and closes it; otherwise, the file buffer will not be cleared, and multiple uses of the file buffers will eventually result in error.

LISTING 6.09: HEAD.DOS.ASM _BUFFCLEAR Routine Source

*
*``````````````````````````````*
* _BUFFCLEAR    (NATHAN RIGGS) *
*                              *
* CLEAR THE FILE BUFFER THAT   *
* IS CURRENTLY IN USE SO THAT  *
* THE BUFFER MAY BE REUSED.    *
*                              *
* INPUT                        *
*                              *
*  NONE.                       *
*                              *
* CYCLES: 31+                  *
* SIZE: 17 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_BUFFCLEAR
*
         LDA   ]FNBUF     ; {4C3B} GET FILENAME BUFFER ADDR
         STA   ADDR2      ; {3C2B} STORE IN ZERO
         LDA   ]FNBUF+1   ; {4C3B} DO SAME FOR HIGH BYTE
         STA   ADDR2+1    ; {3C2B}
         LDA   #0         ; {3C2B} RESET .A
         TAY              ; {2C1B} AND .Y
         STA   (ADDR2),Y  ; {6C3B} STORE #00 IN FIRST SPOT
         RTS              ; {6C1B} TO INDICATE EMPTY BUFFER
*


THE _FMPSET SUBROUTINE

SUMMARY

Condition Value
Name _FMPSET
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Set a file parameter.
Input .A = Value
.Y = File Parameter Offset
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 30+
Bytes 16
Notes none
See Also _FMPSETA _FMPGET _FMPGETA

DETAILS

The _FMPSET subroutine sets a file parameter in the FPL indicated by the offset held in the .Y register to the value held in the .A register. This only sets a single byte.

LISTING 6.10: HEAD.DOS.ASM _FMPSET Routine Source

*
*``````````````````````````````*
* _FMPSET       (NATHAN RIGGS) *
*                              *
* SET A FILE PARAMTER TO THE   *
* VALUE HELD IN .A AT THE      *
* OFFSET INDICATED BY .Y.      *
*                              *
* INPUT                        *
*                              *
*  .A = VALUE                  *
*  .Y = FILE PARAMETER OFFSET  *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 30+                  *
* SIZE: 16 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_FMPSET
                          ; .Y HOLDS THE OFFSET
         TAX              ; {2C1B} .A HOLDS THE VALUE
         LDA   ]FPARM     ; {4C3B} LOAD FILE MGR PARAMETER LOW
         STA   ADDR1      ; {3C2B} HOLD ON ZERO PAGE
         LDA   ]FPARM+1   ; {4C3B} LOAD HIGH BYTE
         STA   ADDR1+1    ; {3C2B} ONTO ZERO PAGE
         TXA              ; {2C1B} RETURN VALUE BACK TO .A
         STA   (ADDR1),Y  ; {6C3B} STORE VALUE AT OFFSET IN PARAMS
         RTS              ; {6C1B}
*

THE _FMPSETA SUBROUTINE

SUMMARY

Condition Value
Name _FMPSETA
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Set a file parameter.
Input .A = Value Low Byte
.X = Value High Byte
.Y = File Parameter Offset
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 46+
Bytes 26
Notes none
See Also _FMPSET _FMPGET _FMPGETA

DETAILS

The _FMPSETA subroutine sets a file parameter address in the FPL indicated by the offset held in the .Y register to the value held in the .A register (low byte) and the .X register (high byte), setting a two consecutive bytes.

LISTING 6.11: HEAD.DOS.ASM _FMPSETA Routine Source

*
*``````````````````````````````*
* _FMPSETA      (NATHAN RIGGS) *
*                              *
* SET A TWO-BYTE VALUE, SUCH   *
* AS AN ADDRESS, IN THE FILE   *
* PARAMETER LIST.              *
*                              *
* INPUT                        *
*                              *
*  .A = LOWEST BYTE            *
*  .X = HIGHEST BYTE           *
*  .Y = OFFSET VALUE           *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 46+                  *
* SIZE: 26 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_FMPSETA
                          ; .Y HOLDS THE OFFSET
         STA   ADDR2      ; {3C2B} .A HOLDS LOW BYTE OF ADDR
         STX   ADDR2+1    ; {3C2B} .X HOLDS ADDR HIGH BYTE
         LDA   ]FPARM     ; {4C3B} LOAD FILE MGR PARAMETER LOW
         STA   ADDR1      ; {3C2B} HOLD ON ZERO PAGE
         LDA   ]FPARM+1   ; {4C3B} LOAD HIGH BYTE
         STA   ADDR1+1    ; {3C2B} ONTO ZERO PAGE
         LDA   ADDR2      ; {3C2B}
         STA   (ADDR1),Y  ; {6C3B} STORE VAL AT OFFSET IN PARAMS
         LDA   ADDR2+1    ; {3C2B}
         INY              ; {2C1B}
         STA   (ADDR1),Y  ; {6C3B}
         RTS              ; {6C1B}
*

THE _FMPGET SUBROUTINE

SUMMARY

Condition Value
Name _FMPGET
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Retrieve a file parameter from the FPL.
Input .Y = File Parameter Offset
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 26+
Bytes 14
Notes none
See Also _FMPGETA _FMPSET _FMPSETA

DETAILS

The _FMPGET subroutine retrieves a single byte from a given parameter in the FPL, as indicated by the offset held in .Y.

LISTING 6.12: HEAD.DOS.ASM _FMPGET Routine Source

*
*``````````````````````````````*
* _FMPGET       (NATHAN RIGGS) *
*                              *
* GET A VALUE RETURNED FROM    *
* THE FILE MANAGER AFTER IT    *
* RUNS. THIS VALUE IS HELD AT  *
* AN OFFSET IN THE FILE PARAM  *
* LIST.                        *
*                              *
* INPUT:                       *
*                              *
*  .Y = OFFSET TO READ         *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 26+                  *
* SIZE: 14 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_FMPGET
                          ; OFFSET IS PASSED IN .Y
         LDA   ]FPARM     ; {4C3B}
         STA   ADDR1      ; {3C2B}
         LDA   ]FPARM+1   ; {4C3B}
         STA   ADDR1+1    ; {3C2B}
         LDA   (ADDR1),Y  ; {6C3B} VALUE RETURNED IN .A
         RTS              ; {6C1B}
*

THE _FMPGETA SUBROUTINE

SUMMARY

Condition Value
Name _FMPGETA
Type Subroutine
File HEAD.DOS.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Retrieve a two-byte address file parameter from the FPL.
Input .Y = File Parameter Offset
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 42+
Bytes 21
Notes none
See Also _FMPGET _FMPSET _FMPSETA

DETAILS

The _FMPGETA subroutine retrieves two consecutive bytes from the offset held in .Y in the FPL. This is usually an address; the low byte is returned in .A and the high byte is returned in .X.

LISTING 6.13: HEAD.DOS.ASM _FMPGETA Routine Source

*
*``````````````````````````````*
* _FMPGETA      (NATHAN RIGGS) *
*                              *
* RETRIEVE A 2-BYTE VALUE LIKE *
* AN ADDRESS FROM THE FILE     *
* PARAMETER LIST AT THE GIVEN  *
* OFFSET.                      *
*                              *
* INPUT                        *
*                              *
*  .Y = OFFSET INDEX           *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 42+                  *
* SIZE: 21 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_FMPGETA
                          ; OFFSET PASSED IN .Y
         LDA   ]FPARM     ; {4C3B}
         STA   ADDR1      ; {3C2B}
         LDA   ]FPARM+1   ; {4C3B}
         STA   ADDR1+1    ; {3C2B}
         LDA   (ADDR1),Y  ; {6C3B} GET LOW BYTE
         PHA              ; {3C1B} HOLD ON STACK
         INY              ; {2C1B} INCREASE INDEX
         LDA   (ADDR1),Y  ; {6C3B} GET HIGH BYTE
         TAX              ; {2C1B} PASS BACK IN .X
         PLA              ; {3C1B} PASS LOW IN .A
         RTS              ; {6C1B}
*

Required DOS Macros

The MAC.DOSREQ.ASM file contains various macros that are required to be included (USE) in order for the entire DOS collection to function. This is unlike other collections, which usually do not require a separate macro file that the other macros and subroutines depend upon. While these macros could be replaced in each macro and subroutine with the appropriate code, the Merlin 8 Pro compiler would quickly run into memory management issues due to limitations on file size.

Most of these macros call a combination of the subroutines found in the HEAD.DOS.ASM file, and should be used in place of calling the subroutines directly.

LISTING 6.20: MAC.DOSREQ.ASM Heading Source

*
*``````````````````````````````*
* MAC.DOSREQ.ASM               *
*                              *
* THESE MACROS ARE REQUIRED    *
* FOR USING THE DOS MACROS AND *
* SUBROUTINES. GENERALLY, THIS *
* INCLUDES LOW LEVEL ROUTINES  *
* AND MACRO SHORTCUTS TO SAVE  *
* MEMORY DURING ASSEMBLY.      *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      06-MAY-2021       *
* ASSEMBLER: MERLIN 8 PRO      *
* OS:        DOS 3.3           *
*                              *
* SUBROUTINE FILES USED        *
*                              *
*                              *
* LIST OF MACROS               *
*                              *
* SRWTS : SET RWTS PARAMETERS  *
* GRWTS : RUN RWTS ROUTINE     *
* FMFIL : FILL FILE MGR PARAMS *
* FMNAM : STRING TO PARAM AREA *
* FRWB  : BYTE READ/WRITE MAC  *
* FWRTB : WRITE A BYTE TO FILE *
* FRDB  : READ BYTE FROM FILE  *
* FRWR  : RANGE READ/WRITE MAC *
* FRDR  : READ RANGE FROM FILE *
* FWRTR : WRITE RANGE TO FILE  *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*

THE SRWTS MACRO

SUMMARY

Condition Value
Name SRWTS
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Set common RWTS parameters.
Input ]1 = Slot
]2 = Drive
]3 = Volume
]4 = Track
]5 = Sector
]6 = Buffer Address
]7 = Command
Output none
Dependencies _SETRWTS
Flags Destroyed NZCV
Cycles 228+
Bytes 141
Notes none
See Also _SETRWTS

DETAILS

The SRWTS macro sets the most common parameters used in the IOB before calling the RWTS routine. This includes the slot, drive, volume, track, sector, buffer address and RWTS command. If the volume is set to #0, then any volume will be acceptable for RWTS.

LISTING 6.21: MAC.DOSREQ.ASM SRWTS Macro Source

*
*``````````````````````````````*
* SETRWTS                      *
*                              *
* SET THE PARAMETERS FOR RWTS. *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = RWTS SLOT              *
*  ]2 = RWTS DRIVE             *
*  ]3 = RWTS VOLUME            *
*  ]4 = RWTS TRACK             *
*  ]5 = RWTS SECTOR            *
*  ]6 = RWTS BUFFER            *
*  ]7 = RWTS COMMAND           *
*                              *
* CYCLES: 228+                 *
* SIZE: 141 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
SRWTS    MAC
         LDA   ]1         ; {4C3B} RWTS SLOT
         STA   MSLOT      ; {4C3B}
         LDA   ]2         ; {4C3B} RWTS DRIVE
         STA   MDRIVE     ; {4C3B}
         LDA   ]3         ; {4C3B} RWTS VOLUME
         STA   MVOL       ; {4C3B}
         LDA   ]4         ; {4C3B} RWTS TRACK
         STA   MTRACK     ; {4C3B}
         LDA   ]5         ; {4C3B} RWTS SECTOR
         STA   MSECTOR    ; {4C3B}
         IF    #=]6       ; IF VALUE IS A LITERAL
         LDA   ]6         ; {4C3B} THEN STORE LITERAL
         STA   MBUFFER    ; {4C3B} LOW AND HIGH BYTES
         LDA   ]6/$100    ; {4C3B}
         STA   MBUFFER+1  ; {4C3B}
         ELSE             ; OTHERWISE,
         LDA   ]6         ; {4C3B} LOAD VALUE FROM ADDRESS
         STA   MBUFFER    ; {4C3B} AND STORE IN BUFFER
         LDA   ]6+1       ; {4C3B} ADDRESS POINTER
         STA   MBUFFER+1  ; {4C3B}
         FIN
         LDA   ]7         ; {4C3B} RWTS COMMAND
         STA   MCMD       ; {4C3B}
         JSR   _SETRWTS   ; {148C81B} SET THE PARAMETERS
         <<<
*

THE GRWTS MACRO

SUMMARY

Condition Value
Name GRWTS
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Run the DOS RWTS Routine.
Input none
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 19+
Bytes 11
Notes none
See Also SRWTS

DETAILS

The GRWTS macro simply runs the RWTS routine found in DOS. At the very least, the SRWTS macro should be called beforehand to set the various parameters used by RWTS.

LISTING 6.22: MAC.DOSREQ.ASM GRWTS Macro Source

*
*``````````````````````````````*
* GRWTS                        *
*                              *
* RUN THE RWTS ROUTINE.        *
*                              *
* PARAMETERS                   *
*                              *
*  NONE.                       *
*                              *
* CYCLES: 19+                  *
* SIZE: 11 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
GRWTS    MAC
         JSR   ]LOCRPL    ; {6C3B} (GET ]LOCRPL CYCLES/SIZE)
         JSR   ]RWTS      ; {6C3B} (GET CYCLES/SIZE)
         LDA   #0         ; {3C2B}
         STA   $48        ; {4C3B} FIX P REG FOR DOS
         <<<
*

THE FMFIL MACRO

SUMMARY

Condition Value
Name FMFIL
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Fill the most common parameters in the FPL.
Input ]1 = Command
]2 = Slot
]3 = Drive
]4 = Volume
]5 = Record Number
Output none
Dependencies _FMGETPARM _FMBUFFSCAN _SETPBUFFS _FMPSET _FMPSETA
Flags Destroyed NZCV
Cycles 603+
Bytes 303
Notes none
See Also SRWTS FMNAM

DETAILS

The FMFIL macro fills out the most common parameters used in the File Parameter List (FPL). This includes the file command, slot, drive, volume, and record number. Note that not all of these are applicable to every use. Like with SRWTS, the volume can be set to #0 to indicate that any volume is acceptable.

LISTING 6.23: MAC.DOSREQ.ASM FMFIL Macro Source

*
*``````````````````````````````*
* FMFIL         (NATHAN RIGGS) *
*                              *
* FILLS THE MOST COMMON AREAS  *
* IN THE FILE PARAMETERS. THIS *
* INCLUDES THE COMMAND, SLOT,  *
* DISK, VOLUME AND RECORD.     *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = COMMAND                *
*  ]2 = SLOT                   *
*  ]3 = DRIVE                  *
*  ]4 = VOLUME (0 FOR ANY)     *
*  ]5 = RECORD NUMBER          *
*                              *
* CYCLES: 603+                 *
* SIZE: 303 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FMFIL    MAC
         JSR   _FMGETPARM ; {26C13B} GET FILE PARAMS ADDRESS
         JSR   _FMBUFFSCAN ; {217C120B} SCAN FOR FREE FILE BUFF
         JSR   _SETPBUFFS ; {125C67B} SET PARAMETER BUFFERS
         LDA   ]1         ; {4C3B} COMMAND TO PARAMETERS
         LDY   #]P_CMD    ; {3C2B} SET INDEX TO COMMAND OFFSET
         JSR   _FMPSET    ; {36C19B} SET COMMAND
         LDA   ]2         ; {4C3B} SLOT TO PARAMETERS
         LDY   #]P_SLOT   ; {3C2B} SET INDEX TO SLOT OFFSET
         JSR   _FMPSET    ; {36C19B} SET SLOT
                          ; VOLUME AND RECORD NUMBER
         LDA   ]3         ; {4C3B} DRIVE TO PARAMETERS
         LDY   #]P_DRV    ; {3C2B} SET INDEX TO DRIVE OFFSET
         JSR   _FMPSET    ; {36C19B} SET DRIVE
         LDA   ]4         ; {4C3B} VOLUME TO PARAMS, 0 FOR ANY
         LDY   #]P_VOL    ; {3C2B} SET INDEX TO VOLUME OFFSET
         JSR   _FMPSET    ; {36C19B} SET VOLUME
         _AXLIT ]5        ; {8C6B}
         LDY   #]P_REC    ; {3C2B} SET INDEX TO RECORD OFFSET
         JSR   _FMPSETA   ; {52C29B} SET RECORD LOW AND HIGH
         <<<
*

THE FMNAM MACRO

SUMMARY

Condition Value
Name FMNAM
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Copy a string with a preceding length-byte to the filename buffer.
Input ]1 = Source string address
Output none
Dependencies _NAMESTR _FN2BUFF
Flags Destroyed NZCV
Cycles 117+
Bytes 70
Notes none
See Also FMFIL

DETAILS

The FMNAM macro copies a string with a preceding length-byte into a 30-byte memory location, filling the unused bytes in the destination with spaces. This is then copied to the Filename Buffer in a currently used file buffer. This filename is used for commands such as deletion, verification, opening and closing, and so on. This is also used with the renaming command, with the addition of a destination filename.

LISTING 6.24: MAC.DOSREQ.ASM FMNAM Macro Source

*
*``````````````````````````````*
* FMNAM         (NATHAN RIGGS) *
*                              *
* COPY A STRING HOLDING THE    *
* NAME OF A FILE BEING HANDLED *
* TO A 30-BYTE LOCATION FILLED *
* WITH SPACES, THEN COPY THAT  *
* TO THE FILE PARAMETER LIST.  *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = ADDRESS OF STRING      *
*                              *
* CYCLES: 117+                 *
* SIZE: 70 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FMNAM    MAC
         _AXLIT ]1
         JSR   _NAMESTR   ; {70C45B} COPY STRING TO TEMP BUFF
         JSR   _FN2BUFF   ; {47C25B} COPY TEMP BUFF TO FNAME BUFF
         <<<
*

THE FRWB MACRO

SUMMARY

Condition Value
Name FRWB
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Read or write a byte in a file.
Input ]1 = Read/Write flag
]2 = Command
]3 = Slot
]4 = Drive
]5 = Volume
]6 = Record Number
]7 = Byte offset
]8 = Byte to write, if writing
Output none
Dependencies FMFIL _FMPSET _FMPSETA
Flags Destroyed NZCV
Cycles 779+
Bytes 404
Notes none
See Also FWRTB FRDB FRWR FRDR FWRTR

DETAILS

The FRWB Macro either reads or writes a single byte in an open file, depending on which flag is provided the macro in the first parameter. Usually, this macro is used internally, rather than by the end user; the FWRTB macro and the FRDB macro are used instead to write and read a byte in a file. If writing, the eighth parameter is set to the byte to write; if not, this parameter is ignored. It should also be noted that this macro does not return a value when reading a byte; instead, this is handled by the FRDB macro, as the byte is returned by the file manager in the File Parameter List (FPL).

As usual, a #0 value can be passed to the volume parameter to indicate that any volume is acceptable.

LISTING 6.25: MAC.DOSREQ.ASM FRWB Macro Source

*
*``````````````````````````````*
* FRWB          (NATHAN RIGGS) *
*                              *
* EITHER READ OR WRITE A BYTE. *
* THIS USUALLY ISN'T CALLED    *
* DIRECTLY, BUT THROUGH        *
* ANOTHER MACRO.               *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = READ/WRITE FLAG (#3/4) *
*  ]2 = COMMAND                *
*  ]3 = SLOT                   *
*  ]4 = DRIVE                  *
*  ]5 = VOLUME (0 FOR ANY)     *
*  ]6 = RECORD NUMBER          *
*  ]7 = BYTE OFFSET            *
*  ]8 = BYTE TO WRITE (0 READ) *
*                              *
* CYCLES: 779+                 *
* SIZE: 404 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FRWB     MAC
*
         FMFIL ]2;]3;]4;]5;]6 ; {603C303B}
*
         LDA   ]1         ; {4C3B} READ OR WRITE FLAG
         LDY   #]P_RDWR   ; {3C2B} INDEX TO READ/WRITE FLAG
         JSR   _FMPSET    ; {30C16B} SET THE READ/WRITE FLAG
         LDA   #]SC_PRWB  ; {3C2B} SET POS THEN READ OR WRITE
         LDY   #]P_SUBC   ; {3C2B} SET INDEX TO SUBCODE OFFSET
         JSR   _FMPSET    ; {30C16B} SET THE SUBCODE
         _AXLIT ]7        ; {8C6B}
         LDY   #]P_BOFF   ; {3C2B} INDEX TO BYTE OFFSET
         JSR   _FMPSETA   ; {46C26B} SET TWO BYTE OFFSET VALUE
         LDA   ]8         ; {4C3B} BYTE TO WRITE, IF WRITING
         LDY   #]P_BYTE   ; {3C2B} WRITE BYTE
         JSR   _FMPSET    ; {30C16B} SET BYTE
         LDX   #1         ; {3C2B} DON'T CREATE NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN FILE MANAGER
         <<<
*

THE FWRTB MACRO

SUMMARY

Condition Value
Name FWRTB
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Write a byte to a file.
Input ]1 = Slot
]2 = Drive
]3 = Volume
]4 = Record number
]5 = Byte offset
]6 = Byte to write
Output none
Dependencies _FMPGET _BUFFCLEAR
Flags Destroyed NZCV
Cycles 665+
Bytes 337
Notes none
See Also FRWB FRDB FRWR FRDR FWRTR FOPEN FCLOS

DETAILS

The FWRTB macro is used for writing a single byte at a time to an open file. Like with most File Manager operations, a value of #0 placed in the volume parameter indicates that any volume is acceptable.

Records in files work much the same way as they do in Applesoft BASIC: each record in a file is separated by a carriage return (#$8D), with the zeroth record being the first string of text prior to the first carriage return. These are usually used with text files, which are only marginally supported by the DOS collection: binary files make much more sense to use in Assembly, even when the data itself represents text characters. This is not to say that text files cannot be used--the FOPEN macro allows you to read and write text files--but that it is better for the end programmer to devise his or her own system for dealing with text files, as there is no standard method for recognizing an End-of-File (EOF) marker. Both binary files and text files can be fully read into memory before being parsed by a given routine.

The byte offset is particularly useful with FWRTB, as without it only the first byte of the file could be written. A byte counter can be used to read or write each consecutive byte at a time, passing the counter value via the offset.

The FOPEN macro should be called before FWRTB, and the FCLOS macro should be called when all operations on the file are finished.

LISTING 6.26: MAC.DOSREQ.ASM FWRTB Macro Source

*
*``````````````````````````````*
* FWRTB         (NATHAN RIGGS) *
*                              *
* WRITE A BYTE TO A FILE.      *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = SLOT                   *
*  ]2 = DRIVE                  *
*  ]3 = VOLUME                 *
*  ]4 = RECORD NUMBER          *
*  ]5 = BYTE OFFSET            *
*  ]6 = BYTE TO WRITE (0 READ) *
*                              *
* CYCLES: 665+                 *
* SIZE: 337 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FWRTB    MAC
*
** FRWB ARGUMENTS
**
** ]1 = READ OR WRITE CODE (3 = READ, 4 = WRITE)
** ]2 = READ OR WRITE COMMAND
** ]3 = SLOT
** ]4 = DRIVE
** ]5 = VOLUME (0 FOR ANY)
** ]6 = RECORD NUMBER
** ]7 = BYTE OFFSET
** ]8 = BYTE TO WRITE, IF WRITING
*
         FRWB  #4;#]FC_WRIT;]1;]2;]3;]4;]5;]6 ; {603C303B}
*
         LDY   #]P_RETC   ; {3C2B} INDEX TO RETURN CODE OFFSET
         JSR   _FMPGET    ; {26C14B} GET THE RETURN CODE
         TAX              ; {2C1B} PASS BACK IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFFER FOR USE
         <<<
*

THE FRDB MACRO

SUMMARY

Condition Value
Name FRDB
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Read a byte from a file.
Input ]1 = Slot
]2 = Drive
]3 = Volume
]4 = Record number
]5 = Byte offset
]6 = Byte to write (always 0)
Output none
Dependencies _FMPGET _BUFFCLEAR
Flags Destroyed NZCV
Cycles 700+
Bytes 357
Notes none
See Also FRWB FWRTB FRWR FRDR FWRTR

DETAILS

The FRDB macro reads a byte from an open file and returns the byte in the .A register. If the volume is set to #0, any volume will be accepted.

Records in files work much the same way as they do in Applesoft BASIC: each record in a file is separated by a carriage return (#$8D), with the zeroth record being the first string of text prior to the first carriage return. These are usually used with text files, which are only marginally supported by the DOS collection: binary files make much more sense to use in Assembly, even when the data itself represents text characters. This is not to say that text files cannot be used--the FOPEN macro allows you to read and write text files--but that it is better for the end programmer to devise his or her own system for dealing with text files, as there is no standard method for recognizing an End-of-File (EOF) marker. Both binary files and text files can be fully read into memory before being parsed by a given routine.

The byte offset is particularly useful with FRDB, as without it only the first byte of the file could be read. A byte counter can be used to read or write each consecutive byte at a time, passing the counter value via the offset.

The FOPEN macro should be called before FWRTB, and the FCLOS macro should be called when all operations on the file are finished.

LISTING 6.27: MAC.DOSREQ.ASM FRDB Macro Source

*
*``````````````````````````````*
* FRDB          (NATHAN RIGGS) *
*                              *
* READ A BYTE FROM A FILE.     *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = SLOT                   *
*  ]2 = DRIVE                  *
*  ]3 = VOLUME                 *
*  ]4 = RECORD NUMBER          *
*  ]5 = BYTE OFFSET            *
*  ]6 = BYTE TO WRITE (0 READ) *
*                              *
* CYCLES: 700+                 *
* SIZE: 357 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FRDB     MAC
*
** FWRB ARGUMENTS
**
** ]1 = READ OR WRITE CODE (3 = READ, 4 = WRITE)
** ]2 = READ OR WRITE COMMAND
** ]3 = SLOT
** ]4 = DRIVE
** ]5 = VOLUME (0 FOR ANY)
** ]6 = RECORD NUMBER
** ]7 = BYTE OFFSET
** ]8 = BYTE TO WRITE, IF WRITING
*
         FRWB  #3;#]FC_READ;]1;]2;]3;]4;]5;]6 ; {603C303B}
*
         LDY   #]P_BYTE   ; {3C2B} INDEX TO BYTE TO READ
         JSR   _FMPGET    ; {26C14B} GET BYTE IN THE PARAMETERS
         STA   BPAR1      ; {3C2B} HOLD IN ZERO PAGE
         LDY   #]P_RETC   ; {3C2B} INDEX TO THE RETURN CODE OFFSET
         JSR   _FMPGET    ; {26C14B} GET THE RETURN CODE
         TAX              ; {2C1B} PASS BACK IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFFER FOR USE
         LDA   BPAR1      ; {3C2B} PASS READ BYTE IN .A
         <<<
*

THE FRWR MACRO

SUMMARY

Condition Value
Name FRWR
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Read or write a range of bytes in a file.
Input ]1 = READ/WRITE flag
]2 = Command
]3 = Slot
]4 = Drive
]5 = Volume
]6 = Record number
]7 = Byte offset
]8 = Range Address
]TEMP = Range length
Output none
Dependencies _FMPSET _FMPSETA
Flags Destroyed NZCV
Cycles 846+
Bytes 451
Notes none
See Also FRWB FWRTB FRDB FRDR FWRTR

DETAILS

The FRWR macro reads or writes a range of bytes from or to an open file, with the Range Address either containing the bytes to be written up to the specified length or the memory area to store the bytes read from the file at the given length. It is notable that because Merlin 8 Pro can only handle eight built-in variables (]1 - ]8), the ]TEMP variable is used to pass the range length. Additionally, and like usual, a value of #0 in the volume parameter indicates that any volume number is valid.

For the most part, this macro is meant to be used internally. The end user should use the FRDR macro for reading a range of bytes and the FWRTR macro for writing a range of bytes.

LISTING 6.28: MAC.DOSREQ.ASM FRWR Macro Source

*
*``````````````````````````````*
* FRWR          (NATHAN RIGGS) *
*                              *
* READ OR WRITE A RANGE.       *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = READ/WRITE FLAG        *
*  ]2 = COMMAND                *
*  ]3 = SLOT                   *
*  ]4 = DRIVE                  *
*  ]5 = VOLUME                 *
*  ]6 = RECORD NUMBER          *
*  ]7 = BYTE OFFSET            *
*  ]8 = RANGE ADDRESS          *
*  ]TEMP = RANGE LENGTH        *
*                              *
* CYCLES: 846+                 *
* SIZE: 451 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FRWR     MAC
*
** SET THE COMMAND, SLOT, DRIVE, VOLUME AND RECORD NUMBER
*
         FMFIL ]2;]3;]4;]5;]6 ; {603C303B}
*
         LDA   ]1         ; {4C3B} LOAD READ OR WRITE FLAG
         LDY   #]P_RDWR   ; {3C2B} INDEX TO RD/WRT FLAG OFFSET
         JSR   _FMPSET    ; {30C16B} SET READ OR WRITE FLAG
         LDA   #]SC_PRWR  ; {3C2B} SUBCODE FOR POS AND READ/WRITE
         LDY   #]P_SUBC   ; {3C2B} INDEX TO SUBCODE OFFSET
         JSR   _FMPSET    ; {30C16B} SET SUBCODE
         _AXLIT ]7        ; {8C6B}
         LDY   #]P_BOFF   ; {3C2B} INDEX TO BYTE OFFSET
         JSR   _FMPSETA   ; {46C26B} SET BYTE OFFSET
         _AXLIT ]8        ; {8C6B}
         LDY   #]P_RADDR  ; {3C2B} INDEX TO RANGE ADDR OFFSET
         JSR   _FMPSETA   ; {46C26B} SET RANGE ADDRESS
         LDA   ]TEMP      ; {4C3B} GET RANGE LENGTH
         LDX   ]TEMP+1    ; {4C3B} LOW BYTE AND HIGH BYTE
         LDY   #]P_RLEN   ; {3C2B} INDEX TO RANGE LENGTH OFFSET
         JSR   _FMPSETA   ; {46C26B} SET RANGE LENGTH
         LDX   #1         ; {3C2B} DON'T CREATE NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN FILE MANAGER
         <<<
*

THE FRDR MACRO

SUMMARY

Condition Value
Name FRDR
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Read a range of bytes from a file.
Input ]1 = Slot
]2 = Drive
]3 = Volume
]4 = Record number
]5 = Byte offset
]6 = Range address
]7 = Range length
Output none
Dependencies _FMPGET FRWR _BUFFCLEAR
Flags Destroyed NZCV
Cycles 697+
Bytes 361
Notes none
See Also FRWB FWRTB FRDB FRWR FWRTR

DETAILS

The FRDR macro reads a range of bytes from an open file, storing the range starting at the given range address through to the given range length (two bytes). As per the collection standard, a value of #0 in the volume parameter indicates that any volume number is valid.

Records in files work much the same way as they do in Applesoft BASIC: each record in a file is separated by a carriage return (#$8D), with the zeroth record being the first string of text prior to the first carriage return. These are usually used with text files, which are only marginally supported by the DOS collection: binary files make much more sense to use in Assembly, even when the data itself represents text characters. This is not to say that text files cannot be used--the FOPEN macro allows you to read and write text files--but that it is better for the end programmer to devise his or her own system for dealing with text files, as there is no standard method for recognizing an End-of-File (EOF) marker. Both binary files and text files can be fully read into memory before being parsed by a given routine.

The byte offset is used to start reading or writing the range at a particular location in the file.

The FOPEN macro should be called before FRDR, and the FCLOS macro should be called when all operations on the file are finished.

LISTING 6.29: MAC.DOSREQ.ASM FRDR Macro Source

*
*``````````````````````````````*
* FRDR          (NATHAN RIGGS) *
*                              *
* READ A RANGE FROM A FILE.    *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = SLOT                   *
*  ]2 = DRIVE                  *
*  ]3 = VOLUME                 *
*  ]4 = RECORD NUMBER          *
*  ]5 = BYTE OFFSET            *
*  ]6 = RANGE ADDRESS          *
*  ]7 = RANGE LENGTH           *
*                              *
* CYCLES: 697+                 *
* SIZE: 361 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FRDR     MAC
         IF    #=]7       ; IF RANGE ADDR IS A LITERAL
         LDA   ]7/$100    ; {4C3B} THEN LOAD HIGH BYTE
         STA   ]TEMP+1    ; {4C3B} AND STORE
         LDA   ]7         ; {4C3B} AND LOAD LOW BYTE
         STA   ]TEMP      ; {4C3B} AND STORE IN TEMP
         ELSE
         LDA   ]7+1       ; {4C3B} LOAD HIGH BYTE
         STA   ]TEMP+1    ; {4C3B} STORE HIGH BYTE
         LDA   ]7         ; {4C3B} LOAD LOW BYTE
         STA   ]TEMP      ; {4C3B} STORE LOW BYTE
         FIN
*
         FRWR  #3;#]FC_READ;]1;]2;]3;]4;]5;]6 ; {603C303B}
*
         LDY   #]P_RETC   ; {3C2B} INDEX TO RETURN CODE
         JSR   _FMPGET    ; {26C14B} GET RETURN CODE
         TAX              ; {2C1B} HOLD IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFFER FOR USE
         <<<
*

THE FWRTR MACRO

SUMMARY

Condition Value
Name FWRTR
Type Macro
File MAC.DOSREQ.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Write a range of bytes to a file.
Input ]1 = Slot
]2 = Drive
]3 = Volume
]4 = Record number
]5 = Byte offset
]6 = Range address
]7 = Range length
Output none
Dependencies _FMPGET FRWR _BUFFCLEAR
Flags Destroyed NZCV
Cycles 940+
Bytes 509
Notes none
See Also FRWB FWRTB FRDB FRWR FRDR

DETAILS

The FWRTR macro writes to an open file a range of bytes found at a given starting range address through a given range length. As per the collection standard, a value of #0 in the volume parameter indicates that any volume number is valid.

Records in files work much the same way as they do in Applesoft BASIC: each record in a file is separated by a carriage return (#$8D), with the zeroth record being the first string of text prior to the first carriage return. These are usually used with text files, which are only marginally supported by the DOS collection: binary files make much more sense to use in Assembly, even when the data itself represents text characters. This is not to say that text files cannot be used--the FOPEN macro allows you to read and write text files--but that it is better for the end programmer to devise his or her own system for dealing with text files, as there is no standard method for recognizing an End-of-File (EOF) marker. Both binary files and text files can be fully read into memory before being parsed by a given routine.

The byte offset is used to start reading or writing the range at a particular location in the file.

The FOPEN macro should be called before FWRTR, and the FCLOS macro should be called when all operations on the file are finished.

LISTING 6.30: MAC.DOSREQ.ASM FWRTR Macro Source

*
*``````````````````````````````*
* FWRTR         (NATHAN RIGGS) *
*                              *
* WRITE A RANGE TO A FILE.     *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = SLOT                   *
*  ]2 = DRIVE                  *
*  ]3 = VOLUME                 *
*  ]4 = RECORD NUMBER          *
*  ]5 = BYTE OFFSET            *
*  ]6 = RANGE ADDRESS          *
*  ]7 = RANGE LENGTH           *
*                              *
* CYCLES: 940+                 *
* SIZE: 509 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FWRTR    MAC
         IF    #=]7       ; IF RANGE LENGTH IS A LITERAL THEN
         LDA   ]7/$100    ; {4C3B} LOAD HIGH BYTE
         STA   ]TEMP+1    ; {4C3B} AND STORE IN TEMP
         LDA   ]7         ; {4C3B} LOAD LOW BYTE
         STA   ]TEMP      ; {4C3B} AND STORE IN TEMP
         ELSE             ; OTHERWISE
         LDA   ]7+1       ; {4C3B} LOAD HIGH BYTE
         STA   ]TEMP+1    ; {4C3B} AND STORE IN TEMP
         LDA   ]7         ; {4C3B} LOAD LOW BYTE
         STA   ]TEMP      ; {4C3B} AND STORE IN TEMP
         FIN
*
         FRWR  #4;#]FC_WRIT;]1;]2;]3;]4;]5;]6 ; {846C451B}
*
         LDY   #]P_RETC   ; {3C2B} INDEX TO RETURN CODE
         JSR   _FMPGET    ; {26C14B} GET RETURN CODE
         TAX              ; {2C1B} PASS BACK IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFFER FOR USE
         <<<
*

DOS File Manager Macros

The MAC.DOSFM.ASM file contains various macros that are used for most file operations. Currently, this includes disk cataloging, locking and unlocking files, deleting files, verifying files, opening and closing files, reading and writing files (both text and binary), renaming files, and bloading and bsaving binary files. Additionally, subroutines are provided for using DOS's RWTS routine for low-level access to a disk, though this is mostly limited to reading and writing bytes in a given track and sector.

It should be noted that all of these macros need to have both the HEAD.DOS.ASM file and the MAC.DOSREQ.ASM file included (PUT and USE, respectively) in order to function properly (or, rather, at all).

LISTING 6.40: MAC.DOSFM.ASM Heading Source

*
*``````````````````````````````*
* MAC.DOSFM.ASM                *
*                              *
* THIS FILE CONTAINS MACROS    *
* USED TO INTERFACE TO THE DOS *
* FILE MANAGER. NOTE THE       *
* FOLLOWING:                   *
*                              *
* 1) THIS COLLECTION CURRENTLY *
* HAS A LOT OF OVERHEAD DUE TO *
* THE TIGHTLY INTEGRATED       *
* NATURE OF THE FILE MANAGER.  *
*                              *
* 2) THIS COLLECTION IS THE    *
* ONLY ONE IN THE LIBRARY THAT *
* ALLOWS FOR USING THE MACROS  *
* WITHIN THE SUBROUTINES, SAVE *
* FOR THE REQUIRED COLLECTION. *
* THIS IS TO MAKE EACH OF THE  *
* SUBROUTINES MORE LEGIBLE, AS *
* JUST THE ACT OF PASSING      *
* VARIABLES TO OTHER ROUTINES  *
* CAN TAKE UP A SIGNIFICANT    *
* NUMBER OF BYTES.             *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      20-APR-2021       *
* ASSEMBLER: MERLIN 8 PRO      *
* OS:        DOS 3.3           *
*                              *
* SUBROUTINE FILES USED        *
*                              *
*                              *
* LIST OF MACROS               *
*                              *
* FCAT  : CATALOG              *
* FULCK : UNLOCK FILE          *
* FLOCK : LOCK FILE            *
* FDEL  : DELETE FILE          *
* FVFY  : VERIFY FILE          *
* FCLOS : CLOSE FILE           *
* FRENM : RENAME FILE          *
* FOPEN : OPEN FILE            *
* BLOAD : LOAD BINARY FILE     *
* BSAVE : SAVE BINARY FILE     *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*

THE FCAT MACRO

SUMMARY

Condition Value
Name FCAT
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Catalog the disk.
Input ]1 = Slot
]2 = Drive
Output A disk catalog to the screen.
Dependencies _FMFIL _FMPGET _BUFFCLEAR
Flags Destroyed NZCV
Cycles 657+
Bytes 348
Notes none
See Also none

DETAILS

The FCAT macro simply requests a disk catalog to be printed to the text screen. This macro does not provide any way to manipulate the data present in the Volume Table of Contents (VTOC); this feature will be added as a separate macro in later revisions of the collection.

LISTING 6.41: MAC.DOSFM.ASM FCAT Macro Source

*
*``````````````````````````````*
* FCAT          (NATHAN RIGGS) *
*                              *
* SIMPLY LIST THE DISK CATALOG *
* TO THE SCREEN.               *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = SLOT                   *
*  ]2 = DRIVE                  *
*                              *
* CYCLES: 657+                 *
* SIZE: 348 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FCAT     MAC
*
         FMFIL #]FC_CAT;]1;]2;#0;#0 ; {603C303B} SET CMD SLOT DRIVE
*
         LDX   #1         ; {3C2B} DON'T CREATE NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN THE FILE MANAGER
         LDY   #]P_RETC   ; {3C2B} SET INDEX TO RETURN CODE
         JSR   _FMPGET    ; {32C17B} GET RETURN CODE FROM PARAMS
         TAX              ; {2C1B} HOLD CODE IN .X
         JSR   _BUFFCLEAR ; {37C20B} CLEAR THE FILE BUFF FOR USE
         <<<
*

THE FULCK MACRO

SUMMARY

Condition Value
Name FULCK
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Unlock a file.
Input ]1 = Filename address
]2 = Slot
]3 = Drive
Output none.
Dependencies _FMFIL FMNAM _FMPGET _BUFFCLEAR
Flags Destroyed NZCV
Cycles 629+
Bytes 353
Notes none
See Also FLOCK

DETAILS

The FULCK macro unlocks a file with the specified filename.

LISTING 6.42: MAC.DOSFM.ASM FULCK Macro Source

*
*``````````````````````````````*
* FULCK         (NATHAN RIGGS) *
*                              *
* UNLOCK A FILE.               *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = FILENAME STR ADDRESS   *
*  ]2 = SLOT                   *
*  ]3 = DRIVE                  *
*                              *
* CYCLES: 629+                 *
* SIZE: 353 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FULCK    MAC
*
         FMFIL #]FC_UNLK;]2;]3;#0;#0 ; {603C303B}
*
         FMNAM ]1         ; {4C3B} SET FILENAME
         LDX   #1         ; {4C3B} DON'T CREATE A NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN FILE MANAGER
         LDY   #]P_RETC   ; {4C3B} SET INDEX TO RETURN CODE
         JSR   _FMPGET    ; {32C17B} GET RETURN CODE FROM PARAMS
         TAX              ; {2C1B} HOLD IN .X
         JSR _BUFFCLEAR   ; {37C20B} CLEAR FILE BUFF FOR USE
         <<<
*

THE FLOCK MACRO

SUMMARY

Condition Value
Name FLOCK
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Lock a file.
Input ]1 = Filename address
]2 = Slot
]3 = Drive
Output none.
Dependencies _FMFIL FMNAM _FMPGET _BUFFCLEAR
Flags Destroyed NZCV
Cycles 172+
Bytes 116
Notes none
See Also FULCK

DETAILS

The FLOCK macro locks a file with the specified filename.

LISTING 6.43: MAC.DOSFM.ASM FLOCK Macro Source

*
*``````````````````````````````*
* FLOCK         (NATHAN RIGGS) *
*                              *
* LOCK A FILE.                 *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = FILENAME STR ADDRESS   *
*  ]2 = SLOT                   *
*  ]3 = DRIVE                  *
*                              *
* CYCLES: 172+                 *
* SIZE: 116 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FLOCK    MAC
*
*
         FMFIL #]FC_LOCK;]2;]3;#0;#0 ; {603C303B}
*
         FMNAM ]1         ; {117C70B} SET FILENAME
         LDX   #1         ; {4C3B} DON'T CREATE A NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN FILE MANAGER
         LDY   #]P_RETC   ; {3C2B} SET INDEX TO RETURN CODE
         JSR   _FMPGET    ; {32C17B} GET RETURN CODE FROM PARAMS
         TAX              ; {2C1B} HOLD IN .X
         JSR _BUFFCLEAR   ; {37C20B} CLEAR FILE BUFF FOR USE
         <<<
*

THE FDEL MACRO

SUMMARY

Condition Value
Name FDEL
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Delete a file.
Input ]1 = Filename address
]2 = Slot
]3 = Drive
Output none.
Dependencies _FMFIL FMNAM _FMPGET _BUFFCLEAR
Flags Destroyed NZCV
Cycles 791+
Bytes 412
Notes none
See Also none

DETAILS

The FDEL macro deletes a file with the specified filename.

LISTING 6.44: MAC.DOSFM.ASM FDEL Macro Source

*
*``````````````````````````````*
* FDEL          (NATHAN RIGGS) *
*                              *
* DELETE A FILE.               *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = FILENAME STR ADDRESS   *
*  ]2 = SLOT                   *
*  ]3 = DRIVE                  *
*                              *
* CYCLES: 791+                 *
* SIZE: 412 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FDEL     MAC
*
         FMFIL #]FC_DEL;]2;]3;#0;#0 ; {603C303B}
*
         FMNAM ]1         ; {117C70B} SET FILE NAME
         LDX   #1         ; {3C2B} DON'T CREATE NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN FILE MANAGER
         LDY   #]P_RETC   ; {3C2B} SET INDEX TO RETURN CODE
         JSR   _FMPGET    ; {26C14B} GET CODE FROM PARAMS
         TAX              ; {2C1B} HOLD IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFF FOR USE
         <<<
*

THE FVFY MACRO

SUMMARY

Condition Value
Name FVFY
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Verify a file.
Input ]1 = Filename address
]2 = Slot
]3 = Drive
Output none.
Dependencies _FMFIL FMNAM _FMPGET _BUFFCLEAR
Flags Destroyed NZCV
Cycles 791+
Bytes 411
Notes none
See Also none

DETAILS

The FVFY macro verifies a file with the specified filename.

LISTING 6.45: MAC.DOSFM.ASM FVFY Macro Source

*
*``````````````````````````````*
* FVFY          (NATHAN RIGGS) *
*                              *
* VERIFY A FILE.               *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = FILENAME STR ADDRESS   *
*  ]2 = SLOT                   *
*  ]3 = DRIVE                  *
*                              *
* CYCLES: 791+                 *
* SIZE: 411 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FVFY     MAC
*
         FMFIL #]FC_VFY;]2;]3;#0;#0 ; {603C303B}
*
         FMNAM ]1         ; {117C70B} SET FILE NAME
         LDX   #1         ; {3C2B} DON'T CREATE A NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN THE FILE MANAGER
         LDY   #]P_RETC   ; {3C2B} SET INDEX TO RETURN CODE
         JSR   _FMPGET    ; {26C14B} GET CODE FROM PARAMETERS
         TAX              ; {2C1B} HOLD IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFF FOR USE
         <<<
*

THE FCLOS MACRO

SUMMARY

Condition Value
Name FCLOS
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Close a file.
Input ]1 = Filename address
]2 = Slot
]3 = Drive
Output none.
Dependencies _FMFIL FMNAM _FMPGET _BUFFCLEAR
Flags Destroyed NZCV
Cycles 797+
Bytes 415
Notes none
See Also none

DETAILS

The FCLOS macro closes a file with the specified filename.

LISTING 6.46: MAC.DOSFM.ASM FCLOS Macro Source

*
*``````````````````````````````*
* FCLOS         (NATHAN RIGGS) *
*                              *
* CLOSE A FILE.                *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = FILENAME STR ADDRESS   *
*  ]2 = SLOT                   *
*  ]3 = DRIVE                  *
*                              *
* CYCLES: 797+                 *
* SIZE: 415 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FCLOS    MAC
*
         FMFIL #]FC_CLOS;]2;]3;#0;#0 ; {603C303B}
*
         FMNAM ]1         ; {117C70B} SET FILENAME
         LDX   #1         ; {3C2B} DON'T CREATE NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN FILE MANAGER
         LDY   #]P_RETC   ; {3C2B} SET INDEX TO RETURN CODE
         JSR   _FMPGET    ; {32C17B} GET RETURN CODE
         TAX              ; {2C1B} AND HOLD IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFF FOR USE
         <<<
*

THE FRENM MACRO

SUMMARY

Condition Value
Name FRENM
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Rename a file.
Input ]1 = Filename address
]2 = New filename address
]3 = Slot
]4 = Drive
Output none.
Dependencies _FMFIL FMNAM _FMPGET _BUFFCLEAR _FMNM2
Flags Destroyed NZCV
Cycles 927+
Bytes 578
Notes none
See Also none

DETAILS

The FRENM macro renames a file with the filename given in the first parameter to the filename given in the second parameter.

LISTING 6.47: MAC.DOSFM.ASM FRENM Macro Source

*
*``````````````````````````````*
* FRENM         (NATHAN RIGGS) *
*                              *
* RENAME A FILE.               *
*                              *
* PARAMETER                    *
*                              *
*  ]1 = FILENAME STR ADDRESS   *
*  ]2 = NEW NAME STR ADDRESS   *
*  ]3 = SLOT                   *
*  ]4 = DRIVE                  *
*                              *
* CYCLES: 927+                 *
* SIZE: 578 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FRENM    MAC
*
         FMFIL #]FC_REN;]3;]4;#0;#0 ; {603C303B}
*
         FMNAM ]1         ; {117C70B} SET FILENAME
         _AXLIT ]2        ; {8C6B}
         JSR   _NAMESTR2  ; {64C42B} COPY TO 2ND FILENAME BUFF
         JSR _FMNM2       ; {64C42B} SET ADDRESS IN PARAMS
         LDX   #1         ; {3C2B} DON'T CREATE NEW FILE
         JSR   ]FMRUN     ; {6C3B} RUN FILE MANAGER
         LDY   #]P_RETC   ; {3C2B} SET INDEX TO RETURN CODE
         JSR   _FMPGET    ; {26C14B} GET RETURN CODE
         TAX              ; {2C1B} AND HOLD IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFFER FOR USE
         <<<
*

THE FOPEN MACRO

SUMMARY

Condition Value
Name FOPEN
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Open a file.
Input ]1 = Filename address
]2 = Slot
]3 = Drive
]4 = Volume
]5 = Record
]6 = File type
Output none.
Dependencies _FMFIL FMNAM _FMPGET _BUFFCLEAR _FMPSET
Flags Destroyed NZCV
Cycles 828+
Bytes 433
Notes none
See Also FCLOS

DETAILS

The FOPEN macro opens a file for reading or writing, which is determined by the FRDB, FWRTB, FRDR and FWRTR macros. Beyond opening the file for use, FOPEN determines the type of file that will be read or written to. The following table describes which type of file corresponds to the value passed in parameter number six, along with a variable name to be used in place of a number for ease of use:

Value Variable Name File Type
$00 TYP_TXT Text File
$01 TYP_INT Integer BASIC File
$02 TYP_APP Applesoft BASIC File
$04 TYP_BIN Binary File
$08 TYP_REL Relocatable File
$10 TYP_S S Type File
$20 TYP_A A Type File
$40 TYP_B B Type File

LISTING 6.48: MAC.DOSFM.ASM FOPEN Macro Source

*
*``````````````````````````````*
* FOPEN         (NATHAN RIGGS) *
*                              *
* OPEN FILE FOR READ OR WRITE. *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = FILENAME STR ADDRESS   *
*  ]2 = SLOT                   *
*  ]3 = DRIVE                  *
*  ]4 = VOLUME (0 FOR ANY)     *
*  ]5 = RECORD NUMBER          *
*  ]6 = FILE TYPE              *
*                              *
* CYCLES: 828+                 *
* SIZE: 433 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
FOPEN    MAC
*
         FMFIL #]FC_OPEN;]2;]3;]4;]5 ; {603C303B}
*
         LDA   ]6         ; {4C3B} FILE TYPE IF NEW FILE
         LDY   #]P_TYPE   ; {3C2B} SET TYPE FOR WRITING
         JSR   _FMPSET    ; {30C16B}
         FMNAM ]1         ; {117C70B} SET THE FILENAME
         LDX   #0         ; {3C2B} NEW FILE ON OPEN
         JSR   ]FMRUN     ; {6C3B} RUN FILE MANAGER
         LDY   #]P_RETC   ; {3C2B} SET INDEX TO RETURN CODE OFFSET
         JSR   _FMPGET    ; {26C14B} GET RETURN CODE
         TAX              ; {2C1B} HOLD IT IN .X
         JSR   _BUFFCLEAR ; {31C17B} CLEAR FILE BUFFER FOR USE
         <<<
*

THE BLOAD MACRO

SUMMARY

Condition Value
Name BLOAD
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Binary-load a file.
Input ]1 = Filename address
]2 = Loading address
]3 = Slot
]4 = Drive
]5 = Volume
Output none.
Dependencies FBLOAD
Flags Destroyed NZCV
Cycles 3768+
Bytes 2735
Notes none
See Also BSAVE FBSAVE FBLOAD

DETAILS

The BLOAD macro loads the contents of a binary file into memory either at a specified address or, if the address passed is #$0000, at the address stored in the start of the file. Like with all properly saved binary file, both the default address and the file byte-length is stored in the first four bytes of the file; these are not copied to the specified location. The length is passed back to the calling program via the .A register (low) and .X register (high).

LISTING 6.49: MAC.DOSFM.ASM BLOAD Macro Source

*
*``````````````````````````````*
* BLOAD         (NATHAN RIGGS) *
*                              *
* LOAD A MACHINE LANGUAGE FILE *
* INTO MEMORY AT A SPECIFIED   *
* ADDRESS. IF THE ADDRESS IS   *
* #0000, THEN USE THE DEFAULT  *
* ADDRESS PROVIDED AT THE      *
* START OF THE FILE. THE FILE  *
* LENGTH IS ALSO HELD AT THE   *
* BEGINNING OF THE FILE, SO    *
* THERE IS NO NEED TO PASS IT  *
* HERE. THIS LENGTH IS PASSED  *
* BACK TO THE USER VIA THE     *
* .A (LOW) AND .X (HIGH)       *
* REGISTERS.                   *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = FILENAME STRING ADDR   *
*  ]2 = LOADING ADDRESS        *
*  ]3 = SLOT                   *
*  ]4 = DRIVE                  *
*  ]5 = VOLUME                 *
*                              *
* DESTROYS: NZCIDV             *
*           ^^^  ^             *
*                              *
* CYCLES: 3768+                *
* SIZE: 2735 BYTES             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
BLOAD    MAC
         _MLIT ]1;WPAR1   ; {16C12B} PARSE STRING ADDRESS
         _MLIT ]2;WPAR2   ; {16C12B} PARSE LOAD ADDRESS
         LDA   ]3         ; {4C3B} LOAD SLOT
         STA   BPAR1      ; {3C2B} AND STORE ON ZERO
         LDA   ]4         ; {4C3B} LOAD DRIVE
         STA   BPAR2      ; {3C2B} AND STORE ON ZERO
         LDA   ]5         ; {4C3B} LOAD VOLUME
         STA   BPAR3      ; {3C2B} AND STORE ON ZERO
         JSR   FBLOAD     ; {3715C2696B} RUN FBLOAD SUBROUTINE
         <<<
*

THE FBLOAD SUBROUTINE

SUMMARY

Condition Value
Name FBLOAD
Type Subroutine
File SUB.FBLOAD.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Binary-load a file.
Input WPAR1 = Filename string address
WPAR2 = Loading Address
BPAR1 = Slot
BPAR2 = Drive
BPAR3 = Volume
Output none.
Dependencies none
Flags Destroyed NZCV
Cycles 3715+
Bytes 2696
Notes none
See Also BSAVE FBSAVE BLOAD

DETAILS

The FBLOAD subroutine loads a binary file into the designated memory address, with the length being determined by a preceding length-byte in the file. If the memory address passed is #$0000, then the default address found in the first two bytes of the file is used in place of the address passed. These first four bytes of the file, signifying the default memory address and the length of the range in bytes, are not copied along with the rest of the file.

The length of the data is store in .A (low byte) and .X (high byte), as well as in RETURN. RETLEN carries #$02.

LISTING 6.50: SUB.FBLOAD.ASM Source

*
*``````````````````````````````*
* FBLOAD        (NATHAN RIGGS) *
*                              *
* BLOAD A FILE'S MACHINE       *
* LANGUAGE CONTENTS TO A GIVEN *
* MEMORY RANGE. NOTE THAT THE  *
* FIRST FOUR BYTES OF A BIN    *
* FILE CONTAINS THE LOADING    *
* ADDRESS (TWO BYTES) AND THE  *
* LENGTH OF THE CODE (TWO      *
* BYTES). IF THE ADDRESS       *
* EQUALS #0000, THEN THESE     *
* VALUES WILL BE USED INSTEAD. *
*                              *
* INPUT                        *
*                              *
*  WPAR1 = FILENAME STR ADDR   *
*  WPAR2 = LOAD ADDRESS        *
*  BPAR1 = SLOT                *
*  BPAR2 = DRIVE               *
*  BPAR3 = VOLUME              *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 3715+                *
* SIZE: 2696 BYTES             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]FNSTR EQU WPAR1 ; FILENAME STRING
]LDADDR EQU WPAR2 ; LOADING ADDRESS
]FLEN EQU WPAR3 ; FILE LENGTH
]SLOT EQU BPAR1
]DRIVE EQU BPAR2
]VOL EQU BPAR3
]FLDADDR EQU ADDR4 ; ADDRESS STORED IN FILE
*
FBLOAD
*
** FIRST, READ FIRST TWO BYTES TO GET THE
** DEFAULT ADDRESS. IF THE ADDRESS PASSED IS
** #0000, THEN THE DEFAULT ADDRESS IS USED INSTEAD.
*
 FOPEN ]FNSTR;]SLOT;]DRIVE;]VOL;#0;#]TYP_BIN ; {828C433B}
 FRDB ]SLOT;]DRIVE;#0;#0;#0;#0 ; {700C357B}
 STA ]FLDADDR ; {4C3B}
 FRDB ]SLOT;]DRIVE;#0;#0;#1;#0 ; {700C357B}
 STA ]FLDADDR+1 ; {4C3B}
*
** NOW GET THE LENGTH OF THE FILE. THEORETICALLY,
** THIS SHOULDN'T INCLUDE THE FIRST 4 BYTES?
*
 FRDB ]SLOT;]DRIVE;#0;#0;#2;#0 ; {700C357B}
 STA ]FLEN ; {4C3B}
 FRDB ]SLOT;]DRIVE;#0;#0;#3;#0 ; {700C357B}
 STA ]FLEN+1 ; {4C3B}
*
** IF PASSED ADDRESS IS ZERO, THEN USE THE
** DEFAULT ADDRESS. OTHERWISE, COPY THE PASSED
** ADDRESS INTO THE DEFAULT ADDRESS VARIABLE.
*
 LDA ]LDADDR ; {4C3B}
 CMP #0 ; {3C2B}
 BNE :SET ; {3C2B}
 LDA ]LDADDR+1 ; {4C3B}
 CMP #0 ; {3C2B}
 BNE :SET ; {3C2B}
 JMP :SKIP ; {633B}
:SET
 LDA ]LDADDR ; {4C3B}
 STA ]FLDADDR ; {4C3B}
 LDA ]LDADDR+1 ; {4C3B}
 STA ]FLDADDR+1 ; {4C3B}
*
** NOW READ THE RANGE OF THE ENTIRE FILE AND
** STORE IT IN MEMORY AT THE APPROPRIATE LOCATION.
*
:SKIP
 FRDR ]SLOT;]DRIVE;#0;#0;#4;]FLDADDR;]FLEN ; {697C361B}
 FCLOS ]FNSTR;]SLOT;]DRIVE ; {797C415B}
*
 LDA ]FLEN ; {4C3B} LOAD LENGTH LOW BYTE
 STA RETURN ; {4C3B} AND HOLD IN .A AND RETURN
 LDX ]FLEN+1 ; {4C3B} LOAD LENGTH HIGH BYTE
 STA RETURN+1 ; {4C3B} AND HOLD IN .X AND RETURN+1
 LDY #2 ; {3C2B} LOAD BYTE LENGTH OF RETURN
 STY RETLEN ; {4C3B} AND STORE IN RETLEN
 RTS ; {6C1B}
*

THE BSAVE MACRO

SUMMARY

Condition Value
Name BSAVE
Type Macro
File MAC.DOSFM.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Binary-save a range of memory.
Input ]1 = Filename address
]2 = Loading address
]3 = Range length
]4 = Slot
]5 = Drive
]6 = Volume
Output none.
Dependencies FBSAVE
Flags Destroyed NZCV
Cycles 5300+
Bytes 2758
Notes none
See Also BLOAD FBSAVE FBLOAD

DETAILS

The BSAVE macro stores a range of memory from a starting address to a given byte-length in a binary file, holding the starting address in the first two bytes of the file and the range length in the third and fourth bytes. This is how all binary files are stored in DOS, or should be stored.

LISTING 6.51: MAC.DOSFM.ASM BSAVE Macro Source

*
*``````````````````````````````*
* BSAVE         (NATHAN RIGGS) *
*                              *
* STORES A MEMORY RANGE IN A   *
* FILE STARTING AT THE LOADING *
* ADDRESS AND CONTINUING FOR   *
* THE GIVEN RANGE LENGTH. THE  *
* FIRST TWO BYTES OF THE FILE  *
* HOLD THE LOADING ADDRESS,    *
* AND THE 3RD AND 4TH BYTES    *
* HOLD THE RANGE LENGTH.       *
*                              *
* PARAMETERS                   *
*                              *
*  ]1 = FILENAME STRING ADDR   *
*  ]2 = LOADING ADDRESS        *
*  ]3 = RANGE LENGTH           *
*  ]4 = SLOT                   *
*  ]5 = DRIVE                  *
*  ]6 = VOLUME                 *
*                              *
* DESTROYS: NZCIDV             *
*           ^^^  ^             *
*                              *
* CYCLES: 5300+                *
* SIZE: 2758 BYTES             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
BSAVE    MAC
         _MLIT ]1;WPAR1   ; {16C12B} PARSE STRING ADDRESS
         _MLIT ]2;WPAR2   ; {16C12B} PARSE LOAD ADDRESS
         _MLIT ]3;WPAR3   ; {16C12B}
         LDA   ]4         ; {4C3B} LOAD SLOT
         STA   BPAR1      ; {3C2B} AND STORE ON ZERO
         LDA   ]5         ; {4C3B} LOAD DRIVE
         STA   BPAR2      ; {3C2B} AND STORE ON ZERO
         LDA   ]6         ; {4C3B} LOAD VOLUME
         STA   BPAR3      ; {3C2B} AND STORE ON ZERO
         JSR   FBSAVE     ; {5231C2707B} RUN FBLOAD SUBROUTINE
         <<<
*

THE FBSAVE SUBROUTINE

SUMMARY

Condition Value
Name FBSAVE
Type Subroutine
File SUB.FBSAVE.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Binary-save a file.
Input WPAR1 = Filename string address
WPAR2 = Loading Address
WPAR3 = Range length
BPAR1 = Slot
BPAR2 = Drive
BPAR3 = Volume
Output none.
Dependencies none
Flags Destroyed NZCV
Cycles 3715+
Bytes 2696
Notes none
See Also BSAVE FBLOAD BLOAD

DETAILS

The FBSAVE subroutine saves a memory range to a binary file that starts at a given address. The first two bytes of the file holds the starting address, while the next two bytes hold the range length.

LISTING 6.52: SUB.FBSAVE.ASM Source

*
*``````````````````````````````*
* FBSAVE        (NATHAN RIGGS) *
*                              *
* THIS SUBROUTINE TAKES AN     *
* ADDRESS AND A BYTE LENGTH,   *
* THEN SAVES THAT MEMORY RANGE *
* TO A FILE. THE FIRST TWO     *
* BYTES HOLD THE ADDRESS WHERE *
* THE MEMORY WAS STORED, AND   *
* THE THIRD AND FOURTH BYTES   *
* OF THE FILE HOLD THE LENGTH  *
* OF THE FILE (NOT INCLUDING   *
* THE FOUR PRECEDING BYTES).   *
*                              *
* INPUT                        *
*                              *
*  WPAR1 = FILENAME STR ADDR   *
*  WPAR2 = LOAD ADDRESS        *
*  WPAR3 = RANGE LENGTH        *
*  BPAR1 = SLOT                *
*  BPAR2 = DRIVE               *
*  BPAR3 = VOLUME              *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 5231+                *
* SIZE: 2707 BYTES             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]FNSTR   EQU   WPAR1
]LDADDR  EQU   WPAR2
]FLEN    EQU   WPAR3
]SLOT    EQU   BPAR1
]DRIVE   EQU   BPAR2
]VOL     EQU   BPAR3
*
FBSAVE
*
** FIRST, OPEN THE FILE FOR BINARY WRITING
*
         FOPEN ]FNSTR;]SLOT;]DRIVE;]VOL;#0;#]TYP_BIN ; {828C433B}
*
** NEXT, STORE THE STARTING ADDRESS OF THE
** MEMORY RANGE AT THE FIRST TWO BYTES OF THE FILE.
*
         FWRTB ]SLOT;]DRIVE;]VOL;#0;#0;]LDADDR ; {665C337B}
         FWRTB ]SLOT;]DRIVE;]VOL;#0;#1;]LDADDR+1 ; {665C337B}
*
** NOW STORE THE LENGTH IN THE THIRD AND FOURTH
** BYTES OF THE FILE.
*
         FWRTB ]SLOT;]DRIVE;]VOL;#0;#2;]FLEN ; {665C337B}
         FWRTB ]SLOT;]DRIVE;]VOL;#0;#3;]FLEN+1 ; {665C337B}
*
** THEN STORE THE MEMORY RANGE IN THE FILE, OFFSETTING
** BY FOUR TO ACCOUNT FOR THE PRECEDING ADDRESS AND
** LENGTH BYTES.
*
         FWRTR ]SLOT;]DRIVE;]VOL;#0;#4;]LDADDR;]FLEN ; {940C509B}
*
** CLOSE FILE, RETURN TO CALLER
*
         FCLOS ]FNSTR;]SLOT;]DRIVE {797C416B}
         RTS              ; {6C1B}


Miscellaneous DOS Macros

The MAC.DOSMORE.ASM file contains macros that are primarily concerned with DOS functions but are not required and do not fit neatly in with file management. This includes macros for checking the DOS version, verifying if DOS or Applesoft is loaded, and macros for telling if an Applesoft or Integer BASIC program is running.

LISTING 6.60: MAC.DOSMORE.ASM Heading

*
*``````````````````````````````*
* MAC.DOSMORE.ASM              *
*                              *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      20-APR-2021       *
* ASSEMBLER: MERLIN 8 PRO      *
* OS:        DOS 3.3           *
*                              *
* SUBROUTINE FILES USED        *
*                              *
* NONE                         *
*                              *
* LIST OF MACROS               *
*                              *
* DVER  : CHECK DOS VERSION    *
* DOSIN : CHECK IF DOS LOADED  *
* ABAS  : IS APPLESOFT LOADED  *
* IBEX  : IS INTEGER BASIC     *
*         PROGRAM RUNNING      *
* ABEX  : IS APPLESOFT BASIC   *
*         PROGRAM RUNNING      *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*

THE DVER MACRO

SUMMARY

Condition Value
Name DVER
Type Macro
File MAC.DOSMORE.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Check the DOS version
Input none
Output none.
Dependencies none
Flags Destroyed NZCV
Cycles 28+
Bytes 18
Notes none
See Also none

DETAILS

The DVER macro checks the current version of DOS in memory and returns the version number in the .A register.

LISTING 6.61: MAC.DOSMORE.ASM DVER Macro Source

*
*``````````````````````````````*
* DVER          (NATHAN RIGGS) *
*                              *
* RETURN THE DOS VERSION. THIS *
* IS ADAPTED FROM DON WORTH'S  *
* AND PIETER LECHNER'S         *
* /BENEATH APPLE DOS/. THE     *
* LICENSE MAY ACCORDINGLY      *
* VARY.                        *
*                              *
* PARAMETERS                   *
*                              *
*  NONE                        *
*                              *
* CYCLES: 28                   *
* SIZE: 18 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
DVER     MAC
         CLC              ; {2C1B} CLEAR CARRY FLAG
         LDA   #0         ; {3C2B} CLEAR ACCUMULATOR
         ADC   #$BE       ; {2C2B} ADD #$16BE TO DOS LOAD POINT
         STA   ADDR1      ; {3C2B} STORE LOW BYTE
         LDA   $3D2       ; {4C3B} LOAD DOS LOADING POINT
         ADC   #$16       ; {2C2B} ADD OFFSET
         STA   ADDR1+1    ; {3C2B} STORE HIGH BYTE
         LDY   #0         ; {3C2B} SET INDEX TO 0
         LDA   (ADDR1),Y  ; {6C2B} RETURNS #2 OR #3 FOR
                          ; THE DOS VERSION IN .A
         <<<
*

THE DOSIN MACRO

SUMMARY

Condition Value
Name DOSIN
Type Macro
File MAC.DOSMORE.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Check if DOS is loaded
Input none
Output none.
Dependencies none
Flags Destroyed NZCV
Cycles 17+
Bytes 12
Notes none
See Also none

DETAILS

The DOSIN macro checks if DOS is currently loaded into memory. The CARRY flag is set if DOS is loaded, and it is cleared if DOS is not loaded.

LISTING 6.62: MAC.DOSMORE.ASM DOSIN Macro Source

*
*``````````````````````````````*
* DOSIN                        *
*                              *
* CHECKS IF DOS IS LOADED.     *
* THIS SHOULD BE CALLED BEFORE *
* RUNNING RWTS OR THE FILE     *
* MANAGER.                     *
*                              *
* THIS IS ADAPTED FROM DON     *
* WORTH'S AND PIETER LECHNER'S *
* /BENEATH APPLE DOS/, SO THE  *
* LICENSE MAY VARY ACCORDINGLY *
*                              *
* PARAMETERS                   *
*                              *
*  NONE                        *
*                              *
* CYCLES: 17                   *
* SIZE: 12 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
DOSIN    MAC
         LDA   $3D0       ; {4C3B} GET VECTOR JUMP
         CMP   #$4C       ; {3C2B} IS IT A JUMP?
         BNE   ]NODOS     ; {3C2B} NOPE, JUMP TO NONE
         SEC              ; {2C1B} CARRY SET, MEANING DOS LOADED
         JMP   ]EXIT      ; {3C3B}
]NODOS
         CLC              ; {2C1B} CARRY CLEAR, MEANING NO DOS
]EXIT
         <<<
*

THE ABAS MACRO

SUMMARY

Condition Value
Name ABAS
Type Macro
File MAC.DOSMORE.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Find out which BASIC system is loaded
Input none
Output none.
Dependencies none
Flags Destroyed NZCV
Cycles 40+
Bytes 29
Notes none
See Also none

DETAILS

The ABAS macro determines whether it is Applesoft BASIC or Integer BASIC that is currently loaded. If Applesoft BASIC is loaded, then the CARRY is set; if it is Integer BASIC loaded, then the CARRY is cleared.

LISTING 6.63: MAC.DOSMORE.ASM ABAS Macro Source

*
*``````````````````````````````*
* ABAS                         *
*                              *
* DETERMINE WHICH BASIC IS     *
* LOADED. IF CARRY IS CLEAR,   *
* THEN INTEGER BASIC IS        *
* LOADED--ELSE, APPLESOFT IS.  *
*                              *
* THIS IS ADAPTED FROM DON     *
* WORTH'S AND PIETER LECHNER'S *
* /BENEATH APPLE DOS/, SO THE  *
* LICENSE MAY VARY ACCORDINGLY *
*                              *
* PARAMETERS                   *
*                              *
*  NONE                        *
*                              *
* CYCLES: 40                   *
* SIZE: 29 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
ABAS     MAC
         LDA   #$4C       ; {4C3B} CODE FOR APPLESOFT
                          ; #$20 IS FOR INTEGER BASIC
         CMP   $E000      ; {4C3B} CORRECT BASIC ALREADY THERE?
         BEQ   ]APPLES    ; {3C2B} YES, GOTO RETURN CARRY
         STA   $C080      ; {4C3B} NOW IS IT THERE?
         CMP   $E000      ; {4C3B} NOW IS IT THERE?
         BEQ   ]APPLES    ; {3C2B} YEP, GOTO RETURN CARRY
         STA   $C081      ; {4C3B} STILL NO, TRY ROM CARD
         CMP   $E000      ; {4C3B} THERE NOW?
         BEQ   ]APPLES    ; {3C2B} YEP, GOTO RETURN CARRY
                          ; NOPE, DON'T RETURN CARRY
         CLC              ; {2C1B}
         JMP   ]EXIT      ; {3C3B}
]APPLES
         SEC              ; {2C1B}
]EXIT
         <<<
*

THE IBEX MACRO

SUMMARY

Condition Value
Name IBEX
Type Macro
File MAC.DOSMORE.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Check if an Integer BASIC program is running
Input none
Output none.
Dependencies none
Flags Destroyed NZCV
Cycles 17+
Bytes 12
Notes none
See Also none

DETAILS

The IBEX macro sets the CARRY flag if an Integer BASIC program is currently running; otherwise, the CARRY is cleared.

LISTING 6.64: MAC.DOSMORE.ASM IBEX Macro Source

*
*``````````````````````````````*
* IBEX                         *
*                              *
* CHECK IF AN INTEGER BASIC    *
* PROGRAM IS RUNNING.          *
*                              *
* THIS IS ADAPTED FROM DON     *
* WORTH'S AND PIETER LECHNER'S *
* /BENEATH APPLE DOS/, SO THE  *
* LICENSE MAY VARY ACCORDINGLY *
*                              *
* PARAMETERS                   *
*                              *
*  NONE                        *
*                              *
* CYCLES: 17                   *
* SIZE: 12 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
IBEX     MAC
         LDA   $D9        ; {4C3B} CHECK BASIC
         BMI   ]YES       ; {3C2B} IF NEG, THEN INT BASIC RUNNING
         BPL   ]NO        ; {3C2B} IF POSITIVE, THEN NOT
]YES
         SEC              ; {2C1B} INT BASIC RUNNING, SET CARRY
         JMP   ]EXIT      ; {3C3B} AND EXIT
]NO
         CLC              ; {2C1B} NOT RUNNING, SO CLEAR CARRY
]EXIT                     ; AND EXIT
         <<<
*

THE ABEX MACRO

SUMMARY

Condition Value
Name ABEX
Type Macro
File MAC.DOSMORE.ASM
Author Nathan Riggs
Last Revision 07-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Check if an Applesoft BASIC program is running
Input none
Output none.
Dependencies none
Flags Destroyed NZCV
Cycles 26+
Bytes 18
Notes none
See Also none

DETAILS

The ABEX macro sets the CARRY flag if an Applesoft BASIC program is currently running; otherwise, the CARRY is cleared.

LISTING 6.65: MAC.DOSMORE.ASM ABEX Macro Source

*
*``````````````````````````````*
* ABEX                         *
*                              *
* CHECK IF AN APPLESOFT BASIC  *
* PROGRAM IS RUNNING.          *
*                              *
* THIS IS ADAPTED FROM DON     *
* WORTH'S AND PIETER LECHNER'S *
* /BENEATH APPLE DOS/, SO THE  *
* LICENSE MAY VARY ACCORDINGLY *
*                              *
* PARAMETERS                   *
*                              *
*  NONE                        *
*                              *
* CYCLES: 26                   *
* SIZE: 18 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
ABEX     MAC
         LDX   $76        ; {4C3B} GET LINE NUMBER
         INX              ; {2C1B}
         BEQ   ]NO        ; {3C2B}
         LDX   $33        ; {4C3B} GET PROMPT CHARACTER
         CPX   #$DD       ; {3C2B} IS PROMPT A "]" ?
         BEQ   ]NO        ; {3C2B} YES, SO NOT EXECUTING
         SEC              ; {2C1B} ELSE, IS EXECUTING--SET CARRY
         JMP   ]EXIT      ; {3C3B}
]NO
         CLC              ; {2C1B}
]EXIT
         <<<
*

Part II: DOS Collection Demos

This section lists two demo files, DEMO.DOSFM.ASM and DEMO.DOSMORE.ASM, that illustrate how to use the various macros in the DOS collection. This only concerns the macros found in the MAC.DOSFM.ASM file and the MAC.DOSMORE.ASM file, as the macros in DOS.DOSREQ.ASM are meant for internal use only.

Listing 6.70: DEMO.DOSFM.ASM Source

*
*``````````````````````````````*
* DEMO.DOSFM.ASM               *
*                              *
* A DEMO FILE FOR THE DOS      *
* FILE MANAGER MACROS.         *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      21-APR-2021       *
* ASSEMBLER: MERLIN 8 PRO      *
* OS:        DOS 3.3           *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** ASSEMBLER DIRECTIVES
*
         CYC   AVE
         EXP   OFF
         TR    ON
         DSK   DEMO.DOSFM
         OBJ   $BFE0
         ORG   $6000
*
*``````````````````````````````*
* TOP INCLUDES                 *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
         PUT   MIN.HEAD.REQUIRED.ASM
         USE   MIN.MAC.REQUIRED.ASM
         USE   MIN.MAC.DOSREQ.ASM
         USE   MIN.MAC.DOSFM.ASM
         PUT   MIN.HEAD.DOS.ASM
*
]HOME    EQU   $FC58
]ZSLOT   EQU   $6
]ZDRIVE  EQU   $2
*
*``````````````````````````````*
* PROGRAM MAIN BODY            *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*``````````````````````````````*
* DOS FILE MANAGER MACROS      *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FOLLOWING MACROS BEING USED ARE EXAMPLES
** OF HOW TO USE EACH MACRO IN THE FILE MANAGER
** MACRO SELECTION OF THE DOS COLLECTION OF THE
** APPLEIIASM LIBRARY. NOTE THAT OTHER DEMO FILES
** EXIST FOR OTHER DOS FUNCTIONS, SUCH AS THE
** DEMO.DOSRWTS.ASM FILE FOR RWTS USAGE AND THE
** DEMO.DOSMORE.ASM FILE FOR MISCELLANEOUS MACROS
** THAT CAN BE OF USE WHILE USING APPLE DOS.
*
*``````````````````````````````*
* THE FCAT MACRO               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FCAT MACRO SIMPLY RUNS THE CATALOG
** DOS COMMAND, WHICH LISTS THE FILES IN A
** DISK IN THE GIVEN SLOT AND DRIVE. A MORE
** ROBUST CATALOGING MACRO IS PLANNED AS PART
** OF THE DEMO.DOSMORE.ASM SELECTION.
*
         JSR   ]HOME
         _PRN  "THE FCAT MACRO",8D
         _PRN  "==============",8D8D
         _WAIT
         FCAT  #]ZSLOT;#]ZDRIVE
         _WAIT
*
*``````````````````````````````*
* THE FLOCK MACRO              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FLOCK MACRO LOCKS A GIVEN FILE AT THE
** PROVIDED SLOT AND DRIVE NUMBERS.
*
         JSR   ]HOME
         _PRN  "THE FLOCK MACRO",8D
         _PRN  "===============",8D8D
         _PRN  "FIRST, CATALOG BEFORE LOCKING:",8D8D
         _WAIT
         FCAT  #]ZSLOT;#]ZDRIVE
         _WAIT
         _PRN  " ",8D
         _PRN  "NOW LOCK A FILE AND DO ANOTHER CAT:",8D8D
         FLOCK #FN5;#]ZSLOT;#]ZDRIVE
         _WAIT
         FCAT  #]ZSLOT;#]ZDRIVE
         _WAIT
*
*``````````````````````````````*
* THE FULCK MACRO              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FULCK MACRO SIMPLY UNLOCKS A FILE IN
** THE GIVEN SLOT AND DRIVE.
*
         JSR   ]HOME
         _PRN  "THE FULCK MACRO",8D
         _PRN  "===============",8D8D
         _PRN  "FIRST, SHOW CATALOG WITH LOCKED FILE:",8D8D
         _WAIT
         FCAT  #]ZSLOT;#]ZDRIVE
         _WAIT
         _PRN  " ",8D
         _PRN  "NOW SHOW CATALOG WITH UNLOCKED FILE:",8D8D
         FULCK #FN5;#]ZSLOT;#]ZDRIVE
         _WAIT
         FCAT  #]ZSLOT;#]ZDRIVE
         _WAIT
*
*``````````````````````````````*
* THE FRENM MACRO              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FRENM MACRO RENAMES A FILE FROM A SOURCE
** FILENAME TO A DESTINATION FILENAME, BOTH IN
** THE SAME SLOT AND DRIVE.
*
         JSR   ]HOME
         _PRN  "THE FRENM MACRO",8D
         _PRN  "===============",8D8D
         _PRN  "CATALOG WITH RENAMED FILE:",8D8D
         FRENM #FN5;#FN3;#]ZSLOT;#]ZDRIVE
         _WAIT
         FCAT  #]ZSLOT;#]ZDRIVE
         _PRN  " ",8D
         _WAIT
         _PRN  "CATALOG WITH FILE RENAMED BACK:",8D8D
         _WAIT
         FRENM #FN3;#FN5;#]ZSLOT;]ZDRIVE
         FCAT  #]ZSLOT;#]ZDRIVE
         _WAIT
*
*``````````````````````````````*
* THE FWRTB MACRO              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FWRTB MACRO, WHICH STANDS FOR
** (F)ILE (WR)I(T)E (B)YTE, WRITES A SINGLE BYTE
** TO A FILE ON A DISK AT A GIVEN SLOT, DRIVE AND
** VOLUME. NOTE THAT THIS CAN BE ANY FILE TYPE.
*
** OTHER THAN THE RETURN CODE, THERE IS NO OUTPUT
** BEYOND THE "A" BEING PUT INTO THE FILE. WE CANNOT
** TEST THIS UNTIL WE ALSO USE A BYTE READING FUNCTION,
** WHICH WE WILL COVER NEXT.
*
** ALSO NOTE THAT THIS MAKES USE OF THE FOPEN AND FCLOS
** MACROS. THESE WILL BE EXHIBITED AGAIN TOWARD THE END
** OF THE DEMO.
*
         FOPEN #FN5;#]ZSLOT;#]ZDRIVE;#0;#0;#]TYP_TXT
         FWRTB #]ZSLOT;#]ZDRIVE;#0;#0;#0;#"A"
         FCLOS #FN5;#]ZSLOT;#]ZDRIVE
*
*``````````````````````````````*
* THE FRDB MACRO               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FRDB MACRO, WHICH STANDS FOR
** (F)ILE (R)EA(D) (B)YTE, READS A BYTE FROM
** A FILE ON A DISK IN THE GIVEN SLOT, DRIVE AND
** VOLUME.
*
         JSR   ]HOME
         _PRN  "THE FRDB AND FWRTB MACROS",8D
         _PRN  "=========================",8D8D
         _PRN  "THE FIRST BYTE OF THE FILE IS: "
         FOPEN #FN5;#]ZSLOT;#]ZDRIVE;#0;#0;#]TYP_TXT
         FRDB  #]ZSLOT;#]ZDRIVE;#0;#0;#0;#0
         JSR   $FDF0
         FCLOS #FN5;#]ZSLOT;#]ZDRIVE
         _WAIT
*
*``````````````````````````````*
* THE FWRTR MACRO              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FWRTR MACRO, WHICH STANDS FOR (F)ILE
** (WR)I(T)E RANGE, WRITES A RANGE OF BYTES IN
** MEMORY TO A FILE (THE TYPE IS UP TO THE USER).
** THIS IS USED IN CONJUNCTION WITH THE FRDR MACRO
** TO READ AND WRITE MULTIPLE BYTES FROM AND TO FILES.
*
** THIS MACRO ONLY OUTPUTS TO A FILE, SAVE FOR THE
** RETURN CODE STORED IN THE .X REGISTER. THE NEXT
** MACRO'S EXPLANATION WILL INCLUDE PRINTING THE TEXT
** SAVED TO A FILE HERE.
*
** NOTE THAT WHEN WRITING A RANGE OF BYTES, THE LENGTH
** OF THE BYTES TO BE WRITTEN SHOULD BE REDUCED BY ONE.
** THIS IS DUE TO AN INCONSISTENCY IN DOS.
*
         FOPEN #FN5;#]ZSLOT;#]ZDRIVE;#0;#0;#]TYP_TXT
         FWRTR #]ZSLOT;#]ZDRIVE;#0;#0;#0;#RANGE+1;#24
         FCLOS #FN5;#]ZSLOT;#]ZDRIVE
*
*``````````````````````````````*
* THE FRDR MACRO               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FRDR MACRO, WHICH STANDS FOR (F)ILE
** (R)EA(D) (R)ANGE, READS A RANGE OF BYTES
** FROM A FILE ON A DISK AT A GIVEN SLOT AND DISK,
** STORING THE DATA AT A PROVIDED ADDRESS. IT
** IS IMPORTANT TO KNOW THE SIZE OF THE FILE
** PRIOR TO READING IT, SINCE READING PAST THE
** END OF THE FILE CAN HAVE UNPREDICTABLE
** CONSEQUENCES.
*
         JSR   ]HOME
         _PRN  "THE FRDR AND FWRTR MACROS",8D
         _PRN  "=========================",8D8D
         _PRN  "THE FILE CONTAINS:",8D8D
         FOPEN #FN5;#]ZSLOT;#]ZDRIVE;#0;#0;#0
         FRDR  #]ZSLOT;#]ZDRIVE;#0;#0;#0;#RDRANGE;#25
         FCLOS #FN5;#]ZSLOT;#]ZDRIVE
         LDY   #255
LOOP1
         INY
         LDA   RDRANGE,Y
         JSR   $FDF0
         CPY   #24
         BNE   LOOP1
         _WAIT
*
*``````````````````````````````*
* THE BLOAD MACRO              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE BLOAD MACRO WORKS MUCH LIKE THE BLOAD
** COMMAND IN DOS, BUT THERE IS NO BLOAD COMMAND
** FOR THE FILE MANAGER; IT HAS TO BE BUILT FROM
** THE ALREADY AVAILABLE COMMANDS.
*
** WHEN USED, THE BLOAD MACRO LOADS A BINARY FILE'S
** CONTENTS AND STORES THEM IN THE PROVIDED ADDRESS ON
** THE DISK IN THE GIVEN SLOT AND DRIVE. IF THE ADDRESS
** PASSED IS #0000, THEN THE MACRO/SUBROUTINE ASSUMES
** THAT THE DEFAULT ADDRESS WILL BE USED, WHICH IS
** STORED IN THE FIRST TWO BYTES OF THE FILE. THE LENGTH
** IS ALSO STORED AT THE BEGINNING OF THE FILE IN BYTES
** THREE AND FOUR, FOLLOWED BY THE ACTUAL DATA REQUESTED.
*
** IT SHOULD BE NOTED THAT THERE IS NO TEXT FILE
** EQUIVALENT TO BLOAD BECAUSE ANYONE WITH ANY SENSE
** WILL USE BINARY FILES TO STORE AND RETRIEVE DATA ON
** THE DISK, AS IT IS BOTH FASTER AND EASIER--TEXT
** FILES, FOR INSTANCE, DO NOT EASILY PROVIDE THE
** LENGTH OF THE FILE. IF A TEXT ROUTINE AS SUCH IS
** NEEDED, IT IS BEST TO BUILD YOUR OWN USING FWRTR,
** FRDR, FWRTB AND FRDB, AS YOU WILL LIKELY CREATE YOUR
** OWN STRUCTURE TO THE FILE.
*
         JSR   ]HOME
         _PRN  "THE BLOAD MACRO",8D
         _PRN  "===============",8D8D
         _PRN  "$300 NOW HOLDS:",8D8D
         BLOAD #FN6;#$0000;#]ZSLOT;#]ZDRIVE;#0
         DUMP  #$300;#$40
         _WAIT
*
*``````````````````````````````*
* THE BSAVE MACRO              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE BSAVE MACRO IS FUNCTIONALLY EQUIVALENT TO
** THE BSAVE COMMAND FROM THE DOS PROMPT. FIRST,
** THE PROVIDED ADDRESS IS STORED IN THE FIRST TWO
** BYTES OF THE FILE TO SUPPLY THE DEAULT LOADING
** ADDRESS. FOLLOWING THAT, THE LENGTH OF THE DATA
** IS STORED IN THE THIRD AND FOURTH BYTES. THE
** DATA IS THEN STORED FOLLOWING THESE BYTES. THIS
** IS HOW DOS ITSELF HANDLES BINARY FILES, AND
** YOUR BINARY FILES SHOULD ALSO FOLLOW THIS SCHEME
** TO AVOID ANGERING THE GODS.
*
** WE WON'T BE GOING THROUGH THE OUTPUT HERE, BUT IF
** YOU EXAMINE THE FILE WITH A TOOL LIKE CIDERPRESS,
** YOU WILL SEE THAT THE FILE SIMPLY CONTAINS THE
** VALUES #$01 TO #$40. BE FOREWARNED THAT YOU WILL
** NOT SEE THE FIRST FOUR BYTES, AS CIDERPRESS HIDES
** THESE TO PREVENT CONFUSION. YOU CAN VIEW THE FIRST
** FOUR BYTES BY LOOKING AT THE SECTOR THE FILE STARTS
** AT.
*
** NOTE AGAIN THAT AN EQUIVALENT MACRO OR SUBROUTINE
** IS NOT PROVIDED IN THIS COLLECTION.
*
         JSR   ]HOME
         _PRN  "THE BSAVE MACRO",8D
         _PRN  "===============",8D8D
         _PRN  "SAVING BINARY DATA..."
         BSAVE #FN7;#MEM40;#$39;#6;#2;#0
         _PRN  "DONE!!!",8D8D
         _WAIT
*
*``````````````````````````````*
* THE FOPEN AND FCLOS MACROS   *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE FOPEN MACRO MUST BE RUN BEFORE READING
** OR WRITING A FILE, AND THE FCLOS MACRO MUST
** BE USED AFTERWARDS. IF FOPEN IS NEGLECTED, THE
** FILE WILL NOT BE CREATED; IF FCLOS IS NEGLECTED,
** THEN THAT FILE BUFFER WILL REMAIN IN USE. SINCE
** WE GENERALLY LIKE TO ACTUALLY USE OUR FILES, IT'S
** GOOD PRACTICE TO USE FOPEN AND FCLOS BECAUSE
** UM.. FILE INPUT AND OUTPUT WOULD NOT HAPPEN OTHERWISE.
*
** IF A FILE DOES NOT ALREADY EXIST, FOPEN AUTOMATICALLY
** CREATES A NEW ONE WITH THE PROVIDED FILENAME. HERE,
** WE WILL CREATE A FILE CALLED "TODELETE" THAT WILL BE
** DELETED IN THE NEXT MACRO'S EXPLANATION.
*
         JSR   ]HOME
         _PRN  "FOPEN AND FCLOS",8D
         _PRN  "===============",8D8D
         _PRN  "CATALOG BEFORE FILE CREATION:",8D8D
         _WAIT
         FCAT  #]ZSLOT;#]ZDRIVE
         _WAIT
         _PRN  " ",8D
         _PRN  "CATALOG AFTER FILE CREATION:",8D8D
         FOPEN #FN8;#]ZSLOT;#]ZDRIVE;#0;#0;#]TYP_TXT
         FCLOS #FN8;#]ZSLOT;#]ZDRIVE
         _WAIT
         FCAT  #]ZSLOT;#]ZDRIVE
         _WAIT
*
*``````````````````````````````*
* THE FDEL MACRO               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** LASTLY (FOR GOOD REASON), THE FDEL MACRO
** DELETES A FILE WITH THE GIVEN NAME IN THE
** NOTED SLOT AND DISK DRIVE. HERE, LET US
** DELETE THE LAST FILE WE CREATED, "TODELETE".
*
         JSR   ]HOME
         _PRN  "THE FDEL MACRO",8D
         _PRN  "==============",8D8D
         _PRN  "LOOK MA, NO TODELETE FILE!",8D8D
         FDEL  #FN8;#]ZSLOT;#]ZDRIVE
         _WAIT
         FCAT #]ZSLOT;#]ZDRIVE
         _WAIT
*
*``````````````````````````````*
* RWTS MACROS                  *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** WHILE THE RWTS ROUTINE HAS NOT BEEN ABSTRACTED
** TOO MUCH, THIS IS FOR GOOD REASON: OUR HEADER
** FILE IS GETTING TOO BIG FOR ITS BRITCHES!
*
** THE RWTS ROUTINE LETS YOU READ AND WRITE DIRECTLY
** TO A DISK, BYPASSING CONVENTIONS USED BY DOS.
** IT GOES WITHOUT SAYING THAT THIS IS DANGEROUS: THE
** SMALLEST ACCIDENT CAN DESTROY A DISK FOR GOOD, SO
** USE THIS AT YOUR OWN DISCRETION.
*
** THERE ARE TWO MAIN MACROS FOR USING RWTS: THE SRWTS
** MACRO ( (S)ET RWTS ) AND THE GRWTS MACRO. THE SRWTS
** MACRO MUST ALWAYS BE RUN BEFORE GRWTS, AS IT SETS
** THE VARIABLES NEEDED FOR RWTS TO WORK. SINCE THERE
** IS SUCH A THREAT OF DISK CORRUPTION, WE ARE ONLY
** SHOWING HOW TO USE RWTS TO READ THE DISK, NOT WRITE
** IT; HOWEVER, THE PROCESS IS THE SAME FOR BOTH.
*
         JSR   ]HOME
         _PRN  "THE RWTS MACROS",8D
         _PRN  "===============",8D8D
         JSR   ]LOCRPL
         STY   ]RWTSPTR
         STA   ]RWTSPTR+1
*
         SRWTS #]ZSLOT;#]ZDRIVE;#0;#$11;#0;#$9000;#1
         GRWTS
         _PRN  "HERE'S THE DISK VTOC:",8D8D
         DUMP  #$9000;#$F
         DUMP  #$9010;#$F
         DUMP  #$9020;#$F
         DUMP  #$9030;#$F
         DUMP  #$9040;#$F
         DUMP  #$9050;#$F
         DUMP  #$9060;#$F
         DUMP  #$9070;#$F
         _PRN  " ",8D
         _PRN  ".....",8D
         _WAIT
*
         JSR   ]HOME
         _PRN  "FIN!",8D8D
*
EXIT
         JMP   $3D0
*
         PUT   MIN.SUB.FBLOAD.ASM
         PUT   SUB.FBSAVE.ASM
         PUT   MIN.LIB.REQUIRED.ASM
*
FN3      STR   "RENAMED"
FN5      STR   "WRITERANGE"
FN6      STR   "BINLOAD"
FN7      STR   "BINSAVE"
FN8      STR   "TODELETE"
MEM40    HEX   000102030405060708091A1B1C1D1E1F
         HEX   101112131415161718191A1B1C1D1E1F
         HEX   202122232425262728292A2B2C2D2E2F
         HEX   303132333435363738393A3B3C3D3E3F
RANGE    STR   "ONE RING TO RULE THEM ALL"
RDRANGE  DS    25
*

Listing 6.71: DEMO.DOSMORE.ASM Source

*
*``````````````````````````````*
* DEMO.DOSMORE.ASM             *
*                              *
* A DEMO FILE FOR VARIOUS DOS  *
* MACROS AND SUBROUTINES.      *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      07-MAY-2021       *
* ASSEMBLER: MERLIN 8 PRO      *
* OS:        DOS 3.3           *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** ASSEMBLER DIRECTIVES
*
         CYC   AVE
         EXP   OFF
         TR    ON
         DSK   DEMO.DOSMORE
         OBJ   $BFE0
         ORG   $6000
*
*``````````````````````````````*
* TOP INCLUDES                 *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
         PUT   MIN.HEAD.REQUIRED.ASM
         USE   MIN.MAC.REQUIRED.ASM
         USE   MIN.MAC.DOSREQ.ASM
         USE   MIN.MAC.DOSMORE.ASM
         PUT   MIN.HEAD.DOS.ASM
]HOME    EQU   $FC58
*
*``````````````````````````````*
* PROGRAM MAIN BODY            *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*``````````````````````````````*
* MISC. DOS MACROS             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*``````````````````````````````*
* DVER                         *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE DVER MACRO TESTS WHICH DOS VERSION IS
** BEING USED. IT RETURNS #2 FOR DOS 3.2 AND #3
** FOR DOS 3.X.
*
         JSR   ]HOME
         _PRN  "DOS VERSION MACRO (DVER)",8D
         _PRN  "========================",8D8D
         DVER
         CMP   #3
         BEQ   THREE
         _PRN  "USING DOS 2.X",8D
         JMP   NEXT1
THREE    _PRN  "USING DOS 3.X",8D
NEXT1
         _WAIT
*
*``````````````````````````````*
* THE DOSIN MACRO              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE DOSIN MACRO CHECK WHETHER DOS IS LOADED.
** THIS IS NECESSARY TO CHECK BEFORE TRYING TO
** USE THE DOS FILE MANAGER OR THE RWTS ROUTINES.
*
         JSR   ]HOME
         _PRN  "THE DOSIN MACRO",8D
         _PRN  "===============",8D8D
         DOSIN
         BCC   NODOS
         _PRN  "DOS IS CURRENTLY LOADED."
         JMP   NEXT2
NODOS    _PRN  "DOS IS NOT LOADED."
NEXT2
         _WAIT
*
*``````````````````````````````*
* THE ABAS MACRO               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE ABAS MACRO TESTS WHICH VERSION OF
** BASIC IS LOADED: INTEGER OR APPLESOFT.
** IF APPLESOFT IS LOADED, THEN THE CARRY IS
** RETURNED AS TRUE; IF INTEGER BASIC IS LOADED,
** THEN THE CARRY IS RETURNED CLEAR.
*
         JSR   ]HOME
         _PRN  "THE ABAS MACRO",8D
         _PRN  "==============",8D8D
         ABAS
         BCC   INTBAS
         _PRN  "APPLESOFT IS LOADED."
         JMP   NEXT3
INTBAS   _PRN  "INTEGER BASIC IS LOADED."
NEXT3    _WAIT
*
*``````````````````````````````*
* THE IBEX MACRO               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE IBEX MACRO TESTS WHETHER INTEGER BASIC
** IS RUNNING. THE CARRY IS RETURNED AS TRUE IF SO,
** AND CLEAR IF NOT. NOTE THAT YOU SHOULD TEST IF
** INTEGER BASIC IS LOADED BEFOREHAND; OTHERWISE,
** A FALSE POSITIVE MAY RESULT.
*
         JSR   ]HOME
         _PRN  "THE IBEX MACRO",8D
         _PRN  "==============",8D8D
         IBEX
         BCC   INTNORUN
         _PRN  "INTEGER BASIC IS RUNNING."
         JMP   NEXT4
INTNORUN _PRN  "INTEGER BASIC IS NOT RUNNING."
NEXT4    _WAIT
*
*``````````````````````````````*
* THE ABEX MACRO               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE ABEX MACRO TESTS WHETHER AN APPLESOFT
** PROGRAM IS CURRENTLY RUNNING.
*
         JSR   ]HOME
         _PRN  "THE ABEX MACRO",8D
         _PRN  "==============",8D8D
         ABEX
         BCC   NOAPP
         _PRN  "APPLESOFT PROGRAM IS RUNNING."
         JMP   NEXT5
NOAPP    _PRN  "APPLESOFT PROGRAM IS NOT RUNNING."
NEXT5    _WAIT
*
         JSR   ]HOME
         _PRN  "FIN!",8D8D
*
EXIT
         JMP   $3D0
*
         PUT   MIN.LIB.REQUIRED.ASM
*