,MLv  X c0C)HCCH Mhhݩh `eCDiCD`  RyHP   * 1H0芢@) Y0.Ș`i#(PMR\ \b Pgi 0  % @ / ՠ`d   0DDԝLHv1000 .OPT NO OBJ1010 .SET 2,120 chars/line for compressed printing1020 .SET 3,10 suppress form feed1030 .SET 4,80 lines/page for compressed printing1040 .TITLE "RECONSTRUCTION of DOS 2.5 with comments"1050 * Rob Bishoff ---------- 31/3/861060 * 16/7/86 format-routine checked1070 * final check-up, june 19871080 * version 21/6/871090 * *** checked with object code ***1100 *1110 * main changed after first version:1120 * ERRNO --> CURFCB1130 * SVD3 --> TEMP41140 * EXTRA --> DRIVE81150 * EXT2 --> D8INIT1160 * EXT3 --> CHKD251170 * EXT4 --> XRDVT1180 * EXT5 --> XWTVT1190 * ANDPB --> XBANK1200 * APB1 --> SBANK1210 * SPARE1/2 --> SABUFL/H1220 * SPARE --> FCBSPR1230 * ERAPO --> ERROR1240 * SPARE5 --> BURFLG1250 * ERROR --> PERROR (in DUP)1260 * DSKUTL --> RAMLO1270 *1280 * link parts of FMS source1290 *1300 .INCLUDE #D:RECDOS1.M651310 .INCLUDE #D:RECDOS2.M651320 .INCLUDE #D:RECDOS3.M651330 .INCLUDE #D:RECDOS4.M651340 *1350 * link resident part of DUP1360 *1370 .INCLUDE #D:RECDUP.M651380 *1390 .END f FMS source1290 *1300 .INCLUDE #D:RECDOS1.M651310 .INCLUDE #D:RECDOS2.M651320 .INCLUDE #D:RECDOS3.M651330 .INCLUDE #D:RECDOS4.M651340 *1350 *X1000 * RECDOS1.M651010 .PAGE "author notice"1020 *1030 * Atari FMS was originally written in the second half of 19781040 * by Paul Laughton, assisted by Paul and Kathleen O'Brien1050 * It was updated (19 Aug. 1980) by Paul Laughton for1060 * t he Atari DOS 2.0S.1070 * The DOS 2.5 version (adapted for enhanced density1080 * by Bill Wilkinson???) was released in late 1984.1090 *1100 * This is a reconstructed & commented version of the1110 * enhanced density DOS.SYS source file.1120 *1130 * A description of Atari DOS is published by COMPUTE!1140 * as INSIDE ATARI DOS.1150 *1160 * system equates1170 *1180 ZICB = $20 zero page i/o control block1190 FMSZPG = $43 DOS zero page registers (7 bytes)1200 STAK = $0102 stack loc for put byte1210 DSKTIM = $0246 addr of o.s. worst case disk time out1220 LMADR = $02E7 pointer to bottom of free memory (called MEMLO by the o.s.)1230 DVSTAT = $02EA device status registers (4 bytes)1240 DCBORG = $0300 device control block12 50 DEVTAB = $031A device table (called HATABS by the o.s.)1260 IOCBORG = $0340 i/o control blocks1270 FMSORG = $0700 start of DOS1280 OSBTM = >$E000-1 hi byte of addr less than (Rev.1/2) o.s.space1290 DHADR = $E453 device handler vector address (called DSKINV by the o.s.)1300 EOL = $9B Atari end of line char1310 LMASK = 3 link mask1320 TIMOUT = 15 time out value of 15 secs.1330 *1340 * more equates (from o.s. source)1350 *1360 RTCLOK = $12 realtime clock1370 BUFRLO = $32 pointer to data buffer, used for ramdisk1380 BUFRHI = $331390 CRITIC = $42 critical i/o flag1400 PORTB = $D301 memory management register (XL/XE only)1410 NMIEN = $D40E non-maskable interrupt enable1420 SIOV = $E459 serial i/o utility entry point1430 .PAGE "IOCB"1440 *= IOCBORG1450 *1460 * IOCB - i/o control block. There are 8 i/o control blocks, 1 iocb is1470 * required for each currently open device or file.1480 *1490 IOCB1500 ICHID *= *+1 device handler1510 ICDNO *= *+1 device number1520 ICCOM *= *+1 i/o command1530 ICSTA *= *+1 i/o status1540 ICBAL *= *+11550 ICBAH *= *+1 buffer addr (L,H)1560 ICPUT *= *+2 put char DH addr1570 ICBLL *= *+11580 ICBLH *= *+1 buffer len (L,H)1590 ICAUX1 *= *+1 aux 11600 *= *+1 aux 2 (unused)1610 ICAUX3 *= *+1 aux 31620 ICAUX4 *= *+1 aux 41630 ICAUX5 *= *+1 aux 51640 *= *+1 aux 6 (unused)1650 ICLEN = *-IOCB1660 *= *+ICLEN*7 space for 7 more iocb's1670 *1680 * zero page iocb labels1690 *1700 ICDNOZ = ICDNO-IOCB+ZICB1710 ICBLLZ = ICBLL-IOCB+ZICB buff len1720 ICBLHZ = ICBLH-IOCB+ZICB1730 ICBALZ = ICBAL-IOCB+ZICB buff addr1740 ICBAHZ = ICBAH-IOCB+ZICB1750 ICCOMZ = ICCOM-IOCB+ZICB1760 ICAX1Z = ICAUX1-IOCB+ZICB1770 .PAGE "DCB"1780 *= DCBORG1790 *1800 * DCB - data control block. The DCB is an iocb like control block used1810 * to interface the disk file management system to the disk handler.1820 *1830 DCBSBI *= *+1 serial bus id1840 DCBDRV *= *+1 disk drive #1850 DCBCMD *= *+1 command1860 DCBSTA *= *+1 i/o status1870 DCBBUF *= *+2 i/o buffer addr (L,H)1880 DCBTO *= *+2 time out count1890 DCBCNT *= *+2 i/o byte count1900 DCBSEC *= *+2 i/o sector number1910 *1920 * DCBCMD value equates1930 *1940 DCBCRS = 'R read sector1950 DCBCWS = 'P put sector1960 DCBCST = 'S status request1970 DCBCFS = '! format diskette single1980 DCBCFE = '" format diskette enhanced1990 *2000 * ** special note:2010 * DCBCWS may be changed to 'W ($57) if desired to have disk perform a2020 * verifying read after each write. Disk write ('W) operations will2030 * take longer, but will be more reliable.2040 *2050 * zero page cells2060 *2070 *= FMSZPG2080 ZBUFP *= *+2 buffer pointer2090 ZDRVA *= *+2 zero page drive pointer2100 ZSBA *= *+2 zero pg sector buff ptr2110 CURFCB *= *+1 current FCB (iocb also)2120 .PAGE "BOOT RECORD"2130 *2140 * The following bytes are stored on disk sector 1. They comprise the2150 * boot load record.2160 *2170 .LOCAL 2180 *= FMSORG2190 BFLG .BYTE 0 boot flag unused = 02200 BRCNT .BYTE 3 no. consective boot records to read2210 BLDADR .WORD FMSORG boot load addr2220 BINTADR .WORD DUPINIT init addr2230 BCONT JMP XBCONT boot read cont. pt.2240 *2250 * The following bytes are set by the console processor. They are acted2260 * upon during FMS init only. They are part of the boot record thus2270 * defining the default initialization parms.2280 *2290 SABYTE .BYTE 3 max # concurrent open files2300 DRVBYT .BYTE $83 drive bits2310 SAFBFW .BYTE 0 storage allocation dir sw (unused)2320 SASA .WORD ENDFMS storage allocation start addr2330 *2340 * The following code reads the FMS and console processor (DOS) from2350 * the DOS.SYS file.2360 *2370 DFSFLG .BYTE 0 DOS flag (00 no DOS file, 01 128 byte sector disk)2380 DFLINK .WORD 4 DOS file start sector number2390 BLDISP .BYTE 125 displ to sector link2400 DFLADR .WORD DFMSDH addr start of DOS.SYS file2410 *2420 XBCONT LDY DFSFLG get DOS flag2430 BEQ BFAIL br if no DOS.SYS file2440 JSR MVSA move load addr to pointer2450 LDA DFLINK+1 get 1st sector #2460 LDY DFLINK2470 XBC1 LDX ICBALZ move zero page ptr2480 STX DCBBUF to DCB2490 LDX ICBAHZ2500 STX DCBBUF+12510 CLC 2520 JSR BSIO go read DOS sector2530 BMI BFAIL2540 LDY BLDISP point to link2550 LDA (ICBALZ),Y get hi link2560 AND #LMASK mask to link bits2570 TAX 2580 INY 2590 ORA (ICBALZ),Y2600 BEQ XBRTN done if link = 02610 LDA (ICBALZ),Y get low link2620 PHA 2630 INY 2640 LDA (ICBALZ),Y get # bytes in sector2650 JSR INCBA go increment bu ff addr (by # bytes in sector)2660 PLA low link to Y reg2670 TAY 2680 TXA hi link to accu2690 JMP XBC1 go read next sector2700 BFAIL LDA #$C0 set for carry set2710 XBRTN ASL A prepare carry & Y reg for rtn2!720 TAY 2730 RTS back to operating system2740 *2750 INCB LDA #$802760 INCBA CLC incr buffer pointer by # in accu2770 ADC ICBALZ2780 STA ICBALZ2790 BCC EXBT2800 INC ICBAHZ2810 EXBT RTS 2820 *2830 MVSA LDA "DFLADR move load start addr2840 STA ICBALZ to zero page ptr2850 LDA DFLADR+12860 STA ICBAHZ2870 RTS 2880 .BYTE 0,0 filler bytes2890 .PAGE "SECTOR I/O"2900 *2910 * BSIO - do sector i/o2920 * on entry: Y/A - sector numb#er, X - doesn't matter2930 * carry clear for read, set for write2940 *2950 BSIO STA DCBSEC+1 set sector hi2960 STY DCBSEC sector lo2970 BSIOR LDA #DCBCRS assume read sector2980 LDY #$40 and get data2990 BCC :BSIO3 br if read3000$ LDA #DCBCWS else load write sector (change this operand to $57 for write with verify)3010 LDY #$80 and put data3020 :BSIO3 PHP save processor status word3030 LDX ICDNOZ check for drive 83040 CPX #83050 BNE DSIO1 br i%f not3060 PLP restore PSW3070 JSR DRIVE8 use DRIVE8 routine for drive #83080 JMP DSIOE exit3090 DSIO1 PLP restore processor status word3100 STA DCBCMD set command3110 LDA #TIMOUT timeout default loaded3120 DS&IO2 STA DCBTO set time out3130 STY TEMP3 save SIO cmd3140 LDA #$31 disk serial bus id3150 STA DCBSBI set id3160 LDA #3 set retry count3170 STA RETRY3180 LDA #$80 set i/o byte count3190 STA DCBCNT3200 ' ASL A shift accu to zero3210 STA DCBCNT+1 set byte count hi to zero3220 DSIOX LDA TEMP3 recall SIO cmd3230 STA DCBSTA set SIO cmd3240 JSR SIOV call serial i/o3250 BPL DSIOE if good i/o then rts3260 DEC RETRY test( if another retry available3270 BPL DSIOX retry the i/o3280 DSIOE LDX CURFCB reload current FCB3290 TYA i/o status set flags3300 RTS 3310 .PAGE "STATUS"3320 *3330 * DFMSTA - get a file status3340 *3350 DFMSTA JSR SETUP) setup3360 JSR XSTAT go decode file name and search for file3370 JSR TSTLOCK test locked3380 JMP GREAT file exists and unlocked3390 .BYTE 0,0 filler bytes3400 .PAGE "FILE MANAGER ENTRY POINT"3410 *3420 * DFMSDH - disk fi*le management disk vector table3430 * (entered into the handler address table)3440 *3450 DFMSDH3460 .WORD DFMOPN-1 open file3470 .WORD DFMCLS-1 close file3480 .WORD DFMGET-1 get file3490 .WORD DFMPUT-1 put byte3500 .WORD DFMS+TA-1 status3510 .WORD DFMDDC-1 device dependent cmd3520 *3530 * bit value table for FRESECT & GETSECTOR3540 *3550 SECTAB .BYTE $80,$40,$20,$10,8,4,2,13560 * following byte is read, but never changed by DOS/DUP3570 XBFLG .BYTE $FF skip delay l,oop in bank switch routine if FF3580 *3590 *= $07E0 insure fixed init addr3600 *3610 * set up drive info3620 * DRVTBL - 8 bytes, one for each possible drive (0 = no drive, set to mark drive)3630 * DBUFA(L,H) - 8 two byte entries for the dri-ve (VTOC) buffer addr for a drive3640 *3650 DINIT LDA SASA move start of alloc3660 STA ICBALZ area to ICBAL/HZ3670 LDA SASA+13680 STA ICBAHZ3690 LDA DRVBYT move drive excess bits from boot3700 STA ZBUFP3710 LDX #7 . dr # minus 13720 DIA LDA #0 assume no drive3730 ASL ZBUFP shift dr bit to carry3740 BCC DIB br if dr doesn't exist3750 LDY #DVDWRQ set write required off3760 STA (ICBALZ),Y in the drive VTOC buffer3770 LDA ICBALZ m/ove current alloc addr to DBUFA3780 STA DBUFAL,X3790 LDA ICBAHZ3800 STA DBUFAH,X3810 LDA #$90 go incr buff alloc by $903820 JSR INCBA3830 LDA #100 indicate drive present3840 DIB STA DRVTBL,X set drive into table38500 DEX dec drive3860 BPL DIA br if more to test3870 LDA ICBALZ save start of sector buffs3880 STA SABUFL3890 LDA ICBAHZ3900 STA SABUFH3910 *3920 * Set up sector allocation table. The sector allocation table (SEC1TBL)3930 * has 8 one byte entries, one for each possible 128 byte buffer.3940 * SABYTE in the boot record determines the number of entries to3950 * allocate. Non allocated byte are minus.3960 *3970 LDY SABYTE get count3980 LDX #03990 DIN2XTS DEY dec count of allocated4000 TYA if plus allocate, else de allocate4010 STA SECTBL,X set allocate byte4020 BMI DIC if not allocated, then don't allocate buffer4030 JSR INCB else, incr buff ptr by $804040 DI3C INX incr buffer #4050 CPX #8 if not all 84060 BNE DINXTS do again4070 *4080 * NOTE: The non-resident part of DUP starts at $1D7F (labeled4090 * NDOS), giving only limited room for drive & sector buffers.4100 * With a gap of4 only $3B0 bytes between ENDFMS and NDOS only4110 * 3 drives (including ramdisk!) & 4 simultaneously open files4120 * (or 4 drives & 2 files) are possible. Althrough DOS itself4130 * will be fine, the DOS menu will not work properly with more4140 * 5buffer space used.4150 *4160 * set low mem4170 *4180 LDA ICBALZ move final addr4190 STA LMADR to low mem ptr4200 LDA ICBAHZ4210 STA LMADR+14220 *4230 * clear FCB's to zero4240 *4250 LDA #04260 TAY 4270 CFCBX STA F6CB,Y4280 INY 4290 BPL CFCBX loop until all 128 cleared4300 *4310 * set device handler table entry4320 *4330 TAY reset index4340 ADI1 LDA DEVTAB,Y find an unused4350 BEQ ADI24360 CMP #'D or disk entry4370 B7EQ ADI24380 INY 4390 INY 4400 INY 4410 CPY #304420 BNE ADI14430 BRK else break4440 ADI2 LDA #'D set disk4450 STA DEVTAB,Y4460 LDA # DFMSDH48490 STA DEVTAB+2,Y4500 RTS 400 INY 4410 CPY #304420 BNE ADI14430 BRK else break4440 ADI2 LDA #'D set disk4450 STA DEVTAB,Y4460 LDA # DFMSDH4%1000 * RECDOS2.M651010 .PAGE "OPEN"1020 *1030 * DFMOPN - file open execution entry point1040 *1050 DFMOPN JSR SETUP do FCB set up1060 JSR FNDCODE go decode file name1070 LDA ICAUX1,X get aux1 (open type codes)1080 STA FCBOTC,X pu:t into FCB1090 AND #OPDIR is this list directory?1100 BEQ OPN1 br if not1110 JMP LISTDIR goto dir list code1120 OPN1 JSR SFDIR go search file dir1130 PHP stack result1140 LDA FCBOTC,X get open type code1150 CM;P #OPIN input1160 BEQ DFOIN1170 CMP #OPOUT output1180 BEQ DFOOUT1190 CMP #OPIN+OPOUT update1200 BEQ DFOUPD1210 CMP #OPOUT+OPAPND append1220 BEQ DFOAPN1230 GOERD JSR ERROR error: device cmd invalid1240 .BYTE $A<8 (error # 168)1250 *1260 * DFOIN - open for input1270 *1280 DFOIN PLP get search flag1290 BCS OPNER1 error if not found1300 BCC DFOUI1310 *1320 * DFOUPD - open for update1330 *1340 DFOUPD PLP get search flag1350 BCS= OPNER1 br not found1360 JSR TSTLOCK test lock1370 DFOUI JSR DFRDSU set up for read1380 JMP GREAT done1390 OPNER1 JSR ERROR file not found1400 .BYTE $AA (error # 170)1410 *1420 * DFOAPN - open for append1430 *1440 DFOAPN PLP > get read status1450 BCS OPNER1 br not found1460 LDY CDIRD get file flag1470 LDA FILDIR+DFDFL1,Y1480 STA FCBSPR,X save flag1490 AND #DFDNLD if old file type then error1500 BEQ APOER1510 JSR TSTLOCK test locked152?0 JSR OPVTOC read VTOC (insure not write protected)1530 JSR GETSECTOR get a new sector1540 STA FCBSSN+1,X move sector # to link sector #1550 LDA FCBLSN,X1560 STA FCBSSN,X1570 JMP DHFOX2 continue as open1580 APOER JSR ERRO@R attempt append to old type file1590 .BYTE $AC (error # 172)1600 *1610 * DFOOUT - open for output1620 *1630 DFOOUT PLP get search flag1640 BCS DFOX11650 JSR XDEL0 delete the file or files1660 LDY CDIRD1670 JMP OPN1AA1680 * make a new entry in the directory1690 DFOX1 LDA DHOLES was there a hole1700 BMI OPNER2 br if no hole1710 STA CDIRS save hole sector as current dir sec1720 JSR RDDIR go read current dir sector1730 LDA DHOLED move hole Bdispl to current dir displ1740 STA CDIRD1750 LDA DHFNUM move hole FN to current1760 STA SFNUM1770 JSR OPVTOC1780 LDY CDIRD1790 LDX #101800 LDA #$201810 OPN1B STA FILDIR+DFDPFN,Y blank fill file entry for file name18C20 INY 1830 DEX 1840 BPL OPN1B1850 * allocate data sector, prepare & write dir entry1860 OPN1A LDX CURFCB1870 LDA #DFDINU+DFDNLD set dir flag in use1880 STA FCBSPR,X1890 JSR GETSECTOR get a sector1900 LDY CDIRD get Ddir displ1910 STA FILDIR+DFDSSN+1,Y put sector into dir rec1920 LDA FCBLSN,X1930 STA FILDIR+DFDSSN,Y1940 LDA #DFDINU+DFDOUT+DFDNLD set dir entry in use, open for output1950 STA FILDIR+DFDFL1,Y1960 LDA #01970 STA FILDIRE+DFDCNT+1,Y set count = 01980 STA FILDIR+DFDCNT,Y1990 LDX #02000 OPN2 LDA FNAME,X move file name2010 CMP #'? if wild card2020 BEQ OPN2A change to blank2030 STA FILDIR+DFDPFN,Y to directory2040 OPN2A INY 2050 INX 20F60 CPX #112070 BCC OPN22080 JSR WRTDIR go write directory2090 * finish open output/append2100 DHFOX2 JSR SETFCB2110 JSR WRTN6 fix up as if write2120 LDA #FCBFAS set new file2130 STA FCBFLG,X2140 * was DOS file opened?G2150 JSR TSTDOS if not DOS2160 BNE DHFOX3 br2170 JMP WRTDOS else write DOS.SYS file2180 DHFOX3 JMP GREAT2190 OPNER2 JSR ERROR directory full2200 .BYTE $A9 (error # 169)2210 * setup FCB2220 SETFCB LDA #0 clear2230 STA FHCBFLG,X flag2240 LDA SFNUM move file number to FCB2250 ASL A2260 ASL A2270 STA FCBFNO,X2280 LDA #02290 STA FCBDLN,X data length2300 STA FCBCNT,X set count = 02310 STA FCBCNT+1,X2320 RTS 2330 * set up for rIead2340 DFRDSU JSR SETFCB setup FCB2350 LDY CDIRD move start sector to link2360 LDA DFDFL1+FILDIR,Y2370 STA FCBSPR,X get file flag2380 AND #DFDNLD set new sector flag2390 STA FCBSLT,X2400 LDA FILDIR+DFDSSN,Y move start sJector2410 STA FCBLSN,X2420 LDA FILDIR+DFDSSN+1,Y2430 STA FCBLSN+1,X2440 JMP RDNSO read 1st sector and rtn2450 .PAGE "PUT BYTE"2460 *2470 * DFMPUT - put a file byte2480 *2490 DFMPUT STA SVDBYT2500 LDA ICDNO,X2510 KSTA ICDNOZ2520 JSR SETUP2530 LDY ENTSTK chk to see if entry wasn't for CIO2540 LDA STAK,Y if hi byte rts is not in o.s. addr2550 CMP #OSBTM space then a non-CIO entry2560 BCS FRMCIO br if from CIO2570 LDA #0 else pLrevent from doing burst i/o2580 STA ICCOMZ2590 FRMCIO LDA FCBOTC,X if not open2600 AND #OPOUT output2610 BEQ PUTER error2620 LDY FCBDLN,X get data length2630 TYA 2640 CMP FCBMLN,X if sector not full2650 BCC PUT1 M then br2660 JSR WRTNXS else write full sector2670 BCS PEOF br if EOF2680 JSR WTBUR test burst2690 LDY #02700 BCS PUT1 br if not burst2710 LDA (ICBALZ),Y put next byte2720 STA SVDBYT after burst area2730 PUTN1 INC FCBDLN,X inc data len2740 LDA SVDBYT get data byte2750 STA (ZSBA),Y and put in sector buffer2760 LDA #FCBFSM indicate sector modified2770 ORA FCBFLG,X2780 STA FCBFLG,X2790 JMP GREAT done2800 PUTER JMP GOERD deviceO command invalid2810 PEOF JSR ERROR end of file error2820 .BYTE $88 (error # 136)2830 .PAGE "BURST I/O"2840 .LOCAL 2850 *2860 * Test burst i/o and do if possible2870 *2880 * burst i/o operates by reading or writing data sectors28P90 * directly into the user buffer instead of transferring2900 * only one byte each time CIO is called2910 *2920 WTBUR LDA FCBFLG,X if not aquiring sectors then update and no burst2930 BMI TBURST2940 SEC indicate no burst2950 RQTS 2960 *2970 RTBUR LDA #0 set read type2980 *2990 TBURST STA BURTYP set burst type3000 LDA #1 assume no burst3010 STA BURFLG flag stays 1 if no burst3020 LDA ICCOMZ if cmd3030 AND #2 is text mode3040 BEQ NOBURRST then no burst3050 BNE BBINC otherwise, test buffer length3060 * do burst i/o3070 NXTBUR ASL BURFLG shift to indicate burst did occure3080 LDA BURTYP get burst type3090 BMI WRBUR minus, so write3100 JSR RDNXTS otherwise, dSo sector read3110 BCS NOBURST br if eof3120 LDY #0 otherwise, move data etc.3130 :LABT3 LDA (ZSBA),Y move data bytes3140 STA (ICBALZ),Y to user buffer3150 INY 3160 TYA 3170 CMP FCBMLN,X end of sector data bytes?3180 T BCC :LABT3 loop if less3190 JSR INCBA incr user buff ptr by number of bytes moved3200 JMP :LABT4 adjust buffer length and test for another try3210 WRBUR JSR MVDAT move data for write3220 JSR WRTNXS do sector write3230 :LABT4 SEUC 3240 LDA ICBLLZ dec user buffer len by3250 SBC FCBMLN,X actual data len got or put3260 STA ICBLLZ3270 BCS BBINC3280 DEC ICBLHZ3290 * enough bytes for at least a full sector?3300 BBINC LDA ICBLLZ if lo buff len >= $803310 V BMI NXTBUR do burst3320 LDA ICBLHZ if hi buff len > 03330 BNE NXTBUR do burst3340 * no (more) burst3350 NOBURST LSR BURFLG set carry if no burst at all3360 RTS and rtn3370 * move data for write3380 MVDAT LDY #03390 :MV2W LDA (ICBALZ),Y move data bytes from user buffer3400 STA (ZSBA),Y to sector buffer3410 INY 3420 TYA 3430 CMP FCBMLN,X end of sector data bytes?3440 BCC :MV2 loop if less3450 STA FCBDLN,X save in current sector buff data Xlen3460 JMP INCBA incr buff ptr and rtn3470 .PAGE "GET BYTE"3480 *3490 * DFMGET - get a file byte3500 *3510 DFMGET JSR SETUP go set up3520 LDA FCBOTC,X if open for dir read3530 AND #OPDIR3540 BEQ GET13550 JMP GDCHAR Ythen go to get next dir char & rtn3560 GET1 LDA FCBDLN,X get data len3570 CMP FCBMLN,X test empty sector3580 BCC GET2 br if not empty3590 JSR RTBUR do burst if possible3600 JSR RDNXTS get next sector3610 BCC GET1 br ifZ not eof3620 JMP PEOF else eof error3630 GET2 TAY 3640 LDA (ZSBA),Y get data byte3650 STA SVDBYT save the byte3660 INY 3670 TYA 3680 STA FCBDLN,X and set new value3690 LDY FCBLSN,X do eof look ahead3700 BNE G[ET3 if lsn not zero3710 LDY FCBLSN+1,X then3720 BNE GET3 not eof3730 CMP FCBMLN,X if lsn=0 then check for last byte3740 BCC GET33750 LDA #3 if last byte then rts with impending eof code3760 JMP RETURN3770 GET3 J\MP GREAT3780 .PAGE "CLOSE"3790 *3800 * DFMCLS - close a file3810 *3820 DFMCLS JSR SETUP3830 LDA FCBOTC,X get open code3840 AND #OPOUT if not output3850 BEQ CLDONE then done3860 ROL FCBFLG,X if not acquiring sectors3870 ] BCC CLUPDT then is update3880 JSR WRTLSEC write last sector3890 JSR RRDIR go get directory3900 LDA FCBCNT+1,X get cnt of sectors3910 PHA 3920 LDA FCBCNT,X3930 PHA 3940 LDA FCBOTC,X get open code3950 AND #OPAP^ND if not append3960 BEQ CLOUT br3970 LDA FCBSPR,X else stack file flag3980 PHA 3990 JSR DFRDSU set up for read4000 PLA restore file flag4010 STA FCBSPR,X4020 APP1 JSR RDNXTS read to eof4030 BCC APP14040 _ LDA FCBSSN,X move start sector4050 STA FCBLSN,X to eof link sector4060 LDA FCBSSN+1,X4070 STA FCBLSN+1,X4080 JSR WRTN2 then write as not eof4090 CLOUT LDY CDIRD get dir displ4100 CLC update sector count4110 PL`A 4120 ADC FILDIR+DFDCNT,Y4130 STA FILDIR+DFDCNT,Y4140 PLA 4150 ADC FILDIR+DFDCNT+1,Y4160 STA FILDIR+DFDCNT+1,Y4170 LDA FCBSPR,X set entry to in use4180 STA FILDIR+DFDFL1,Y4190 JSR WRTDIR write dir4200 JSR WaRTVTOC write VTOC4210 CLDONE LDA #0 clear open code4220 STA FCBOTC,X4230 JMP FGREAT4240 *4250 CLUPDT ROL FCBFLG,X if sector not modified4260 BCC CLDONE then done4270 JSR WRCSIO else write it4280 JMP CLDONE then done4290b .PAGE " "4300 *4310 * re-read dir record4320 *4330 RRDIR LDA FCBFNO,X get file number (in 6 leftmost bits)4340 LSR A4350 LSR A4360 STA SFNUM4370 JSR FNSHFT set accu = file no/84380 STA CDIRS to get dir sector4390 c JSR FNSHFT move low nibble of file number to high4400 JSR FNSHF14410 ASL A4420 STA CDIRD to get dir displ4430 JMP RDDIR4440 *4450 FNSHFT LDA #04460 FNSHF1 LDY #3 shift 3 bits of file no into accu4470 FNSHF2 ASL FCBFNO,X44d80 ROL A4490 DEY 4500 BNE FNSHF24510 RTS 4520 .PAGE "DEVICE DEPENDENT COMMAND"4530 .LOCAL 4540 *4550 * DFMDDC -- device dependent cmd execution4560 *4570 DFMDDC JSR SETUP set up for execution4580 LDA ICCOM,X get comemand4590 CMP #254 is it format (try enhanced & single)?4600 BEQ XFV br if4610 CMP #253 other format (forced single/enh)?4620 BEQ XFVS br if4630 CMP #MAXDDC test range4640 BCS DVDCER br out of range4650 SEfC 4660 SBC #$20 subtract base of cmds4670 BCC DVDCER br out of range4680 ASL A4690 TAY 4700 LDA DVDCVT,Y4710 PHA push execution addr4720 LDA DVDCVT+1,Y4730 PHA 4740 RTS execute4750 * devigce dependent command vector table4760 DVDCVT4770 .DBYTE XRENAME-1 20-rename4780 .DBYTE XDELETE-1 21-delete4790 .DBYTE DVDCER-1 invalid cmd4800 .DBYTE XLOCK-1 23-lock4810 .DBYTE XUNLOCK-1 24-unlock4820 .DBYTE XPOINT-1 25-pohint4830 .DBYTE XNOTE-1 26-note4840 MAXDDC = $27 max DVDC+14850 DVDCER JMP GOERD error4860 .PAGE "FORMAT"4870 *4880 * format a diskette4890 *4900 * table contains: length of VTOC, type code,4910 * total # of sectors, # of sectors mappied in sector $1684920 *4930 :TABLE .BYTE $64,$02 single4940 .WORD $02C3,$02C3 (707)4950 .BYTE $8A,$02 enhanced4960 .WORD $03F2,$02C3 (1010/707)4970 .BYTE $4A,$02 ramdisk4980 .WORD $01F3,$01F3 (499)4990 * format in a forced mojde5000 XFVS LDA ICAUX1,X get aux as cmd5010 BNE :LBL15020 LDA #DCBCFS format single if aux = 05030 :LBL1 LDX #0 indicate format mode = forced5040 BEQ :LBL2 (always)5050 * format, try enhanced but if impossible, do single5060 XFV kLDA #DCBCFE format enhanced5070 TAX indicate 'try it' mode5080 :LBL2 STX TEMP1 save format mode (0 = forced sd/md)5090 :LBL2A STA DCBCMD command to DCB5100 LDA ICDNOZ get drive #5110 LDX #12 offset in table, assume ramdiskl5120 CMP #85130 BEQ XF1 skip physical formating if D8:5140 * do physical formating5150 LDA ZDRVA+1 move VTOC buf adr5160 STA DCBBUF+1 to DCB5170 LDA ZDRVA5180 STA DCBBUF5190 LDY #$40 tell SIO receiving data5200m LDA DSKTIM get format time out value5210 JSR DSIO2 goto local disk handler, then SIO5220 BPL XF0 if no errors cont5230 * act upon error5240 CPY #$8B device NAK?5250 BNE :LBL45260 LDX TEMP1 recall format mode52n70 BEQ XFERR error if forced mode5280 LDA #DCBCFS otherwise set cmd to format single5290 CMP DCBCMD actual cmd already single?5300 BNE :LBL2A no, have another try5310 XFERR JMP RETURN do error exit5320 :LBL4 CPY #$90 ck for devoice done error5330 BNE XFERR no, then error exit5340 LDY #0 else ck for bad sector info5350 LDA #$FF returned by controller5360 CMP (ZDRVA),Y5370 BNE XFBAD bad sectors ret err msg5380 INY 5390 CMP (ZDRVA),Yp5400 BEQ XFERR not bad sec err, req err exit5410 XFBAD JSR ERROR return with error #1735420 .BYTE $AD (bad format)5430 * recall density, set X as offset in table5440 XF0 LDX #0 assume single5450 LDA DCBCMD ck cmd5460 CMPq #DCBCFS5470 BEQ XF1 br if is5480 LDX #6 if not, must be enhanced5490 * do logical formating5500 XF1 LDA #0 zero VTOC buffer5510 LDY #$8F 144 bytes long5520 XF2 STA (ZDRVA),Y5530 DEY 5540 BNE XF25550 LDAr :TABLE,X move length of VTOC5560 STA DRVTYP5570 XF3 INX 5580 LDA :TABLE,X move entries5590 STA (ZDRVA),Y to VTOC buffer5600 INY 5610 CPY #55620 BNE XF35630 * write VTOC sector(s)5640 LDY #DVDSMP get start of bit maps5650 LDA #$0F deallocate 1st 4 sectors for boot5660 XF4 STA (ZDRVA),Y5670 LDA #$FF set sector map to all ones5680 INY 5690 CPY DRVTYP ck for end of VTOC5700 BNE XF45710 LDY #DVDSMP+45 deallocate middle 95720 LDtA #05730 STA (ZDRVA),Y for VTOC and file dir5740 INY 5750 LDA #$7F5760 STA (ZDRVA),Y5770 LDX DRVTYP more to do?5780 BPL XF5 br if not enhanced5790 LDY #DVDSMP+90 deallocate sector 7205800 STA (ZDRVA),Y5810 u LDY #DVDESA get end of VTOC for enh sector count5820 LDA # <$012F tell 303 more sectors available5830 STA (ZDRVA),Y5840 INY 5850 LDA # >$012F5860 STA (ZDRVA),Y5870 XF5 JSR WRTVTOC write the VTOC5880 * write empty directory vsectors5890 LDA #0 zero filler dir sectors5900 TAY 5910 XF6 STA FILDIR,Y use file dir buffer5920 INY 5930 BPL XF65940 LDA #7 write to all 8 dir sectors5950 STA CDIRS5960 XF7 JSR WRTDIR write the file dir5970 w DEC CDIRS5980 BPL XF75990 JSR DELDOS set no DOS6000 JMP FGREAT done use file dir buffer5920 INY 5930 BPL XF65940 LDA #7 write to all 8 dir sectors5950 STA CDIRS5960 XF7 JSR WRTDIR write the file dir5970 X1000 * RECDOS3.M651010 .PAGE "RENAME"1020 .LOCAL 1030 *1040 * XRENAME - rename a file or files1050 *1060 XRENAME JSR FNDCODE decode file name1070 JSR FNDCNX go decode next file name1080 LDX #10 move new filename1090 :LBL1 L yDA FNAME,X1100 STA AFNAME,X1110 DEX 1120 BPL :LBL11130 JSR XSTAT decode old filename, dont rtn if not in directory1140 XRN1 JSR TSTLOCK test lock1150 JSR TSTDOS test old file entry1160 PHP indicate DOS in stacke zd PSW1170 LDX #01180 STX TEMP11190 LDY CDIRD get index to filename in dir sector1200 * move filename from AFNAME to dir entry1210 XRN2 LDA FNAME,X don't change wild card1220 CMP #'?1230 BNE :LBL21240 DEC TEMP1 indicat {e wild card1250 CMP AFNAME,X ck with new name1260 BNE :LBL3 br to error exit if not also a '?'1270 :LBL2 LDA AFNAME,X get new name char1280 CMP #'? wild card?1290 BEQ XRN3 skip if so1300 STA FILDIR+DFDPFN,Y otherwise, |store new char1310 XRN3 INY 1320 INX 1330 CPX #111340 BNE XRN2 loop until done1350 PLP unstack PSW to indicate (no) DOS1360 BNE :LBL41370 JSR DELDOS tell no DOS if DOS.SYS was renamed1380 :LBL4 JSR TSTDOS test } new file entry1390 BNE :LBL5 skip if no DOS1400 LDX CDIRD otherwise, set index1410 LDA FILDIR+DFDSSN+1,X1420 LDY FILDIR+DFDSSN,X A,Y new DOS start sector1430 JSR SETDSO go write sector one1440 :LBL5 JSR WRTDIR go write cu ~r dir record1450 LDA TEMP1 wild card used?1460 BEQ :LBL6 no, done1470 JSR CSFDIR yes, cont search of dir1480 BCC XRN1 br if found another1490 :LBL6 JMP FGREAT go to good ending1500 :LBL3 JMP FNDERR file name error1510 .PAGE "DELETE"1520 *1530 * XDELETE - delete all filenames that match1540 *1550 XDELETE JSR XSTAT decode filename & search dir, don't rtn if not found1560 XDELX JSR XDEL0 delete1570 JSR TSTDOS was it DOS?1580 BNE XDELY br if not1590 JSR DELDOS otherwise re-write boot record1600 XDELY JSR WRTDIR write dir entry1610 JSR CSFDIR look for next match1620 BCC XDELX br if found1630 JSR WRTVTOC write VTOC1640 JMP FGREAT done1650 *1660 XDEL0 JSR OPVTOC don't rtn if disk write protected1670 LDY CDIRD get dir displ1680 JSR TSTLOCK go test lock1690 LDA #DFDEDE load deleted flag1700 STA FILDIR+DFDFL1,Y delete file1710 JSR DFRDSU read first sector1720 XDEL2 JSR FRESECT free cur sector1 730 JSR RDNXTS read next sector1740 BCC XDEL21750 LDY #DVDWRQ turn on write required1760 TYA 1770 STA (ZDRVA),Y1780 :EXIT RTS 1790 .PAGE "LOCK AND UNLOCK"1800 *1810 * XLOCK - lock a file1820 * XUNLOCK - unlock a file18 30 *1840 XLOCK LDA #DFDLOC set lock1850 .BYTE $2C skip word by nonsense instruction1860 *1870 XUNLOCK LDA #0 set unlock1880 * common continuation1890 STA TEMP41900 JSR XSTAT decode file name and find 1st match1910 XLC1 LDY CDIRD get current displ1920 LDA FILDIR+DFDFL1,Y get lock byte1930 AND #$DF turn off lock1940 ORA TEMP4 or in lock/unlock1950 STA FILDIR+DFDFL1,Y set new lock byte1960 JSR WRTDIR go write1970 JSR CSFDIR look for next matc h1980 BCC XLC1 br found1990 JMP FGREAT else done2000 *2010 * TSTLOCK - test file locked2020 * don't rtn if file locked2030 *2040 TSTLOCK LDY CDIRD get dir displ2050 LDA FILDIR+DFDFL1,Y load lock byte2060 AND #DFDLOC mask loc k bit2070 BEQ :EXIT br & rtn if not locked2080 JSR ERROR error: file locked2090 .BYTE $A7 (error # 167)2100 .PAGE "POINT"2110 *2120 * XPOINT - point request2130 *2140 * sets diskette location of next byte to be read or writ ten2150 * (file must have been opened for update)2160 * expects sector number in ICAUX3/4 (lsb/msb)2170 * and relative sector displacement in ICAUX52180 *2190 XPOINT LDA FCBFLG,X if acquire sectors2200 BMI PERR1 point invalid2210 LDA IC AUX4,X if request is not same as current2220 CMP FCBCSN+1,X2230 BNE XP1 then br2240 LDA ICAUX3,X2250 CMP FCBCSN,X2260 BEQ XP2 else no need to change2270 XP1 LDA FCBFLG,X if not modified2280 BEQ XP1A br2290 JSR WRCSIO else write it2300 LDA #02310 STA FCBFLG,X2320 XP1A LDA ICAUX4,X2330 STA FCBLSN+1,X2340 LDA ICAUX3,X2350 STA FCBLSN,X2360 JSR RDNSO read req sector2370 BCS XPERR2380 XP2 LDA ICAUX5,X test req data len23 90 CMP FCBMLN,X less then max2400 BCC XP32410 BEQ XP32420 XPERR JSR ERROR if not then: point data length error2430 .BYTE $A6 (error # 166)2440 XP3 STA FCBDLN,X set new data len2450 JMP GREAT2460 PERR1 JSR ERROR error: invali d point2470 .BYTE $AB (error # 171)2480 .PAGE "NOTE"2490 *2500 * XNOTE - execute note request2510 *2520 * returns the diskette location of next byte to be read or2530 * written2540 * sector number in ICAUX3/4 (lsb/msb)2550 * relative sector displ in ICAUX52560 *2570 XNOTE LDA FCBDLN,X data length value2580 STA ICAUX5,X to aux52590 LDA FCBCSN,X current sector number (lo)2600 STA ICAUX3,X to aux32610 LDA FCBCSN+1,X curr sec no (hi)2620 STA ICAUX4,X to aux42 630 JMP GREAT2640 .PAGE "LIST DIRECTORY"2650 .LOCAL 2660 *2670 * LISTDIR -- list the directory, called by DFMOPN2680 * GDCHAR -- get next dir character, called by DFMGET2690 *2700 * the directory is listed via open list directory2710 * function. Each dir entry that matches the file2720 * spec is converted to a printable format into a2730 * sector buffer. The get byte entry is used to get2740 * the printable characters one at a time. The last2750 * line printed is always a count of the number of2760 * sectors remaining available.2770 *2780 * Files invisible to single density DOS 2.0 will have their2790 * names placed between brackets if ICAUX1 has bit 0 set.2800 * A directory opened with ICAUX1 set to 7 will return with2 810 * brackets, if necessary. The traditional ICAUX1 value2820 * of 6 will not.2830 *2840 LISTDIR JSR SFDIR search for a file name2850 BCC LDENT1 br if found2860 * prepare SECTORS FREE line2870 LDCNT JSR RDVTOC read VTOC2880 LDY #DVDESA get enhanced # sector available (lo byte)2890 LDA (ZDRVA),Y2900 LDY #DVDNSA add to # sector available2910 CLC 2920 ADC (ZDRVA),Y2930 PHA save on stack2940 INY do hi byte2950 LDA (ZDRVA),Y get # sector a vailable2960 LDY #DVDESA+12970 ADC (ZDRVA),Y add to enhanced # sector2980 TAX save hi byte in X reg2990 PLA 3000 TAY lo byte in Y reg3010 TXA hi byte in accu3020 LDX #0 set char cnt = 0303 0 STX TEMP23040 JSR CVDX and convert3050 LDY #3 set to position 33060 TXA put there a blank or a '+'3070 STA (ZSBA),Y3080 INY incr to position 43090 MVFSCM LDA FSCM-4,Y text 'FREE SECTORS'3100 S TA (ZSBA),Y3110 INY 3120 CPY #$103130 BNE MVFSCM loop until 16 bytes3140 JSR CVDY do eol3150 GDCRTN JMP GREAT and rtn3160 * get next dir char3170 GDCHAR LDY TEMP2 get count of chars sent3180 BPL :LBL1 br if o.k.3190 JMP PEOF set to $80 if all done3200 :LBL1 LDA (ZSBA),Y get next char3210 STA SVDBYT in SVDBYT3220 INC TEMP2 inc count3230 CMP #EOL test if eol done3240 BNE GDCRTN br not eol3250 CPY #17 was this an entry3260 BCS LDENT br if it was3270 LDA #$80 else indicate end3280 STA TEMP2 in char counter3290 JMP FGREAT done3300 * look for more matches3310 LDENT JSR CSFDIR search for next match3320 BCS LDCNT br no more matches3330 *3340 LDENT1 JSR FDENT format entry3350 JMP GREAT done3360 * message3370 FSCM .BYTE "FREE SECTORS"3380 * format dir entry into a sector buffer3390 FDENT LDX CDIRD get curr dir displ3400 LDY #0 start at displ zero3410 LDA #$20 sta rt with a blank3420 STA (ZSBA),Y3430 LDA FILDIR+DFDFL1,X3440 AND #DFDLOC but if file locked3450 BEQ LD13460 LDA #'* change to asterix3470 STA (ZSBA),Y3480 LD1 INY 3490 LDA #$20 followed by a blank3500 STA (ZSBA),Y3510 INY 3520 LD2 LDA FILDIR+DFDPFN,X move the 12 char3530 STA (ZSBA),Y file name3540 INX 3550 INY 3560 CPY #133570 BCC LD23580 LDA #$20 followed by a blank3590 STA (ZSBA),Y3600 INY 3610 STY TEMP2 save line index3620 LDX CDIRD recall file dir index3630 * place brackets if necessary3640 LDA ICAX1Z get aux13650 ROR A3660 BCC :SKIP skip brackets if bit 0 zero3670 LDA FILDIR+DFDFL1,X get flag3680 ROR A3690 BCC :SKIP no brackets if bit 0 zero3700 DEY else, change last blank3710 LDA #'> to right bracket3720 STA (ZSBA),Y3730 LDY #1 change bracket at position 13740 LDA #'< to left bracket3750 STA (ZSBA ),Y3760 :SKIP LDY FILDIR+DFDCNT,X set A,Y to sector count3770 LDA FILDIR+DFDCNT+1,X3780 * calculate decimal sector cnt3790 CVDX LDX #100 convert and move3800 JSR CVDIGIT 100s digit3810 LDX #103820 JSR CVDIGIT 10s digit3830 LDX #13840 JSR CVDIGIT 1s digit3850 LDX #$20 prepare for a trailing blank3860 TYA test if any value left3870 BEQ :L4 no, skip the '+'3880 LDX #'+ otherwise, change to plus3890 :L4 LDY #17 then put out390 0 CVDY LDA #EOL an eol3910 STA (ZSBA),Y3920 LDY #03930 STY TEMP2 set char cnt = 03940 RTS done3950 * convert digit3960 CVDIGIT STX SVD2 save digit value3970 LDX #$FF3980 CVD1 STA ZBUFP+1 save current value hi3990 STY ZBUFP and lo4000 INX inc digit counter4010 SEC subtract digit value4020 LDA ZBUFP from curr value4030 SBC SVD24040 TAY 4050 LDA ZBUFP+14060 SBC #04070 BCC STDIGIT if gone minus, done4 080 CPX #9 otherwise, check for 9 (don't exceed 999)4090 BNE CVD1 if not equal, do again4100 STDIGIT TXA digit to accu4110 ORA #$30 plus ascii zero4120 LDY TEMP2 get output index4130 STA (ZSBA),Y and set digit4 140 INC TEMP2 inc output index4150 LDA ZBUFP+1 load value hi4160 LDY ZBUFP and value lo4170 RTS 4180 .PAGE "FILE NAME DECODE"4190 *4200 * FNDCODE -- decode a file name4210 *4220 * The user filename is pointed to by ICBAL/ H. It is4230 * on the form P.X where P is the primary file name4240 * (1 to 8 chars) and X is the extended file name4250 * (0 to 3 chars). The period is optional (if not4260 * present, then no extension). The decoded file4270 * name will be 11 char s in length. The P field will4280 * be left justified in the 1st 8 bytes. The X field4290 * will be left justified in the last 3 bytes. Blanks4300 * are used to pad the fields to full size. If the4310 * user specified P or X fields contain more than 4320 * 8 or 3 chars, then the extra chars are ignored.4330 * The '*' wild card char will cause the rest of the4340 * field to be filled with the '?' wild card char. Any4350 * non-alphanumeric char terminates the filename.4360 *4370 FNDCODE LDY #2 find the ':'4380 FD0A LDA (ICBALZ),Y4390 DEY 4400 BMI FNDERR br if not 2nd or 3rd place4410 CMP #':4420 BNE FD0A not found, try again4430 INY found, restore index4440 * decode next char4450 FNDCNX INY inc IC BALZ index to start of primary fn4460 LDA #8 set primary fn length4470 LDX #0 index to FNAME4480 :LBL5 STA EXTSW set length of field4490 :LUS LDA (ICBALZ),Y get char4500 CMP #'. was char field seperator4510 BNE FD3 br if not4520 * process period4530 CPX #8 at end of P field4540 BNE :LBL4 br if so4550 INY otherwise, advance to extender field4560 LDA #11 set P + X field length4570 BNE :LBL5 (always)4580 :LBL4 BCC :L6 br if index less than field length to pad with blanks4590 * process chars4600 FD3 CMP #'* test for asterix wild cards4610 BNE FD4 br if not4620 LDA #'?4630 CPX EXTSW end of field?4640 BCS FD6 yes, advance to next f ield4650 BCC FD6A no, pad field with question marks4660 * NOTE:4670 * Contrary to DOS 2.0, this version accepts numeric and4680 * alpha chars in all positions, including a primary4690 * filename beginning with a numeric. Lowercase is accepte d4700 * as input, but changed to, and handled as, uppercase.4710 FD4 CMP #'? was it ? wild card4720 BEQ FD6 yes, br4730 CMP #'0 is char numeric4740 BCC FD5 br not numeric (period or end of name)4750 CMP #'9+1 test numeric hi4760 BCC FD6 o.k., br4770 AND #$DF change lowercase to upper4780 CMP #'A is char alpha4790 BCC FD5 br not alpha4800 CMP #'Z+1 test hi alpha4810 BCC FD6 o.k., br4820 * process period or non l egal char4830 FD5 LDA #11 set P + X field length4840 STA EXTSW4850 CPX #11 complete file name moved?4860 BEQ :LBL3 br if so4870 :L6 LDA #$20 otherwise, pad with blanks4880 BNE FD6A (always)4890 * char to FNAME4900 FD6 INY 4910 FD6A CPX EXTSW end of field?4920 BEQ :LUS br if so4930 STA FNAME,X otherwise, set char into name4940 INX inc to next char4950 BNE :LUS (always)4960 * test filename4970 :LBL3 LDA FNAME is first char fna me a blank4980 CMP #$204990 BEQ FNDERR yes, error5000 LDX CURFCB no, restore FCB5010 RTS 5020 * error exit5030 FNDERR JSR ERROR file name error5040 .BYTE $A5 (error # 165)5050 .PAGE "DIRECTORY SEARCH"5060 .LOCAL 5070 *5080 * SFDIR -- search file directory5090 * CSFDIR -- continue search5100 *5110 * The file directory is searched for the filename in FNAME. The5120 * search starts at the central sector+1 and will continue for5130 * up to a total of 8 secto rs. When testing for FNAME match, '?'5140 * FNAME chars will always match the corresponding dir filename5150 * char. If a match is found CDIRS contains the relative5160 * directory sector number (0-7) and CDIRD (and the Y reg)5170 * contains the dis placement of the entry. After a match has5180 * been found, the directory can be searched for another match5190 * via the CSFDIR entry point. If a match has not been found then5200 * DHOLES and DHOLED will point to a directory hole that can be5210 * used. If DHOLED = FF then the directory is full. The carry5220 * is returned clear if file found, set if file not found.5230 *5240 * Dir entries are flaged:5250 * bit 7 - deleted (if set)5260 * 6 - in use5270 * 5 - locked5280 * 1 - created by DOS 25290 * 0 - open for output if bit 6 set5300 * - in used by enh sectors if bit 6 zero5310 *5320 SFDIR LDA #$FF init to -15330 STA DHOLES dir hole sector5340 STA CDIRS curr dir sector5350 STA SFNUM f ile number5360 LDA #$70 init to -16 (-entry length)5370 STA CDIRD curr dir displ5380 *5390 CSFDIR INC SFNUM5400 CLC 5410 LDA CDIRD CDIRD = CDIRD + entry len5420 ADC #DFDELN5430 BPL SFD2 if result <128 then br, e lse at end of dir sect5440 INC CDIRS inc to next dir sector5450 LDA #8 test end of dir5460 CMP CDIRS5470 BCC SFD1 br not end5480 BEQ SDRTN5490 SFD1 JSR RDDIR read the next dir record5500 LDA #0 set dir disp l = 05510 SFD2 STA CDIRD set new dir displ5520 TAY put displ in Y as index5530 LDA FILDIR+DFDFL1,Y get flag 15540 BEQ SFDSH br if unused (end of used entries)5550 BMI SFDSH br if deleted5560 AND #$43 mask off lo ck bit5570 CMP #3 is it enhanced sector file?5580 BEQ :LBL1 br if so5590 AND #DFDOUT if open output5600 BNE CSFDIR don't find it5610 * entry in use, test for match5620 :LBL1 LDX #0 test match on 11 chars5630 SFD3 LDA FN AME,X file name char5640 CMP #'? is fnc wild card5650 BEQ SFD4 then it matches5660 CMP FILDIR+DFDPFN,Y else it must match for real5670 BNE CSFDIR if not match then try next5680 SFD4 INX inc char count5690 INY 57 00 CPX #11 test all5710 BNE SFD3 and continue check5720 CLC we have a match5730 BCC SDRTN5740 * empty or deleted5750 SFDSH LDA DHOLES if DHOLES not minus5760 BPL SFDSH1 then already have a good hole5770 LDA CDIRS else, move curr displ sector5780 STA DHOLES and current dir displ5790 LDA CDIRD to hole sector and displ5800 STA DHOLED5810 LDA SFNUM save hole5820 STA DHFNUM file number5830 SFDSH1 LDA FILDIR+DFDFL1,Y if hole wa s deleted5840 BMI CSFDIR entry then continue, else we are at end of5850 SEC used entries thus file not found5860 SDRTN LDX CURFCB restore FCB5870 RTS 5880 .PAGE "STATUS SUBROUTINE"5890 *5900 * search for a file (don't rtn if not found)5910 *5920 XSTAT JSR FNDCODE decode file name5930 JSR SFDIR search for file5940 BCS :ERR br not found5950 RTS rtn if o.k.5960 :ERR JMP OPNER1 not found, so go with error 170 (file not found)5970 .PAGE "W RITE DATA SECTOR"5980 *5990 * WRTNXS - write next sector6000 *6010 WRTNXS LDA FCBFLG,X if acquiring sectors6020 BMI WRTN1 then no update6030 * process update6040 ASL A if sector not modified6050 BPL WRU1 then skip write60 60 ASL A6070 STA FCBFLG,X turn off flag bits6080 JSR WRCSIO write current sector6090 BMI WRNERR br if bad i/o6100 WRU1 JMP RDNXTS else read next sector6110 * process no update6120 WRTN1 JSR GETSECTOR get a new sector6130 * entry point for write last sector, called from CLOSE6140 WRTLSEC LDA FCBDLN,X get data len6150 LDY #127 into last byte6160 STA (ZSBA),Y of sector6170 WRTN2 LDA FCBLSN+1,X move link sector6180 ORA FCBFNO,X plus file number6190 LDY #12 5 to bytes 125-1266200 STA (ZSBA),Y of sector buff6210 INY 6220 LDA FCBLSN,X link sector in msb/lsb order (10 bits)6230 STA (ZSBA),Y6240 JSR WRCSIO write sector6250 BPL WRTN5 br no error6260 WRNERR LDA #0 close fil e6270 STA FCBOTC,X6280 LDA DCBSTA recover error status6290 JMP RETURN6300 * update FCB6310 WRTN5 INC FCBCNT,X inc sector count6320 BNE WRTN66330 INC FCBCNT+1,X6340 WRTN6 JSR MVLSN link acquired sector to curr6350 LDA #0 6360 STA FCBLSN,X set link to zero6370 STA FCBLSN+1,X6380 STA FCBDLN,X data length also6390 LDA #125 set max data length6400 STA FCBMLN,X6410 CLC 6420 RTS 6430 *6440 WRCSIO SEC set for write curr sector6450 * read/write current sector (# in FCBCSN)6460 RWCSIO LDA FCBCSN+1,X6470 LDY FCBCSN,X6480 JMP DSIO6490 * move link sector no to current sect no6500 MVLSN LDA FCBLSN,X move link6510 STA FCBCSN,X6520 LDA FCBLSN+1,X6530 STA FCBCS N+1,X6540 RTS sector (# in FCBCSN)6460 RWCSIO LDA FCBCSN+1,X6470 LDY FCBCSN,X6480 JMP DSIO6490 * move link sector no to current sect no6500 MVLSN LDA FCBLSN,X move link6510 STA FCBCSN,X6520 LDA FCBLSN+1,X6530 STA FCBCS 1000 * RECDOS4.M651010 .PAGE "READ DATA SECTOR"1020 *1030 * RDNXTS - read next sector1040 *1050 RDNXTS LDA FCBFLG,X if not upd mode1060 BEQ RDNSO br1070 JMP WRTNXS else write first1080 RDNSO LDA FCBLSN,X if LSN not zero1090 ORA FCBLSN+1,X1100 BNE RDNS1 br1110 SEC else eof1120 RTS 1130 RDNS1 JSR MVLSN move link to current1140 CLC read1150 JSR RWCSIO current sector1160 BMI RDIOER br if i/o error1170 LDY #1251180 LDA (ZSBA),Y test for same file no1190 AND #$FC mask off sector bits1200 CMP FCBFNO,X1210 BNE RDFNMM if not, then error1220 * update FCB1230 LDA (ZSBA),Y move link sector1240 AND #3 mask off file no bits1250 STA FCBLSN+1,X1260 INY get lower part of link sector #1270 LDA (ZSBA),Y1280 STA FCBLSN,X1290 INY inc to len byte1300 LDA (ZSBA),Y get len byte1310 PHA save it1320 LDA FCBSLT,X get sector len type1330  BNE RDNS3 br if new type1340 PLA get len1350 BMI RDNS2 br if old short sector1360 LDA #125 else set full sector1370 RDNS2 AND #$7F turn off msb1380 PHA balance stack1390 RDNS3 PLA 1400 STA FCBMLN,X set max len1410 LDA #0 set curr data len = 01420 STA FCBDLN,X1430 CLC 1440 RTS 1450 RDIOER JSR ERRIO i/o error1460 * file number mismatch1470 RDFNMM LDA ICCOM,X recall cmnd1480 CMP #$21 was this delete?1490 BEQ RDDELE br if delete1500 JSR ERROR otherwise, file number mismatch1510 .BYTE $A4 (error # 164)1520 RDDELE SEC indicate eof to delete1530 RTS 1540 .PAGE "READ/WRITE DIR"1550 .LOCAL 1560 *1570 * RDDIR/WRTDIR - read/write directory1580 *1590 RDDIR CLC set read1600 BCC DIRIO1610 *1620 WRTDIR SEC set write1630 * calls DSYSIO with lo byte dir sector in Y, file1640 * dir buff in X/A (lo/hi) and r/w in carry1650 DIRIO PHP save read/write1660  CLC 1670 LDA CDIRS CDIRS +1680 ADC #$69 ((40*18)/2)+1 (is dir sector number)1690 TAY into Y (lo byte)1700 PLP 1710 LDX # >FILDIR file directory buffer in X/A1720 LDA # FMSORG move DOS start addr to DCB4760 STA DCBBUF+14770 LDY # RDTXT1370 JSR DUP11380 LDA # AF1400 JMP DUP1 and rtn1410 RDTXT .BYTE "D:RAMDISK.COM",EOL1420 *1430 * check for 2.5 DUP1440 *1450 CHKD25 LDA #$4C is it 2.5?1460 CMP JDOSOS1470 BNE :DOCHK no, br1480 JMP CIO1 o.k., call CIO an"d go to DOS menu if break key abort1490 :DOCHK LDA #0 set no DUP in memory1500 STA DUPFLG1510 LDA # NDTXT1530 JSR ERR21540 JMP :DOCHK loop until return is pressed1550 *1560 #* patch for o.s. Rev.1 serial output interrupt service routine1570 * only installed if Rev.1 o.s. is active1580 *1590 ISRODN LDA CHKSNT test checksum sent1600 BNE :SENT br if sent1610 JMP $EA90 to o.s. ISRODN entry point1620 :SENT TYA $ stack Y register1630 PHA 1640 JMP $EAB3 to o.s. CHKDON entry point1650 *1660 .BYTE $B3,$EA,0,0,0,0,0 fossil filler bytes1670 *1680 * go read VTOC1690 *1700 XRDVT TSX save stack level1710 STX ENTSTK1720 JSR RDV%TOC do VTOC read1730 LDY #1 set o.k. status1740 RTS 1750 *1760 * go write VTOC1770 *1780 XWTVT TSX save stack level1790 STX ENTSTK1800 JSR WRTVTOC do VTOC write1810 LDY #1 set o.k. status1820 RTS 1830 & .PAGE "MINIDUP -- init code for DUP"1840 DDSKNO .BYTE '8 drive number of DUP.SYS file1850 *1860 * initialization code for DUP - calls FMS init code1870 * called on warm start and cold start1880 *1890 DUPINIT LDA #0 reset option1900 STA O'PT1910 LDA # MNDUP1940 STA DOSVEC+11950 LDA $EA9C test for o.s. version (Rev.2 $A5, XL $85)1960 CMP #$901970 BNE XINIT if not rev.1 skip SIO patch1980 L(DA # ISRODN2010 STA VSEROR+12020 XINIT JSR DINIT FMS initialization2030 NOP 2040 NOP 2050 ) NOP 2060 LDA WARMST test for coldstart2070 BNE CKMDOS br if warm2080 JSR D8INIT load and run RAMDISK.COM and AUTORUN.SYS files2090 RTS return control to o.s.2100 * run disk file (RAMDISK/AUTORUN), pointed to by A/X -- c*alled from D8INIT2110 DUP1 STA ICBAL+16 store low byte filename2120 STX ICBAH+16 hi byte2130 JSR INITX clear DUPFLG show DUP not in memory2140 LDA #$C02150 JSR STLOAD load, init and run the file2160 JMP CLOSX make sure ioc+b #1 is closed & return2170 * warmstart2180 CKMDOS LDA DUPFLG see if DUP was in memory2190 BEQ INITX if zero then wasn't2200 LDA MEMFLG see if user area written to MEM.SAV2210 BEQ CLDSET if zero then wasn't2220 JSR LDMEM1 else, get user memory back in2230 JSR RELDIN reload saved DOSINI vector2240 JSR INITX clear DUP in memory flag2250 JSR WARMSV redo warm start2260 INITX LDA #0 say DUP not in memory2270 STA DUPFLG clear flag2280 RTS 2290 *2-300 CLDSET STA WARMST no valid user memory2310 BEQ INITX set to cold start2320 .PAGE "MINIDUP -- loader routine"2330 *2340 * loads from the file (must be load format) into memory2350 * returns: X=0 load o.k.2360 * X=1 open error.s Y=CIO code2370 * X=2 read errors Y=CIO code2380 * X=3 bad load file2390 * on entry, IOCB 1 points to filename2400 *2410 DUPFLG .BYTE 0 flag - if DUP in memory not zero2420 OPT .BYTE 0 holds value of option given by user24/30 LOADFLG .BYTE 0 flag = $80 if memory file doesn't have to be loaded2440 HDBUF .WORD 0,0 temp for start/end address2450 * open file2460 SFLOAD LDA #$802470 STLOAD STA LOADFLG2480 LOAD LDA # LRTS2510 S0TA RUNAD+1 make run at eof default to LRTS2520 LDX #$10 iocb #12530 LDA #3 open2540 STA ICCOM,X2550 LDA #4 open type=input2560 STA ICAUX1,X2570 JSR GOCIO try to open file2580 BPL RDLF cont if o.k.25910 LDA #1 open errors2600 BNE CLFX close and exit2610 * read two header bytes2620 RDLF LDX #$10 iocb #12630 LDA # DBUF2660 STA ICBAH,X2670 LDA #22680 STA 2ICBLL,X2690 LDA #02700 STA ICBLH,X2710 STA MEMLDD clear MEM.SAV loaded flag2720 LDA #7 get char2730 STA ICCOM,X2740 JSR CIOV2750 BMI ERST if errs2760 LDA #$FF2770 CMP DBUF check for valid load fil3e2780 BNE LNLF2790 CMP DBUF+12800 BNE LNLF branch if not a load file2810 * get section of load file2820 * read start/end address to HDBUF2830 RDDRC LDX #$102840 LDA # HDBUF2870 S4TA ICBAH,X2880 LDA #42890 RDDRC1 STA ICBLL,X2900 LDA #02910 STA ICBLH,X2920 JSR CIOV no error check so can catch eof2930 BPL STOK if no error2940 CPY #$88 see if eof2950 BNE ERST if some error status2960 5* eof so done, exit2970 JSR CLOSX close iocb's 1 and 22980 BIT OPT2990 BMI DRUN branch if no run option3000 JSR JMPRUN jump through run vector3010 DRUN LDA #0 o.k. status3020 BIT LOADFLG was memory swapped?3030 S6TA LOADFLG reset flag3040 BMI CLFX branch if memory wasn't swapped3050 JSR MEMSVG does memory save file exist?3060 BMI DRUN1 branch if not3070 PLA 3080 PLA 3090 JMP GOOD write memory and reload DUP3100 *3110 * Se7e if DUP written over. If is reload & tell3120 * user need MEM.SAV to load this file.3130 *3140 DRUN1 LDA DUPFLG see if DUP globbered3150 BNE DRUN2 no, then return3160 LDA # NMSF3180 8JSR PRNTMSG print msg3190 JMP RRDUP reload & run DUP3200 * return to calling routine3210 DRUN2 LDA #0 no DUP err msg on eof3220 CLFX TAX 3230 LRTS RTS 3240 * error returns3250 LNLF JSR CLOSX3260 LDA #3 bad load file3270 BN9E CLFX (always)3280 ERST TYA 3290 PHA 3300 JSR CLOSX3310 PLA 3320 TAY 3330 BNE CLFX (always)3340 * continue with load - check load address for header3350 * if have concatenated load files3360 STOK LDX #$103370 LDA: HDBUF move params to iocb3380 STA ICBAL,X3390 PHA 3400 LDA HDBUF+13410 STA ICBAH,X3420 TAY 3430 PLA 3440 INY was address FF?3450 BNE ADOK branch if not3460 TAY 3470 INY other byte F;F?3480 BNE ADOK branch if not3490 * have a header & start address - get end address for text & do again3500 LDA HDBUF+23510 STA HDBUF3520 LDA HDBUF+33530 STA HDBUF+1 move load address3540 LDA # HDBUF+23570 STA ICBAH,X so load address doesn't get wiped out3580 LDA #23590 JMP RDDRC1 read end address3600 * get length of text, then determine if in DUP3610 ADOK LDA HDBUF+23620 SEC 3630 SBC HDBUF3640= STA ICBLL,X3650 LDA HDBUF+33660 SBC HDBUF+13670 STA ICBLH,X3680 LDA HDBUF+1 is beginning address within DUP?3690 CMP # >[NMDUP+1]3700 NOP 3710 BCS ANWD branch if hi byte outside DUP addr space3720 LDA HDBU>F+3 is ending address within DUP?3730 CMP # >NDOS end of system buffers and minidup3740 NOP 3750 BCS AWD br if less, since in DUP, load MEM.SAV is neccesary3760 * outside DUP, load MEM.SAV not neccesary3770 ANWD LDA MEMLDD3780 ?BMI AWD branch if MEM.SAV already loaded3790 LDA #$803800 ORA LOADFLG3810 STA LOADFLG set MEM.SAV doesn't have to be loaded flag3820 * adjust length & load3830 AWD INC ICBLL,X3840 BNE :AWD13850 INC ICBLH,X3860 :AWD1 BIT L@OADFLG does memory have to be loaded3870 BMI DLM branch if not3880 LDA MEMLDD was MEM.SAV already loaded?3890 BMI DLM branch if so3900 DEC MEMLDD3910 JSR LDMEM load MEM.SAV file (if it exists)3920 LDA #0 shoAw user area not DUP in memory3930 STA DUPFLG3940 JSR RELDIN restore DOS init vector from saved location3950 * set no init addr default then read in text & attempt init3960 DLM LDX #$103970 LDA # LRTS4000 STA INITAD+1 init defaults to a rts4010 JSR CIOV read data directly to memory4020 BPL DLM14030 JMP ERST if errors4040 DLM1 BIT OPT4050 BMI DIN branch if no go option4060 JSR JMPINT do init4070 DIN JMCP RDDRC get next section of load file4080 * the following code is a fossil4090 * it used to determine if an address is within DUP space4100 CMP # >NDOS4110 BCC :AWDQR branch if hi byte lt DUP start4120 CMP # >[NMDUP+1]4130 :USRDOS RDOL A label mentioned in 'Mapping'4140 EOR #14150 LSR A complement carry4160 :AWDQR RTS 4170 *4180 JMPINT JMP (INITAD)4190 JMPRUN JMP (RUNAD)4200 *4210 MEMLDD .BYTE 0 MEM.SAV already loaded flag4220 AF .BYTE "D1:AUTORUN.SYS",EOEL4230 NMSF .BYTE "NEED MEM.SAV TO LOAD THIS FILE.",EOL4240 .PAGE "MINIDUP -- create MEM.SAV file"4250 *4260 * routine written by M.E., april 21, 19804270 * this routine creates a file on disk of data from memory4280 * create file called 'Dn:MEFM.SAV', set Y=14290 * able to create file then set reg. Y=error returned from CIO4300 * the ram to be occupied by DUP is stored by this routine into MEM.SAV4310 .LOCAL 4320 MSTXT .BYTE "D8:MEM.SAV",EOL4330 *4340 MWRITE JSR CLOSX close iocb's aGnd open #2 to write4350 LDA #84360 STA ICAUX1,X4370 JSR OREST4380 BMI ERRWR if error then jmp and ret4390 * write memory block4400 LDA #11 put char4410 STA ICCOM,X4420 LDA # NDOS start addr (high)4450 STA ICBAH,X4460 LDA # LEN length (high)4490 STA ICBLH,X4500 JSR CIOV write data block4510 BMI ERRWR iIf write error then jmp4520 JSR CLOSX4530 BMI ERRWR4540 LDY #04550 RTS 4560 * routine to complete open of 'Dn:MEM.SAV' -- calling4570 * sub supplies 'read' or 'write' in ICAX14580 OREST LDA #3 open4590 STA ICCOM,X4600 JLDA # MSTXT4630 STA ICBAH,X4640 JMP GOCIO4650 *4660 ERRWR RTS error rtn4670 * to CIO after storing DUP drive4680 GOCIO LDA DDSKNO get drive # of DUP.SYS file4690 STKA MSTXT+1 set at Dn:MEM.SAV filename4700 STA DUPSYS+1 set at Dn:DUP.SYS filename4710 JMP CIOV call CIO and rtn4720 *4730 .BYTE $17,$A0,$90,$60 fossil filler bytes4740 .PAGE "MINIDUP -- entry point on 'DOS' call"4750 INISAV .WORDL 0 DOSINI vector save loc4760 MEMFLG .BYTE 0 set to FF for memory written to MEM.SAV, else zero4770 *4780 MNDUP LDX #04790 STX MEMFLG memory not saved4800 STX LOADFLG memory should be saved4810 DEX 4820 STX WARMST assume no coMld start needed4830 JSR INITIO close iocb's and reopen E:4840 JSR MEMSVG find out if file Dn:MEM.SAV exists4850 BPL GOOD branch if so4860 LDA #04870 STA WARMST clear warm start flag4880 BEQ FINAL (always)4890 * wriNte memory file4900 GOOD JSR MWRITE write user area to MEM.SAV4910 BMI PERROR4920 DEC MEMFLG show memory written4930 BMI FINAL (always)4940 * MEM.SAV failed, print error message4950 PERROR LDA # OERRMES4970 JSR PRNTMSG goto msg printer4980 LDA # ERR5000 ERR2 JSR PRNTMSG5010 * wait for Y to run DOS5020 LDA #5 get record5030 STA ICCOM5040 LDA # STAK05070 STA ICBAH5080 LDA #25090 STA ICBLL5100 LDA #05110 STA ICBLH5120 JSR CIOV5130 LDA STAK0 see if Y typed5140 CMP #'Y5150 BNE RTCART branch if not5160 LDA #05170 STA WARMST5Q180 *5190 FINAL LDX #$20 close MEM.SAV file5200 LDA #125210 STA ICCOM,X5220 JSR CIOV5230 *5240 RRDUP LDA DOSINI save DOS init vector5250 STA INISAV5260 LDA DOSINI+15270 STA INISAV+15280 LDA # DUPINIT5310 STA DOSINI+15320 RRDUP1 LDA # DUPSYS5360 STA ICBAH,X5370 LDY #05380 STY OPT assure no /N Soption in effect5390 DEY show that DUP is in memory5400 STY DUPFLG5410 JSR SFLOAD load DUP.SYS and run it5420 RTCART RTS 5430 *5440 EC .BYTE "E:",EOL5450 DUPSYS .BYTE "D8:DUP.SYS",EOL5460 ERRMES .BYTE "ERROR-SAVING USER MEMTORY ON DISK",EOL5470 ERR .BYTE "TYPE Y TO STILL RUN DOS",EOL5480 .PAGE "MINIDUP -- subroutines"5490 * routine tests if MEM.SAV is present on the disk5500 * returns - minus if not there5510 * plus if MEM.SAV is there5520 *5530 MEMSVGU JSR CLOS20 close iocb #25540 LDA #3 open5550 STA ICCOM,X5560 LDA # MSTXT5590 STA ICBAH,X5600 LDA #12 read/write5610 STA ICAUX1,X try to open Dn:MEM.SAV for read/write56V20 JSR GOCIO5630 PHP save status5640 JSR CLOS20 close MEM.SAV5650 PLP restore status5660 RTS 5670 *5680 * save file subroutine - write file body, init, & run vectors5690 *5700 WDR1 LDA #0 this immediate vWalue modified5710 BEQ WDR2 br if mem file doesn't have to be loaded5720 JSR LDMEM reload saved memory5730 WDR2 LDX #$105740 JSR CIOV do save - write body to disk5750 INITQ LDA #0 this immed value changed during save5760 XBEQ RUNQ set to FF when an init vector is present5770 INC INITQ+15780 LDA INITAD5790 STA VECTR if init vector for file save it5800 LDA INITAD+15810 STA VECTR+15820 LDA # INITAD5860 JSR WRVEC5870 RUNQ LDA #0 this immediate value modified5880 BEQ NORNAD set to FF when a run vector is present5890 INC RUNQ+15900 LDA RUNAD5910 STA VECTR if run vector for file save it5920 LDA RUNAZD+15930 STA VECTR+15940 LDA # RUNAD5980 JSR WRVEC5990 NORNAD JSR CLOSX close iocb's 1&26000 LDA MEMFLG6010 AND WDR1+16020 BEQ DRRDUP6030 INC WDR1+1 reset mem nee[ds to be loaded flag6040 JMP RRDUP1 reload & run DUP6050 DRRDUP JMP JDOSOS run the swapped in DUP6060 *6070 WRVEC STA LDST+16080 INX 6090 STX LDND6100 STA LDND+16110 LDX #$106120 LDA # LDST6150 STA ICBAH,X6160 LDA #66170 STA ICBLL,X6180 LDA #06190 STA ICBLH,X6200 JMP CIOV write init or run address6210 *6220 * jump to cartridge6230 *6240 CLMJMP JSR LDMEM6250 LDA #0 show DUP no lon]ger in memory6260 STA DUPFLG6270 JSR RELDIN restore DOS init vector saved6280 JMP (CARTSA) jump to cartridge6290 *6300 * load MEM.SAV (if it exists) before run at address6310 *6320 LMTR JSR LDMEM load MEM.SAV if it exists6330 L^DA #0 show that DUP no longer in memory6340 STA DUPFLG6350 JSR RELDIN restore DOS init vector saved6360 JMP (RAMLO) run at address6370 *6380 * restore DOSINI vector from saved location6390 *6400 RELDIN LDA INISAV6410 STA DO_SINI6420 LDA INISAV+16430 STA DOSINI+16440 RTS 6450 *6460 * subroutine LDMEM - load MEM.SAV if it exists6470 *6480 LDMEM LDA MEMFLG6490 BNE LDMEM1 branch if memory was saved6500 RTS 6510 LDMEM1 JSR MEMSVG6520 BPL LDME`M2 branch if MEM.SAV file does exist6530 LDA #0 tell cart pgm area clobbered6540 STA WARMST6550 BEQ CLOS2 go close and goto cart6560 *6570 LDMEM2 LDA #3 open6580 STA ICCOM,X6590 JSR GOCIO reopen MEM.SAV6600 LDaA #7 get char6610 STA ICCOM,X6620 LDA #[ LEN6650 STA ICBLH,X6660 LDA # NDOS6690 STA ICBAH,X6700 JSR CIOV6710 CLOS2 LDA #12 closbe6720 STA ICCOM,X6730 JMP CIOV close MEM.SAV6740 *6750 * close all iocbs & re-open zero as screen editor6760 *6770 INITIO JSR CIOINV this routine closes all iocbs6780 LDX #0 then reopens the screen editor6790 LDA #3 copen6800 STA ICCOM,X6810 LDA # EC6840 STA ICBAH,X6850 LDA #12 read/write6860 STA ICAUX1,X6870 JMP CIOV call CIO and rtn6880 *6890 * CLOSX - close iocbs 1 & 26900 *6910 CLOdSX LDA #12 close6920 LDX #$106930 STA ICCOM,X6940 JSR CIOV6950 * entry point to close iocb #2 only6960 CLOS20 LDX #$206970 LDA #12 close6980 STA ICCOM,X6990 XCIO JMP CIOV also used by PRNTMSG subroutine7000 *7010 * esubroutine PRNTMSG7020 * puts a character string terminated by a7030 * carriage return char to screen editor7040 * entry - lo/hi byte msg address in A/X7050 * put params in iocb - use iocb 0 for screen editor7060 *7070 PRNTMSG STA ICBAL set msg adfdr in iocb buff addr7080 STX ICBAH7090 * set up rest of iocb7100 LDX #1 set in buffer length7110 STX ICBLH assume 256 bytes max, or some more7120 DEX use reg X to set in iocb index for CIO7130 LDA #9 put msgg7140 STA ICCOM7150 NOP 7160 NOP 7170 * test if DUP is resident - if is then use indirect CIO routine7180 * to test break key abort7190 LDA DUPFLG if zero non-resident DUP not in memory7200 BEQ XCIO go direct to CIO & returqbRECDOS LSTb0 RECDOS1 LSTb?9RECDOS2 LSTbMxRECDOS3 LSTbURECDOS4 LSTbRRECDUP LSTBvDOS SYSBDUP SYSB<MAC65 COMBAUTORUN SYSn7210 JMP CHKD25 in memory, so use it, but be sure it's 2.5 version7220 *7230 * file header7240 *7250 SAVH .BYTE $FF,$FF7260 LDST .WORD 0 load address7270 LDND .WORD 0 end address7280 VECTR .WORD 0 run/init vector7290 *7300 .BrYTE $95,$20,$16 fossil filler bytes7310 *7320 ENDFMS ; end of FMS7330 * Used by 144 byte drive buffers & 128 byte sector buffers.7340 * Each active drive and each simultaneously open file needs7350 * a buffer. Without loading the DOS menu, tshere will be7360 * enough space. Using the menu limits the buffer space to7370 * the $3B0 bytes gap between ENDFMS and NDOS.7380 * With 1 drive, 6 open files are possible without affecting7390 * the DOS menu.7400 * 2 drives allow 5 open files7410 t* 3 drives allow 4 open files7420 * 4 drives allow 2 open files7430 * (a ramdisk needs a drive buffer as any other drive)7440 *= *+$03B07450 NDOS ; end of system buffers and minidup (DUP file equate)7460 *= *+120 parameter areau & type in line buffer for DUP7470 DBUF ; data buffer for copy7480 * length of non-resident portion of DUP7490 LEN = NMDUP-NDOSB07450 NDOS ; end of system buffers and minidup (DUP file equate)7460 *= *+120 parameter areaN@  )?HI Y0`HIJH) * J j * hJJJ )HJ h i      YS S0 i`ϣ߳ϣ߳H J3xj2h w1 |9 ӭ45(420 *(0241өX.`  R *i)Lvw  ~*PE 5 LN(G E  r s k rsrL ( E LO(0d( L iE0O +)$IC  H S8 q xp h   j 8no CDLQ CFl M  LO Ri)Llk2'")*F$F$F$F$F$ 5 )ШF/Șl]kpqС,LQ/A! Ti)Zlk@ ܬ/i)(")")k$F$yF$F 5$/L /lF@jj(LNkle$$%8(k()` R 8 ELO Ri)^>jf | NrC s  ) vw5g   enfo Glvw LQ@iLm>j FL ~Jjjjii p qEhjlrzs`LQ:$ȱ$@+[_#{ 8  Խut! ai 8   E I   ] C H h    ˰ 8  N   Lm E  ,  [ `LQ ,/ 8 ~/  Ơ? ѩ/  [ /{Lj0?MoLn FjMqLp NklLOLQnLoMlNLO R"(+ըHH`Q R!!  % !   / .   FȑF! /GF \H"+0+* ! F t|LQnm: J~nTF1F  *n+)5! n (, n)1JJJn(n*o I ,0  ci a oF? @ , 8,0 ʩ0H Eh   i  D ]D}mmFLQvtu`*&!*@h ] 0 ^0` c 0l$$%()()%*&J%H,@hH hH@,h $% 8i8$(%)0hhH ]h`() c 0H c 0 h`hhh&JJ ](~ll  LQ0  /qnoHH 9 9 H H  I9  9  Nd EH  Q8 o n  FnoL HII/ Ih8`h`Lnon`no`u F E VEhLO/luF l0BF/lɜɛ׽hE N  b VFL FREE SECTORS C H) *Fh ):FȽ F FC IH' 0 d  i:Fȩ/F.l`CD/08HDICIHȰ/F`ȱ$>.+.i ȱ$:刄H !A \ Hȱ$*?ȝ 2. ? [_{ ,0-:) 0$:>WI  IТ,LQH  0hLd ~ t u`C ?( 0(C.` E  R =! .ti S0N EE D XC )0')AY  )ע ? 0E088FG \on  (HhLcL3 iJ i Lqp 0=rspnqopqlk`jZj0  j FL`HFhȑFȽlFi0 h FFLFpvqwgneofLF pq7  G0i 0 FJJh1FqȱFpȱFk`B!08`hEE D 8. =D}tui( TʩL`b!)    cȌaȌd b`aabH8 hdaHcd8 cH hHH  \h hc` =Hh I8ih( t  ( t(!` L\CJfCJfCJfCDfC` a  HII  INdh  `h  `n)8jHniPoijIjFIjFIjh` a I 38  8H0 I  ' H LQ8j Y  8j NdY  &I &I &IHeH.pIiq  `!.莿 2Jjj }.m Ȉ!m FG` ɩLQ z  e Hi04 \ Ȍ  8 i h !`I0 `C Y8.`DOS SYS I  ` ~ݩ.C/`ba.m۩mѤC9 `C L] H  ,- '0 l , BLVDE`D1:AUTORUN.SYS8hhJ ȱHȱIȱBȱDȱEeeHHLV)  1*  ,,p-  0 I &  '0   Lw)l, 0  I&LD1:MEM.SAVE:D1:DUP.SYSJ)1CD1:DOS.SYS n  * \*`آ R'S )ɀ@  U))% BError loading MEM.SAV or memory!  0* b*c*d*e* R Hd*JSDd*J-=e* 0c*ʈд =}MYDOS 4.50 -- Copyright 1988,˛Disks 1D- 8R D: = D1: ~= =1-8.Dir of D1:-D8: *. Dir of D:A. Disk Directory K. Save MemoryB. Run Cartridge L. Load MemoryC. Copy File(s) M. Run at AddressD. Delete File(s) N. Load MEM.SAVE. Rename File(s) O. Change Config.F. Lock File(s) P. Set DensityG. Unlock File(s) Q. Make DirectoryH. Write DOS Files R. Pick DirectoryI. Initialize Disk S. Set RAMdisk #J. Duplicate Disk V. Set Verify Flag  ?莼( 0  =Select Item ( for menu):@  =ɛL)1L,*L,:W@ ,,L=No such item!L*, -L*, BNeed new file name! BNo drive or directories allowed in new name!Lock Unlock Delete Lock which file?â-#Unlock which file?ɢ-$((H @ AQ/wDelete what file?Ѣ-!((H @ ANJ =Answer 'Y' or 'N'h `B L?;(( ~=( ~= =? =Y ?Lj.H @ AhR ?R)L*,LM/L-Lz-File to rename, new name? @ A(9', ȱ:>0{ ПFull directory name?Z"L.Directory to be used as 'D:'? @ A(5)L.(I: ȱޝL*, BInvalid directory!L?( (0Li-File source, destination? '( @C۩2ڭ82ܭC B9'0 @(ߍeލd(DЍ( ? 9' A rBȱޙ':>Ȍ(C0J* .B :'ȱ/.* #,ɛȝ:' ߰ A L?,(0L*, 'ut(:'3?&' .'Ƚ:'?&'  .ى'Q?''(#( ~= =-->' ~=Q =YR_o (J(  0?B݌''BK)`''utz0( >(L0L*,L?nDisk to FORMAT: YA B(UTލ1 =(Press for Enhanced Dns)Type to Format Drive 2: =AIYZNj[R VL?L*,D1:DUP.SYSDrive to write DOS files to? YAH1:*K)2J) Z wB hpJ) 2<2UTC٩1ة۩کL;Source, Destination (Sectors)? YA)((9'( SA)((((( @(0% =Insert both disks, type = A( A((/( B(( BDrives not compatible!J(j(9'Hi''h(ɛy BInvalid options! @-&& @)׍&&(&&&۩ک&&&&8* <4&&&& <48*8(ܭ(ݥ2C, BNot enough memory! ک&&`(Mh  & =L?&i &&&&mm   =  &((&թԥԍ(Ս(((( ( ((C2((ՠԍ((,(0"( (( =m(m( & &("L*,  ( AL4,(, =Insert DESTINATION disk, press =Nͼ J) b( 0K) ?((ԭ(խ( ( (((L4Drive, new density: YA9'ɛ BDrive unchanged.(ު90٨Ȍ(SD  ABL)xԌҭHӭ@ @ ʎӆ@ӭ@@ :  $ӹ @hөԥX` Aˠ =RAM disk present? =NL#8 =xlon or E type RAMdisk? =Aό   L   M A, A6: ' =No extra memory available!L#8L7 & & & =Use default config for 0)ȩ ~= =K? =NL7 =Size(K)? ? @FjFjFjFj: =Page sequence? ? @o* =RAM disk drive no? = 09) `8 -8**H***) 9 Ȋ)h9 @@ʊ H'h(#''/'(ɛ ? @(@: 3 ʽ' L7 =Duplicated sequence number!L7 =Wrong number of entries!L7K큅쀄 =Verify WRITEs? ; =Number of File Buffers? ? @  6 Lw),R( ';L*,Drive number or : =ɛLC99L60Ȍ( =Remove drive? =Y =Is drive configurable? =YЂ =High capacity drive? =Yy =Is drive double sided? =Y ; =Tracks/side? ? @#0M P( ; =Step rate? =4/ ; ';L*, =Drive size (in sectors)? ? @H(h *;L*,RAM disk drive no? 8L*,Verify WRITEs? ;L*, =WNPy`(`(  LABSAVE:filename,start,end(,init(,run)) @TUH @Cp` 2< @؆8օڊ BInvalid START-END range!۩ @  @ hԄՠAμȌZ wB04*  0$ڍXۍY֍T׍U,0LBLB #CL?ֆ׌`Load MEM.SAV from what file? 0#L*,L?Load from what file?) @TU&̩Z wB &0&-&а&𨭼INIZ'RV0II BNO CARTRIDGE!Ԇ  )L?Run from what address? ?ɛ @ BAddress must be 1-4 hex digits! BHILV n=`hh =HH` =0{a Hɛ n= n=h` n=L*, = = pHH =hh`K: p `(((( i ɀ((L?(`(B'(0!HH''^>I^>(`^>DH(`(HI`(o5 ~= =( B( >@A (J wB0x((HHIIDDEE B ?(CɈK(٢A ~= =( BL>(B^>((ڤ ܝHݝI VL_>L?(" B !B J)  B(L& R XY( ?&:0H&((& ( .( & ( .(ʩ(`ލD&ߍEBIʎH( V0`ԩ ؠ@ȱ@ȱ)@ BError -- 163&`$8f 3AԄձG/ $<68i/(Ԧ`H&եԦ&&eԅheԅԊe(iL*@&&&&ԅL*@B ? 3A?*(ɛ:./2SX(0ȱ/.ɛ(ލ9'ި0#:Ȱ :ފ :ȱ: : CAD CAޥ`(eޅީe߅`(` @L\A @TUȪ: BFile name not allowed!: )  i( =0+L TUD BNot a disk file!(0` =Insert SOURCE disk, press  =,(pӮ(A(O  1B AB1B ` % 1(L/ b(de BJKO L?O` B((*(((`ȱޙ((:>Ȍ(`D:`OS.SYS,DOS.SYShh =L*,  VLJ C C,pLiLF#Խ٩Յ׆  LB` % 1(L/ b(de BJKO L?O` B((*(((`ȱޙ((:>Ȍ(`D:`OS.SYS,DOS.SYShh =L*,  VLJ<? } %`ee`L`8Ƹȥ`ȱi`Ȧ````8`ƶ`l8嶅`ȱ` M` Mȥ``EE`%%!`8(` Ƶ` Ƶ` % 0Ƶ` 0Ƶ` Ƶ` 0Ƶ`Ŷŵ(` FƵ` FƵ` % FƵ` FƵ` %*ff` %&`8嵅嶅`II` Lj ff`&&`!$ Ȃ8嵅嶅$8峅崅 @&&&8嵨嶐泅$p8峅崅Ld8居岅$㥴` L L`0Lee`ee`ȱl MLÀ MLɂ!v$Lw ix iy z w z !! :8`ȱ -0.:*ɂ`|ȱ A [|숭|L!ɂ {iʂi˂{ 0 ! 0{ɂL%  6ɂ M >LGچن߂! 6 M L섭܂ L 6 K L 6 K ʅ 6 M  6 K 6 K L&ą 6 K ʅ 6 M  6 K!  6ɂ M >L1ʅ 6 K! ʅ 6 M  6 K  6ɂ M >L1ͅ 6 K ʅ 6 M  6 K  6ɂ M >L1Ѕ 6 K ʅ 6 ؆ M  6 K Ӆ 6 K ۆ `! Lنچ چن 6 6 À LKنچ 6 `ENTER #LOAD #ASM ASM #,#,#,#DOSۆ䝇!"``!"ffLL}OSS MAC/65MACRO ASSEMB!LER 4.20 (c) 1982 Stephen D. Lawro.I.ELS.ENDI.MACR.END.TITLŠ.PAG.WOR.ERRO.BYT.SBYT.DBYT.EN.OP.TA.INCLUD .FLOA.CBYTŻ.LOCA.SE*.JSJMDEINLDLDSTSTCPCPBIBRCLCLCLCLDEDEININNOPHPHPLPLRTRT!SESESETATATSTXTXTYBCBCBEBMBNBPBVBVORANEOADSTLDCMSBASROLSRO% <>.DEƽ<><.O.AN.NOԡ.RE .REF.DEF.NOT .AND .OR ,X),,,ةNNOOBEREJECLISXREMLISCLISNUؐҐҐ!ɐҐ3''3ϐꐰ'ϐϐĐPKrrurSSTWT~x(æKJ3bǧrnhw ^~7*C25  榤 XʈHh(@`8x0Pp!Aa&Ff Ɍ! T :X  ,  C uLЋ - ۢ -Hȱ h L(EDIWHATTEXTMODũ5 L(Ҍ` HH`ɛ ۱Lɛ L^LH Ɛ ݟ !8 zH %h  c $p əLHL ݟ H %h @ ؐ`H h ٰ եԄL Q Ɉ򅗅 `  CȊ L0ߩ!` 04C L؍l !L؍L;8eHeHL H H`L0󆞥hhL;`ʆL; 0   L L; `!` 񒦞` ) %H$H`͒I9Ɛ Ɛ`L ĭs i ů8` @`` ۢB `хѦ򤟱")Q ȱ8e`8`LISԠNEבDE̘FINIJASSAVLOAENTEBLOABSAV!NUPRINRE΢REРSIZLOME͠BYŠCРDO TEX ۄ ذ ِЄL ۱$  @L8 @ @ @` ۄЩ Əe Ə  ZڰեLo800  8` ۹ɛg+< ۩, @`!0" `Ѫ$ɛ @$P `8`ɛ @`0 g8`0 45` ۄ, = @`8`U; =ZZZfZnnZ& /# 1D EFGJHIM!KL=>A Aλ߻A A @:=>@>>8?8679<;ޑ<<;C;?<;<>7;;<;<><;N;?>;!<<;<;;B<<>< 0 4 5 # 1u ô $%! 3" 2=_  W @=:q:ߌћݝOƞd6ޕÛipMM/,[]+-*/!&^"   ۱Ò ɛ;ė(` -!Є 5ɛș IX; @򹋻 @ɛ`旤;*,0ҪH  h`L ۄЄ  @)++D LT hh ` ۤЄѱ >  &𥐪 @ @񊨱Ɂȱ!Aх`? [``.8` i L@0:`󙋻ə<ȱɛ5)"ȱɛ&)"a{i 'ȱɛ`IȢ8ee͙̘ װL8u慓eeeee褚 !`8IȄ嚅8圕坕嚅馛褚`` . ݟ ȱ "Lsee`Lee`  g `8` ݟ !ȑ "L ,L ݟ "8堨0עL c S> a з` g S /    "Ll` L  Qڥ< g Qڠȱ)Ȅ汥 )   ! UX `Xd ĵB  ] Ķ m  ` 9;!  ݩLVԩ <0 ̎ H Nԅh ܗL'ՅԅՅօנ&uԕ JJJJ ϗ) ϗ(L' 0 `$  ꗥHJJJ!J h))`Lį`s8 քՊօ0ȱ8eԐհֱ֤֠H h`J (L ` ) ` ``͌ƵƵƶƶ`mi͝LH 0+ hȄ H Qڭim hLhH !hL˜ H  hH hɛ` SƮ` S  g LݟƐƐLݟ@  SƐ  SAR {Ɛ 00 N g 0ͥeLyԦH gh !g S) S N g$PI LƐ Įɛʆ N g䮐)`  Lai@( `ș`@  SE*JFH hG*I%L˚ SJ FH ޚh* S=Lܢ`8!qiHH hihi`H饦 ޚL  LEH h HLܢ WHVH`ajllvp)`8`LLܢ g.;* S  Q ؐ! gͭLv ] ]ҩ; S>+ 8!8吅膐 LWƐ ] 8 " ,p   "L`- ? Qک Q L(Y ɛL08҅8HŲ&eҪȹɛʈıh8宅汥豂Ʈ򅗅! -L^ BL& c 򈄲Ʊ洤́汤IJ ـ褳Ȅ` , g S?莁` S)e` m } m } mL= SB  JLH$ h L L g SN 匥 eLH L!H g Z ZL Z Ze樥e͙ ̘Ѧ o  碈  з` Z7 Z0 Z ZLF Z Z 9 ZL|L ȟ 8儅充 k  ӍLӷ ȟ ( ! 8慜煝 kLʼnň` š Š``  `ŝ Ŝ` ԥ ݟ $p L( N [б)ȩ Ȅe8Ш ˶ LQڥЯ ˶ L ޶Lԟ搠 ޶  ! L ř Ř ř Ř` "L` e` }  } g    š Ġ`Ʈ0ii`   g; L L L` g]; !X _ &  gD S; g+ S; ȟ g / ~ G P n !@ ^ L+ S<`& { з ޶ii  j H L(  G P:ӄ!7 X҄ۺ;hd~ ` <& S] ߭р SXILLy,PLޚ$0c ^ m )$0O J != ե m $01 , L۸$ 8 MLL θ)` Ƹ  Ĺ  -(`$0 ` L S i U8`0  "Ȅ<$0)Hh`H 8嬨孪8h g g!0  0 Lv" mHlH`+LD gLv)ㅪ) S?>  @Ɛ eɂ ɀ   g g g  Lv  (L9@ L 9L < S ` S! 9) - ܢLLܢ LФȥ LL ư  LܢLФ` L S ) Lܢ@𥆝i ܢ 0$0 `i ! e/ȑȥȥȄ g>;:=A /L*Ɛ HhȥȥȄiL⥥`L S  Ǭ搦ʩ`G!@` ܢ`Le H h g g gLv@L搩!l S @)8 <L S`L*) ܢ < ܢ S`8 E( Ǭ$0). ȥՑL) ȱՆL ) LHH hh!` էLܢ է Lܢ SA`/0 S)QP S) `    cLܢ Z Z Z Z`L $LHH ޚ hhLL$ 8`$p/+ߤėLѤė ՚! Ƹм ਩8 LШL۸ Ĺ  sƗƮ`_<+ 2ԅդ6e $Hՙ+ȥԙ+ȄhԅL83+`ų* {LdHH`+L8 L搥 Ɛԥ!ȥ`刾++`(Xȉ9܂e( S0' J搱`LS 1`ei` )ȱ` ` S@` 劤шܦ eȪHȱȱ)h`6`0!``Յԩ` ©eԅԘeՅ`8ԅԩՅ` ©8ԅԘՅ`օנ` © FfffԈ0?uؕԅՅ ©Ն &&&8થ׆Ԉ` ©%ՅՊ%ԅ`$p$0)  몥 Ն` 몥!)Iڤhh+Lshhզ uՆL8 ©ՅՊԅ` ©EՅՊEԅ` ©Ր` ><7 23 +)* ©! ©  LL    )!` ?i??[Z 07ee YzȱĘL8匝卝ei͙ ̘L8匑ȥ卑ȪȑȑȩȽ䯐`$P<@4!18匝!9卝808899莚(` Lӭ )H0 L )ёё hH  h$$0 ,P {`? ?ԩL*** ERROR -MEMORY FULBAD DEBRANCH RANGNOT Z PAGE/IMUNDEFINED LABEEXP TOO CO!MPLEDUP LABEO'FLO IF/ENDIF NESTIN VAL >25 IF/ENDIF STAC NESTED MACRO DE PHASE ERRO*= EXP UNDESYNTAX O'FLODUP MACRO NAMLINE # >6553MISSING .ENDNO *NUM/REN O'FLONESTED INCLUDLIST O'FLONOT SAVE FILLOAD TOO BINOT BINARY FIL!INVALID .SETOO MANY X-REFTOO MANY LOCAL FIELDUNDEFINED MACRMACRO NESTIN BAD PARAMETE!NOT F.P. NO DEV HANDLE҉TRUNCATED REÊTIMEOUԋNAːWRITE PROTECTEĒBAD DEV CMĠDRIVE TOO MANY OPEN FILEӢDISK FUL̥FILE NAMŧLOCKEĪFILE NOT FN(SEE MANU!AL$`݆   װLH`H H hh 鸩 R ƥ0C6ȐH J, h⩮^+ȱ8e;LLa L ͹0L` GA) 8!勢  * ɇ * *LɆɅɄ $p 6LN`ۺȄ@ J @[L 0 0 Ĺ `0עਈɛO(K֠)- Hȱh ץ8 0Lq JL >!L(@[` 0 0i~iنؠ0 >օנ֐ֈƮ ȱ֐+Į!䪱ؑHر֑hֈ֥ЦքׄИ}e`q䨊e`8包卅  0PH hšĠ答 $0! (,  J8  鸩 Ĺ Lqɇ'IimiLv  LvɆ LֳɅ LvɄ#Lv`` Z渦 6LN ) `Ԣ儐`Z!8圅坅 o   L8HI 8`LKȅ k L搥3 财 Qڠ Ÿh _ &Lܢ Lܢɛ򈱑 `濥ɀ`8!~H m~  h`$0 8 xIiH {h {L { {ȹ8 {9 {̚ȱ`& Ͷ LMLN= Ȋ ``l 搤搱` Ͷ 0`Lө ϶HI` `!H ҶhH hLJ*K+GHFH`H ƶhL `H ն  նhJ S)` 0`ɀ/ L˷)Lʎ JLڱ)⭆Ŧ  L(  `Ɉ"% ͶNL!M 0L4 ӷ 财@` 緥Ɉ` ն 0` նC` ӷΆ`~IHEDBKLV`ՆԈ gȱ80 LQՆ gФб$0 (` LH shHJJJJ ~h)L012345!6789ABCDEF s )LL mL殤 (` L0) ``) Lװ`͟?)4 Ƹ/HH L ^ hhԩ` է Ƹ ܢ J`L 鸭` { Ĺ  J }!L Ĺ۠ 8 XhLL` Ĺ  J }8厪 J"LPAGESYMBOL*** ASSEMBLY ERRORS: BYTES FRE ?=?%?=?ۺ;!!DOS DISK:** 1 }D8:D8:DUP.SYSD1:DUP.SYSD8:DUPC.SYSD1:DUPC.SYSD1:RAM/$/