
This article describes a program which lets you easily install customizing routines, such as a RAMdisk and clock card drivers, on bootup into ProDOS, It mimics, under ProDOS 8, the SYSTEM.SETUP feature of ProDOS 16. It is emphatically placed in the public domain: I urge software publishers to take it and include it where appropriate with their own programs. I only ask that you take the program unmodified. It would be unfortunate if variants of the program spread around, each subtly incompatible with the others.
One feature which makes ProDOS 16 a more powerful operating system than ProDOS 8 is its flexible and complicated startup sequence. This includes the ability to boot up into either ProDOS 8 or ProDOS 16 based applications, as well as automatically installing, on bootup, patches in RAM to the Apple IIGS toolbox. ProDOS 16 accomplishes this by loading and executing all files found in the /SYSTEM/SYSTEM.SETUP subdirectory. These files must include TOOLSETUP, but may include other files for installing desk accessories, diagnostic and debugging routines, or anything else you can think of.
SYSTEM.SETUP is a nice idea. It allows you to specify what happens at boot up simply by placing the correct files in a particular subdirectory. Unfortunately, ProDOS 8 does not support SYSTEM.SETUP. If it did, it would be much easier to install IIe RAM disk drivers, clock card drivers, and IIGS Classic Desk Accessories on ProDOS 8 disks.
Suppose you have a large memory card in your IIe, and you want a RAM disk driver for it to be installed automatically every time you boot. Here are two ways you could do it:
- If the RAM disk driver is a system program, you could place it first on the disk so that it’s automatically called on boot up. When the system program quits, you then type in the name of the next system program to run, such as “BASIC.SYSTEM”.
- If the RAM disk driver is a binary file, you can place BASIC.SYSTEM first, and have a BASIC program called STARTUP which BRUNs the RAM disk driver. This is fine, as long as you plan to boot up into BASIC.
If you have both a large memory card and a clock card, you may need to install drivers for both of them. Now things become more difcult for you, particularly if your memory card came with a SYStem file program to install the RAM disk, and your clock card came with a BINary file clock driver. SETUP.SYSTEM (note: not SYSTEM.SETUP) automates the bootup sequence for you. To use it, assemble it and make it the first SYStem program on your disk whose name ends in “.SYSTEM”. This ensures that it will be run on boot up. Then create a subdirectory called “SETUPS”, containing the files which you want to be executed on boot up. That’s all there is to it.
Many existing programs already work with SETUP.SYSTEM. I have used it with the RAM disk drivers for both Applied Engineering’s and Checkmate Technologies’ IIe memory cards, and with Diversi-Cache and Diversi-Hack (1165 classic desk accessories by Bill Basham).
When run, SETUP.SYSTEM will search for the SETUPS subdirectory in the volume directory of the last disk accessed. It then loads and executes, in turn, each SYStem or BINary file in the SETUPS subdirectory. These files I refer to as “setup files.” When all setup files have been called, SETUP.SYSTEM then looks for the second system file in the main volume directory whose name ends in “.SYSTEM”, and runs that. This second “.SYSTEM” program is your main application. It can be BASIC.SYSTEM, your assembler, word processor, AppleWorks, or any other ProDOS application.
SETUP.SYSTEM was especially written to be compatible with already existing RAM disk drivers, clock drivers, and Apple IIGS Classic Desk Accessories under ProDOS 8. The rules for compatibility are simple. Setup files must be either BINary files or SYStem programs in the SETUPS subdirectory. This is in contrast to ProDOS 16’s SYSTEM.SETUP, which uses new ProDOS 16 file types exclusively. You may place other file types in the SETUPS subdirectory, such as text files, but SETUP.SYSTEM will ignore them. BINary setup files may load anywhere in either memory range $200-$3EF or $800-$BEFF. They should exit with an RTS. You may also place SYStem programs in the SETUPS subdirectory. These SYStem programs. as usual, must load at S2000, and must not exceed $B8FF when loaded. SYStem setup programs should exit with a ProDOS QUIT call. Most SYStem programs do this, although there are exceptions. A few exit by looking for the next SYStem program to run by name, or look for and run the second “.SYSTEM” file on the disk. Programs which do this are incompatible with SETUP.SYSTEM. Among the few system programs which are incompatible for this reason is the original version of the ProDOS FILER.
Once the setup program is in memory, it may use any memory except for pages $BD and $BE, which is where SETUP.SYSTEM lives in hibernation, and the ProDOS global page at $BF00. Because of this memory restriction, some existing SYStem programs may not be used as setup files. You should not, for instance, place BASIC.SYSTEM in the SETUPS subdirectory. BASIC.SYSTEM relocated itself to $9A00-$BEFF, overwriting SETUP.SYSTEM. If you do so, and then type “BYE” from BASIC, your Apple will explode into a reball, destroying all life other than insects within a half mile radius. Really.
A third reason why system programs may not work in the SETUPS subdirectory is that they may require subsidiary files ó which must also be placed in the SETUPS subdirectory. If these subsidiary files are BINary or SYStem files, SETUP.SYSTEM will eventually try to call them on their own. This problem happened to me when I moved the Apple IIGS System Utilities into my SETUPS directory. (Why? So I could copy some files onto my RAM disk on bootup.) The problem was solved by changing the file type of the three BINary files which the System Utilities needed. I gave them file type codes of $03. which is a defunct Apple III Pascal Text file code. The point was, SETUP.SYSTEM cared what the le types were and the System Utilities didn’t. I should point out that placing random system programs in your SETUPS subdirectory can be dangerous. By trial and error, I found that the GS System Utilities left the crucial pages $BD and $BE undamaged.
If you plan to write new setup programs, I recommend that you make them BINary files rather than SYStem programs. SETUP.SYSTEM temporarily redirects the ProDOS quit vector at $BF03 into itself before calling any SYStem programs in the SETUPS subdirectory. Therefore, when the setup program executes a ProDOS Quit call, control is returned to my code. This is not kosher programming, and may not work with future revisions of ProDOS. I added the feature solely so that many already existing SYStem programs could be used with SETUP.SYSTEM.
Typing it in
Although the program below was assembled using the Merlin Pro assembler, I tried to avoid as many Merlin-specific psuedo ops as possible and present a generic assembly listing. In order to assemble it on other assemblers, some minor changes will be necessary: The psuedo-op “ASC” in Merlin creates either high or low ASCII characters, depending on whether the string is surrounded by a single quote (low ASCII) or a double quote (high ASCII), I used both varieties. Users of EDASM, APW, or ORCA/M should add the MSB psuedo-op where needed. The last byte of the program is a checksum byte. It is the exclusive-OR of all the previous bytes in the program. If you assemble the program using Merlin, be sure to check that the byte you get is the same as the one in the listing. If it isnët, you made a typo.
If you are not using Merlin, replace the last line with
DFB $E8
and run the following program to check that the code is correct:
10 PRINT CHR$(4) "BLOAD SETUP.SYSTEM,A$2000,TSYS"
20 FOR X=8192 TO 8703
30 SUM=SUM+PEEM(X)
40 NEXT
50 IF SUM=64732 THEN PRINT "OK":END
60 PRINT "ERROR"
Program Logic
SETUP.SYSTEM is not a model of good programming practice. In order to get all the functionality I wanted into 512 bytes, I had to resort to self-modifying code. If the program went one byte over, to 513 bytes, the storage space on disk would mushroom from one block to three.
Among the first tasks of SETUP.SYSTEM is to relocate itself from it’s load address of $2000 to it’s running address of $BD00. SETUP.SYSTEM must move itself out of the way so that it can load other system programs without overwriting itself. Lines 48 through 54 in the program listing accomplish this. Next, the program (lines 61 through 72) tries to determine the name of the disk from which SETUP.SYSTEM was run. This name is saved so that the program can set the ProDOS prefix to the volume directory at a later time. The quit vector in the ProDOS global page is then saved (lines 73-76) so that it can be restored on exit.
Control returns to line 78 at the label MainLoop, before and after executing each of the setup files. The reset vector and the quit vector are both redirected to point to MainLoop, to increase the chances of SETUP.SYSTEM regaining control after calling setup programs. The system bitmap is then cleared so that we can load the setup file (lines 87-95), and the machine is then put into as normal a state as possible (lines 96-103).
Lines 106 through 127 make sure that the original volume is in the disk drive, and sets the ProDOS prefix to that volume. If the disk isn’t around, a warning message is displayed, and the user is given a chance to insert the correct disk.
Line 129 calls a subroutine called NextFile, which reads the SETUPS subdirectory until it finds the name of the next BINary or SYStem program. It leaves that name in a known place. If it finds no more SYStem or BINary files it exits with the carry set. This will happen when all of the setup files have been loaded and executed ó that case will be dealt with later.
If NextFile found the name of a setup file, we proceed to line 132. Here the prefix is set to the SETUPS snbdirectory, and the setup file is loaded into memory by calling the subroutine ReadFile, which starts at line 240. If there was no error when loading it, the setup file in memory is called. One way or another, control retums to MainLoop, either through the ProDOS Quit call, the user pressing RESET, or the setup file exiting with an RTS.
Once all the setup files have been loaded, we go to line 139 and restore the original ProDOS quit vector. Lines 145 through 149 then modify the NextFile routine so that it works rather differently. Where before NextFile looked for either BINary or SYStem files, now it will look for only SYStem ones. NextFile used to look in the SETUPS subdirectory. It now looks in the volume directory. NextFile will now be used to find the name of the system program to exit to.
NextFile is called repeatedly, returning the names of all SYStem programs in the volume directory (line 150). Lines 152-159 make sure that the filename ends in “.SYSTEM”. If it passes this test, we then check that it is not the first “.SYSTEM” file on the disk (lines 160-162). The first “.SYSTEM” file on the disk is presumably “SETUP.SYSTEM”, and we don’t want to run that, or we’d go into an endless loop. The system file is loaded, and called (line 163) with the same subroutine, ReadFile, which was used to load and call setup files. The difference is that this time we never come back, since the ProDOS quit vector has been restored to its original value.
Program Listing
1 *
2 * SETUP.SYSTEM by Sean Nolan
3 *
4 * A Proposed Startup File Standard
5 *
6 * Published in Call-APPLE, November, 1987
7 * This program is in the public domain.
8 *
9 * This program mimics the ProDOS 16
10 * SYSTEM.SETUP convention. It can be used
11 * to install RAM disk drivers, clock
12 * drivers, and IIGS Classic Desk
13 * Accessories on bootup under ProDOS 8.
14 *
15 * This program loads and calls all BINary
16 * and SYStem files in a subdirectory named
17 * SETUPS. It then looks for the second
18 * system program in the volume directory
19 * whose name ends in ".SYSTEM", and runs
20 * that.
21 *
22 *
23 TYP $FF ;save as a system file
24 ORG $BD00 ;load at $2000, but run at $BD00
25 ******************* equates
26 CH = $24
27 IN2 = $280
28 FILETYPE = IN2+16
29 AUXCODE = IN2+31
30 RESET = $3F2
31 IOBUFFER = $B900
32 PRODOS = $BF00
33 QUITVECT = $BF03
34 DEVNUM = $BF30
35 BITMAP = $BF58
36 INIT = $FB2F
37 VTABZ = $FC24
38 HOME = $FC58
39 RDKEY = $FD0C
40 SETVID = $FE93
41 SETKBD = $FE89
42 SETNORM = $FE84
43 ******************* boot code
44 VOLNAME = * ;The first 17 bytes are overwritten with the
45 ;name of the volume from which this was run.
BD00: A2 01 46 LDX #1 ;mark page $BD as free in the system bitmap
BD02: 8E 6F BF 47 STX BITMAP+23 ;so we can put Online result in our code.
BD05: CA 48 DEX ;relocate this program to $BD00-BEFF
BD06: BD 00 20 49 LOOP1 LDA $2000,X
BD09: 9D 00 BD 50 STA $BD00,X
BD0C: BD 00 21 51 LDA $2100,X
BD0F: 9D 00 BE 52 STA $BE00,X
BD12: E8 53 INX
BD13: D0 F1 54 BNE LOOP1
BD15: CA 55 DEX
BD16: 9A 56 TXS ;init stack pointer
BD17: 4C 21 BD 57 JMP ENTER ;jump to relocated code
BD1A: 06 58 DIRNAME DFB 6 ;DirName and VolName must be in the same page
BD1B: D3 C5 D4 59 ASC "SETUPS"
BD1E: D5 D0 D3
60 ******* Get name of boot volume
BD21: AD 30 BF 61 ENTER LDA DEVNUM ;get name of last volume accessed
BD24: 8D BF BE 62 STA ONLINEN
BD27: 20 00 BF 63 JSR PRODOS
BD2A: C5 64 DFB $C5 ;ONLINE
BD2B: BE BE 65 DA ONLINEP
BD2D: AD 01 BD 66 LDA VOLNAME+1 ;insert a slash nefore the name
BD30: 29 0F 67 AND #$0F
BD32: AA 68 TAX
BD33: E8 69 INX
BD34: 8E 00 BD 70 STX VOLNAME
BD37: A9 2F 71 LDA #$2F ;/
BD39: 8D 01 BD 72 STA VOLNAME+1
BD3C: AD 04 BF 73 LDA QUITVECT+1 ;save original quit vector
BD3F: 8D D2 BD 74 STA QUITMOD1+1
BD42: AD 05 BF 75 LDA QUITVECT+2
BD45: 8D D7 BD 76 STA QUITMOD2+1
77 ******* Clean up before & after calling files
BD48: A2 02 78 MAINLOOP LDX #2 ;point Reset vector and ProDOS
BD4A: BD CB BD 79 LOOP3 LDA JUMP+1,X ;Quit vectors to MainLoop
BD4D: 9D F2 03 80 STA RESET,X
BD50: BD CA BD 81 LDA JUMP,X
BD53: 9D 03 BF 82 STA QUITVECT,X
BD56: CA 83 DEX
BD57: 10 F1 84 BPL LOOP3
BD59: 9A 85 TXS ;fix stack pointer (X=$FF)
BD5A: 20 85 BE 86 JSR CLOSE ;close all open files
BD5D: A2 17 87 LDX #23 ;clear system bit map
BD5F: A9 00 88 LDA #0
BD61: 9D 58 BF 89 LOOP2 STA BITMAP,X
BD64: CA 90 DEX
BD65: 10 FA 91 BPL LOOP2
BD67: A9 CF 92 LDA #$CF ;mark pages 0,1,4-7 as used
BD69: 8D 58 BF 93 STA BITMAP
BD6C: A9 07 94 LDA #%111 ;mark pages $BD-$BF as used
BD6E: 8D 6F BF 95 STA BITMAP+23
BD71: AD 82 C0 96 LDA $C082 ;Language card off
BD74: 8D 0C C0 97 STA $C00C ;40-column
BD77: 8D 0E C0 98 STA $C00E ;normal character set
BD7A: 8D 00 C0 99 STA $C000 ;80STORE off
BD7D: 20 84 FE 100 JSR SETNORM ;normal
BD80: 20 2F FB 101 JSR INIT ;display text page 1
BD83: 20 93 FE 102 JSR SETVID ;PR#0
BD86: 20 89 FE 103 JSR SETKBD ;IN#0
104 *Make sure boot volume is around
105 *AND set prefix to the boot volume
BD89: 20 58 FC 106 VOLMOUNT JSR HOME
BD8C: 20 00 BF 107 JSR PRODOS ;set prefix to volume
BD8F: C6 108 DFB $C6 ;SET PREFIX
BD90: C5 BE 109 DA PFX2P
BD92: 90 28 110 BCC VOLOK
BD94: A2 0D 111 LDX #13
BD96: BD F1 BE 112 LOOP6 LDA VOLTEXT-1,X ;print message "insert volume"
BD99: 9D AC 05 113 STA $5A8+4,X
BD9C: CA 114 DEX
BD9D: D0 F7 115 BNE LOOP6
BD9F: BD 01 BD 116 LOOP7 LDA VOLNAME+1,X ;print volume name
BDA2: 09 80 117 ORA #$80
BDA4: 9D BB 05 118 STA $5A8+19,X
BDA7: E8 119 INX
BDA8: EC 00 BD 120 CPX VOLNAME
BDAB: 90 F2 121 BCC LOOP7
BDAD: A9 23 122 LDA #35 ;go to CH=35, CV=11
BDAF: 85 24 123 STA CH
BDB1: A9 0B 124 LDA #11
BDB3: 20 24 FC 125 JSR VTABZ
BDB6: 20 0C FD 126 JSR RDKEY ;wait for keypress
BDB9: 4C 89 BD 127 JMP VOLMOUNT
128 ******* Get name of next file at IN2
BDBC: 20 15 BE 129 VOLOK JSR NEXTFILE ;get name of next file at IN2
BDBF: B0 0D 130 BCS EXITLOOP ;if error, we're done with setup files
131 ******* Load and call setup file
BDC1: 20 00 BF 132 JSR PRODOS ;set prefix to SETUPS
BDC4: C6 133 DFB $C6 ;SET PREFIX
BDC5: C2 BE 134 DA PFX1P
BDC7: 20 8E BE 135 JSR READFILE ;read in file whose name is at IN@
136 ;and call it if there was no error.
BDCA: 4C 48 BD 137 JUMP JMP MAINLOOP ;3 bytes here copied into ProDOS quit vector
BDCD: 18 138 DFB #$BD!$A5 ;3 bytes here are copied into reset vector
BDCE: EE F4 03 139 EXITLOOP INC RESET+2 ;scramble reset vector
BDD1: A9 00 140 QUITMOD1 LDA #0 ;restore original quit vector
BDD3: 8D 04 BF 141 STA QUITVECT+1
BDD6: A9 00 142 QUITMOD2 LDA #0
BDD8: 8D 05 BF 143 STA QUITVECT+2
144 ******* Look for second system program on disk
BDDB: A9 00 145 LDA #0 ;modify NextFile routine so that it searches
BDDD: 8D 3E BE 146 STA NUMBER+1 ;the volume directory for system files only.
BDE0: 8D 82 BE 147 STA CHEKTYPE+1
BDE3: A9 00 148 LDA #<VOLNAME ;NamePtr+1 does not bneed to be changed
BDE5: 8D D2 BE 149 STA NAMEPTR ;since VolName and DirName are in the same page
BDE8: 20 15 BE 150 NEXTSYS JSR NEXTFILE
BDEB: B0 1B 151 BCS QUIT
BDED: AE 80 02 152 LDX IN2 ;see if file ends with ".SYSTEM"
BDF0: A0 06 153 LDY #6
BDF2: BD 80 02 154 LOOP4 LDA IN2,X ;I expect pathname at IN2 in low ASCII
BDF5: D9 0E BE 155 CMP SYSTEXT,Y
BDF8: D0 EE 156 BNE NEXTSYS
BDFA: CA 157 DEX
BDFB: 88 158 DEY
BDFC: 10 F4 159 BPL LOOP4
BDFE: EE 02 BE 160 INC MOD+1
BE01: A9 FF 161 MOD LDA #$FF ;the first .SYSTEM program we find is this
BE03: F0 E3 162 BEQ NEXTSYS ;one, so skip it and look for next one.
BE05: 20 8E BE 163 JSR READFILE ;if successful, never come back
BE08: 20 00 BF 164 QUIT JSR PRODOS
BE0B: 65 165 DFB $65 ;QUIT
BE0C: C8 BE 166 DA QUITP
BE0E: 2E 53 59 167 SYSTEXT ASC ë.SYSTEM'
BE11: 53 54 45 4D
168 * Get name of next system file or binary file
169 *
170 * This routine is set up to look for both SYSTEM and
171 * BINary files in the SETUPs subdirectory. It is later
172 * modified to search for SYSTEM files only in the
173 * volume directory. The locations which are changed
174 * are ChekType+1, Number+1, and NamePtr (in the Open
175 * parametr list)
176 *
177 * Returns carry if not found, clear if found.
BE15: 20 00 BF 178 NEXTFILE JSR PRODOS
BE18: C8 179 DFB $C8 ;OPEN
BE19: D1 BE 180 DA OPENP
BE1B: B0 68 181 BCS CLOSE
BE1D: AD D6 BE 182 LDA OPENN
BE20: 8D D8 BE 183 STA MARKN
BE23: 8D DD BE 184 STA READN
BE26: 20 00 BF 185 JSR PRODOS ;Read in first 39 bytes of directory to
BE29: CA 186 DFB $CA ;IN2. This gets the number of entries per
BE2A: DC BE 187 DA READP ;block and number of bytes per entry.
BE2C: B0 57 188 BCS CLOSE
BE2E: AD A3 02 189 LDA IN2+35 ;save number of bytes per directory entry
BE31: 8D 54 BE 190 STA ENTSIZE+1
BE34: AD A4 02 191 LDA IN2+36 ;save number of entries per directory block
BE37: 8D 44 BE 192 STA ENTRIES+1
BE3A: EE 3E BE 193 NEXTENT INC NUMBER+1
BE3D: A9 00 194 NUMBER LDA #0 ;self-modified operand
195 * Retrieve catalog entry #A
BE3F: A2 FE 196 LDX #$FE ;build page index in X
BE41: E8 197 LOOP5 INX
BE42: E8 198 INX
BE43: C9 0D 199 ENTRIES CMP #13
BE45: 90 05 200 BCC OK
BE47: ED 44 BE 201 SBC ENTRIES+1
BE4A: B0 F5 202 BCS LOOP5 ;always
BE4C: A8 203 OK TAY
BE4D: A9 04 204 LDA #4 ;1st entry per directory block starts 4 bytes in
BE4F: 88 205 LOOP10 DEY
BE50: 30 08 206 BMI OK2
BE52: 18 207 CLC
BE53: 69 27 208 ENTSIZE ADC #39 ;add size of directory entry
BE55: 90 F8 209 BCC LOOP10
BE57: E8 210 INX
BE58: D0 F5 211 BNE LOOP10 ;always
BE5A: 8D D9 BE 212 OK2 STA MARK ;save mark in file
BE5D: 8E DA BE 213 STX MARK+1
BE60: 20 00 BF 214 JSR PRODOS ;set the mark
BE63: CE 215 DFB $CE ;SET_MARK
BE64: D7 BE 216 DA MARKP
BE66: B0 1D 217 BCS CLOSE
BE68: 20 00 BF 218 JSR PRODOS ;read in directory info
BE6B: CA 219 DFB $CA ;READ
BE6C: DC BE 220 DA READP
BE6E: B0 15 221 BCS CLOSE
BE70: AD 80 02 222 LDA IN2 ;make sure that file is not deleted
BE73: F0 C5 223 BEQ NEXTENT
BE75: 29 0F 224 AND #$0F
BE77: 8D 80 02 225 STA IN2
BE7A: AD 90 02 226 LDA FILETYPE ;make sure file type is correct
BE7D: 49 FF 227 EOR #$FF ;we look for system programs...
BE7F: F0 04 228 BEQ CLOSE
BE81: 49 F9 229 CHEKTYPE EOR #6!$FF ;...and binary ones.
BE83: D0 B5 230 BNE NEXTENT
BE85: 08 231 CLOSE PHP ;close all files - do not change carry
BE86: 20 00 BF 232 JSR PRODOS
BE89: CC 233 DFB $CC ;CLOSE
BE8A: CF BE 234 DA CLOSEP
BE8C: 28 235 PLP
BE8D: 60 236 ANRTS RTS
237 * Read file and call it.
238 * Name should be found at IN2
239 * Prefix must be set.
BE8E: AE 90 02 240 READFILE LDX FILETYPE ;if a system program, set to read to $2000
BE91: A9 20 241 LDA #$20
BE93: E8 242 INX
BE94: F0 06 243 BEQ SETDEST
BE96: AE 9F 02 244 LDX AUXCODE ;else, set to read in file at address
BE99: AD A0 02 245 LDA AUXCODE+1 ;found in auxcode
BE9C: 8E EC BE 246 SETDEST STX READ2D
BE9F: 8D ED BE 247 STA READ2D+1
BEA2: 20 00 BF 248 JSR PRODOS ;Open file
BEA5: C8 249 DFB $C8 ;OPEN
BEA6: E4 BE 250 DA OPEN2P
BEA8: B0 DB 251 BCS CLOSE
BEAA: AD E9 BE 252 LDA OPEN2N
BEAD: 8D EB BE 253 STA READ2N
BEB0: 20 00 BF 254 JSR PRODOS ;Read file into memory
BEB3: CA 255 DFB $CA ;READ
BEB4: EA BE 256 DA READ2P
BEB6: 20 85 BE 257 JSR CLOSE
BEB9: B0 D2 258 BCS ANRTS
BEBB: 6C EC BE 259 JMP (READ2D) ;call the file just loaded
260 ******* ProDOS MLI parameter lists
BEBE: 02 261 ONLINEP DFB 2 ;Online parameter list
BEBF: 00 262 ONLINEN DS 1
BEC0: 01 BD 263 DA VOLNAME+1
264 *
BEC2: 01 265 PFX1P DFB 1 ;to set prefix to SETUP
BEC3: 1A BD 266 DA DIRNAME
267 *
BEC5: 01 268 PFX2P DFB 1 ;to set prefix to volume directory
BEC6: 00 BD 269 DA VOLNAME
270 *
BEC8: 04 00 00 271 QUITP DFB 4,0,0,0,0,0,0
BECB: 00 00 00 00
272 *
BECF: 01 00 273 CLOSEP DFB 1,0 ;close all files
274 *
BED1: 03 275 OPENP DFB 3 ;open directory
BED2: 1A BD 276 NAMEPTR DA DIRNAME ;pathname pointer
BED4: 00 B9 277 DA IOBUFFER
BED6: 00 278 OPENN DS 1 ;reference number
279 *
BED7: 02 280 MARKP DFB 2 ;set mark in directory
BED8: 00 281 MARKN DS 1
BED9: 00 00 00 282 MARK DS 3
283 *
BEDC: 04 284 READP DFB 4 ;read directory
BEDD: 00 285 READN DS 1
BEDE: 80 02 286 DA IN2 ;target address
BEE0: 27 00 287 DA 39 ;length
BEE2: 00 00 288 DS 2
289 *
BEE4: 03 290 OPEN2P DFB 3 ;open setup or system file
BEE5: 80 02 291 DA IN2
BEE7: 00 B9 292 DA IOBUFFER
BEE9: 00 293 OPEN2N DS 1
294 *
BEEA: 04 295 READ2P DFB 4 ;read setup or system file
BEEB: 00 296 READ2N DS 1
BEEC: 00 00 297 READ2D DS 2 ;destination of file is self-mod here
BEEE: 00 B1 298 DA $B900-$800 ;ask for largest possible that will fit
BEF0: 00 00 299 DS 2
300 *
BEF2: C9 CE D3 301 VOLTEXT ASC "INSERT VOLUME"
BEF5: C5 D2 D4 A0
BEF9: D6 CF CC D5
BEFD: CD C5
BEFF: E8 302 CHK ;checksum - eor for all previous bytes
--End assembly, 512 bytes, Errors: 0
You can download the disk with this program on it at:
https://www.callapple.org/soft/ap2/anthology/CA8711_Example_ProDOS.dsk