#@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝL 3u }HHݠJ 3JLL %K 3J J H6K 3JJ HbK 3JL*}H}K #J JB,J DJE V䢠K #JlTULLRZLL[ V K 3Jl RTLUX+}Y V0HI L-L ؠK 3Jl TLUXY VrLILLL LLL8LL JLLL,}L LL iHiEh JXY V K 3Jl LLI R V }J(L Y-}JL YJ }J-IJL YJL YJGK 3J`D:MDOS.OBJD:MDUP.OBJE: 3JЭ)` lJ`0123456789ABCDEFHJJJJIJ .}lJh)IJ BHI V`hh lJLJHH` }J(L YJL YJ }J-L YJL YJ` }J)`  l /}ӳJKɠӠ 򠠠LOADING MDOS.OBJLOADING MDUP.OBJ0}EDMoving DOS/DUP into placePRESS TO INITIALIZE NEW DOSPRESS TO ENTER NEW DOS.Cannot open Object File1}Invalid Header in ObjectKL FileI/O Error, load abortedHSPRESS TO ENTER NEW DOS.Cannot open Object FileD MYDOS 4.51 Source Code Documentation L3} Copyright (C) 1988, 1989 by WORDMARK Systems and the authors: Charles L4}Marslett 2705 Pinewood Dr. Garland, TX 75042 L5} CIS: 73317,3662 UseNet: CHASM@KILLER.DALLAS.TX.US L6} and Robert Puff Suite 222 L7} 2117 Buffalo Rd. Rochester, NY 14624 L8} GEnie: BOB.PUFF This software may be freely used and distributed provided that this copyrigL9}ht notice is left intact, and provided that: (1) The source code in machine readable form is provided with L:} any binary distribution, or made available at no additional cost to the recipients of the binary distribution. L;} (2) A binary version of a derivative work may be sold for a reasonable distribution charge (less than $50), L<}and the source code in machine readable format must be available. (3) A derivative work may not impose anL=}d restriction on the free distribution of the source code. This is the source coL>}de to MYDOS version 4.51. It is written in Atari AMAC format. Use the included A65 assembler, Atari AMAC or the AL?}tari MADMAC programs to assemble it. If you do not want a listing, or do not have a printer, and you are assembling witL@}h A65, you can specify "-" as the listing file and only the object files will ge generated. If you want a listing yLA}ou will probably have to increase the "FILES" configuration parameter to 4 (so the included files can be read -- this LB} is the cause of the "I" errors). Here are a few notes on how to create a working copy of MYDOS from tLC}he source: (1) It is easiest to use an older version of MYDOS to assemble the new DOS. All filenames used inLD} assembling use the D: default drive number; so go to your DOS menu, and set the default drive (and directory) to wLE}here your source code resides. The source code and object files will all fit on one double density disk. If you only LF} have single density drive(s), then separate the MDOS and MDUP files, but put the object files on the same disk priorLG} to BUILDing. (2) Load A65 and enter D:MDOS.ASM as the source file. Press return for the object file and eitLH}her - or P: for the listing file. A65 will exit back to the MYDOS menu when the assembly is completed. (3) LLI}oad A65 and enter D:MDUP.ASM as the source file. This will assemble the rest of the resident code, and also the non-resLJ}ident DUP.SYS part. Again A65 will return to the MYDOS menu. (4) If necessary, copy the MDOS.OBJ and MDUP.OBLK}J files to a diskette containing BUILD. Now load (and execute) BUILD. This file will read the MDOS.OBJ and MDUP.OLL}BJ files you just created. When asked to, press START, and you will be in the new DOS! Now use the [H] command toLM} write out DOS files, and you're set! What the files contain: The MDOS.ASM and MDUP.ASM files areLN} "header" files, that have some equates, and simply INCLUDE the actual source files (source files are MDOS1.ASM, MDLO}OS2.ASM, MDOS3.ASM, MDOS4.ASM, MDUP1.ASM, MDUP2.ASM, MDUP3.ASM, MDUP4.ASM, MDUP5.ASM, MDUP6.ASM and MDUP3.ASM). Be LP}warned that there are absolute references that MDUP makes to the MDOS files; these are limited to locations in MDOS1.ASMLQ} so if the MDOS.ASM or MDOS1.ASM files are modified in any way, these references may need to be changed as well. TLR}hey are located in the very beginning of the MDUP.ASM file. The DOS.SYS file itself is contained mostly O}TITLE 'DOUBLE DENSITY MYDOS3 SYSTEM DISK BUILDER';; Copyright 1984, Charles Marslett, Wordmark Systems;; Permission isT} granted by the author for any use whatsoever of this; code, so long as this notice remains in the source code, and so; U} long as the source to this routine, however modified or unmodified,; is made available for a nominal cost.;;; SomeV} important absolute addresses;CIOV=$E456;CIO ENTRY VECTOR;MENUP=$02E0;THE RUN ENTRY POINT OF "MDUP.OBJ";ORIGIN=W}$4800;GOTTA BE BIG ENOUGH TO NOT HIT EITHER COPY OF MYDOS;ZCTR=$FA;A GENERAL PURPOSE COUNTERBPTR=$FC;A GENERAL PURPX}OSE POINTERZPTR=$FE;AND ANOTHER GENERAL PURPOSE POINTER;; Define the fields of IOCB $10 that I use;ORG$0351DS1Y}ICMDDS1DS1IBUFDS4ILENDS2IAUX1DS1IAUX2DS1;; The BUILD program itself -- loads MDOS.OBJ and MDUP.OBJ into meZ}mory above; itself, then relocates the code down over the previous version of MYDOS; that we are running with and start[}s it up. This is how we create a new; version of MYDOS.;ORGORIGIN;STARTLDX#LOW[SIGNON]LDY#HIGH[SIGNON];LOG ON\}TO THE SCREENJSRDMSG;LDA#$C0STABPTR+1;POINT BPTR AT $C000LDY#0STYBPTRLDA#$FFSTASAVCLDX#$10CLRCST]}A(BPTR),YINYBNECLRCINCBPTR+1DEXBNECLRC;LDA#HIGH[BUFFER]STABPTR+1;POINT BPTR AT "BUFFER"LDA#LOW[BUFF^}ER]STABPTRLDX#$20LDA#0MVLP1STA(BPTR),Y;FILL THE 8K BUFFER WITH $00 BYTESINYBNEMVLP1INCBPTR+1DEXBNEM_}VLP1;; COPY NEW DOS CODE FROM FILE "MDOS.OBJ";LDX#LOW[MSG01]LDY#HIGH[MSG01]JSRDMSG;ANNOUNCE WE ARE READING "D:M`}DOS.OBJ"LDY#LOW[DOSFIL]LDA#HIGH[DOSFIL]JSRLOADBF;LOAD CONTENTS OF "MDOS.OBJ";; COPY NEW DOS AND DUP CODE FROM FIa}LE "MDUP.OBJ";LDX#LOW[MSG02]LDY#HIGH[MSG02]JSRDMSG;ANNOUNCE WE ARE READING "D:MDUP.OBJ"LDY#LOW[DUPFIL]LDA#Hb}IGH[DUPFIL]JSRLOADBF;LOAD CONTENTS OF "MDUP.OBJ";; MOVE BUFFER DOWN TO LOW MEMORY;LDX#LOW[MSG03]LDY#HIGH[MSG03]c}JSRDMSG;ANNOUNCE WE ARE RELOCATING DOS AND DUP CODELDA#$07STAZPTR+1LDA#$00STAZPTR;SET DESTINATION POINTER d}TO $0700LDA#HIGH[BUFFER]STABPTR+1LDA#LOW[BUFFER]STABPTR;SET SOURCE POINTER TO "BUFFER";LDY#0MVLP2LDA(BPTe}R),YSTA(ZPTR),Y;COPY 256 BYTES AT A TIME UNTIL WEINY;ARE ABOUT TO OVERWRITE BUILD ITSELFBNEMVLP2;(THIS IS TOO Mf}UCH, I HOPE, BUT IT WORKS)INCBPTR+1INCZPTR+1LDAZPTR+1CMP#HIGH[START]BNEMVLP2;; REINITIALIZE THE SYSTEM;LDg}X#LOW[MSG04]LDY#HIGH[MSG04]JSRWFSTR;ANNOUNCE STARTUP AND WAIT FOR A KEY;JSRDOSINI;REINITIALIZE THE NEW MYDOS;h}LDX#0LDA#3STAICMD-16LDA#$2CSTAIAUX1-16LDA#LOW[EC]STAIBUF-16LDA#HIGH[EC]STAIBUF+1-16JSRCIOV;REi}OPEN THE KEYBOARD/SCREEN "E:" DEVICE;LDX#LOW[MSG05]LDY#HIGH[MSG05]JSRWFSTR;ANNOUNCE WE ARE READY TO RUN THE NEW Mj}YDOS;JMP(MENUP);ENTER BACK AT MENU (USE "H" TO SAVE NEW DOS);;; LOAD CONTENTS OF OBJECT FILE INTO BUFFER;LOADBFSTk}YIBUFSTAIBUF+1LDA#$FFSTAMINADSTAMINAD+1;SET LOW ADDRESS TO $FFFFLDA#3STAICMDLDA#4STAIAUX1LDA#0l}STAMAXAD;SET HIGH ADDRESS TO $0000STAMAXAD+1STAIAUX2LDX#$10JSRCIOV;OPEN D:MDOS.OBJ OR D:MDUP.OBJBPLGOTFIm}LLDX#LOW[NOFIL]LDY#HIGH[NOFIL]JSRDMSG;REPORT IT IF WE CANNOT OPEN THE FILEJMP($000A);GOTFILLDA#7;ELSE,Sn}TAICMD;CHANGE COMMAND TO READLDA#LOW[BUFAD]STAIBUFLDA#HIGH[BUFAD];BUFFER ADDRESS TO THAT OF LOCAL BUF.STAIBUFo}+1LDA#2STAILENLDA#0STAILEN+1;LENGTH TO 2 BYTESLDX#$10JSRCIOV;READ HEADERBMIINVHDR;IF ERROR, REPORTp} ITLDABUFADANDBUFAD+1CMP#$FF;ELSE, VALID HEADER?BPLRDNXTBINVHDRLDX#LOW[NOHDR]LDY#HIGH[NOHDR]JSRDMSG;q}IF NOT, REPORT THAT ERRORJMP($000A);RDNXTBLDA#LOW[BUFAD];READ THE NEXT WORD PAIR (START & END ADDR)STAIBUFLDA#Hr}IGH[BUFAD]STAIBUF+1LDA#4STAILEN;SET LENGTH TO 4 BYTESLDA#0STAILEN+1LDX#$10JSRCIOV;READ START/END ADDs}RESSESBPLRDDATA;IF NO ERROR, LOAD THE DATACPY#$88;ELSE, IS IT EOF?BNEABORT;IF NOT EOF, REPORT THE ERRORJMPMt}OVER;IF EOF, WE HAVE LOADED IT ALL, RETURN NORMALLY;RDDATALDABUFAD+2LDYBUFAD+3CPYMAXAD+1BCCNOTMAX;IF THIS BLu}OCK SETS A NEW HIGH ADDRESS LOADEDBNENEWMAXCMPMAXADBCCNOTMAXNEWMAXSTYMAXAD+1;UPDATE THE HIGH WATER MARKSTAMAv}XADNOTMAXSECSBCBUFADSTAZCTRTYASBCBUFAD+1STAZCTR+1INCZCTRBNELENOKINCZCTR+1LENOKJSRDEBUG1LDYBUFAw}D+1LDABUFADCPYMINAD+1;AND IF IT SETS A NEW LOW ADDRESS LOADEDBCCNEWMINBNENOTMINCMPMINADBCSNOTMIN;UPDATEx} THE LOW WATER MARKNEWMINCPY#$03BCCNOTMINSTYMINAD+1STAMINADNOTMINCPY#$07BCCDONTMVCPY#$C0;SKIP THE INDIy}RECT BUFFER AND MOVEBCSDONTMV;IF THE ADDR <0700 OR >BFFFADC#LOW[BUFFER-$700]PHATYAADC#HIGH[BUFFER-$700]TAYz}PLADONTMVSTABPTRSTYBPTR+1JSRDEBUG2LDA#0STAILENSTAILEN+1;READ ONE BYTE AT A TIMEGETNBLDX#$10JSRCIOV{}BPLSTBYTE;AND IF NO ERROR, STORE ITABORTLDX#LOW[ABORTED]LDY#HIGH[ABORTED]JSRDMSG;REAL I/O ERRORJMP($000A)|};EXIT TO DOS;STBYTELDYBPTRBNESTBY0LDYBPTR+1;TEST FOR BUFFER POINTER BEING STILL VALIDCPY#$C0BNESTBY0STAS}}AVCBEQSTBY3STBY0LDY#0STA(BPTR),Y;ALL OK, STORE THE BYTE JUST READSTBY3INCBPTRBNESTBT1INCBPTR+1STBT1LDAZ~}CTRBNESTBT2;INCREMENT THE MEMORY POINTERDECZCTR+1STBT2DECZCTRLDAZCTRORAZCTR+1;DECREMENT THE BYTE COUNTER}BNEGETNB;IF STILL IN THE BLOCK, READ THE NEXT BYTEJMPRDNXTB;ELSE, EXAMINE THE NEXT BLOCK;MOVERLDA#12;DONE WITH }THE LOAD,STAICMDLDX#$10JSRCIOV;CLOSE LOAD FILEJSRPSTRDB'(',0LDAMINAD+1JSRPHEX;REPORT THE LOW AND HIG}H WATER MARKSLDAMINADJSRPHEXJSRPSTRDB'-',0LDAMAXAD+1JSRPHEXLDAMAXADJSRPHEXLDX#LOW[LOADED]LDY#HI}GH[LOADED]JSRDMSGRTS;AND RETURN TO THE MAIN LINE CODE;;PROGRAM FILE (NEW FMS);DOSFILDB'D:MDOS.OBJ',$9B;;PRO}GRAM FILE (NEW UTILITY PROGRAM);DUPFILDB'D:MDUP.OBJ',$9B;;CONSOLE KEYBOARD/DISPLAY;ECDB'E:',$9B;; DISPLAY A MESS}AGE AND WAIT FOR "START";WFSTRJSRDMSG;NESTED CALL TO DISPLAY THE MESSAGELDA#8STA$D01FWFSTRTLDA$D01F;READ CON}SOLE SWITCHESAND#1BNEWFSTRT;WAIT UNTIL START IS DEPRESSEDRTS;; DISPLAY A MESSAGE TO THE OPERATOR;DMSGSTXZPTR}STYZPTR+1LDA#0STAZCTRMSGLPLDYZCTRLDA(ZPTR),YBEQDXITJSRBYTOUTINCZCTRBNEMSGLP;DXITRTS;CODEDB'0}123456789ABCDEF';; DISPLAY A 4 DIGIT HEX NUMBER ON THE SCREEN;PHEXPHALSRALSRALSRALSRATAXLDACODE,XJSR}BYTOUTPLAAND#$0FTAXLDACODE,X;BYTOUTLDX#11STXICMD-$10LDX#0STXILEN-$10STXILEN-$10+1JSRCIOVRTS;}PSTRPLASTAZPTRPLASTAZPTR+1PLOOPINCZPTRBNEPOUTINCZPTR+1POUTLDX#0LDA(ZPTR,X)BEQPEXITJSRBYTOUTJ}MPPLOOP;PEXITLDAZPTR+1PHALDAZPTRPHARTS;; REPORT THE HIGH AND LOW BUFFER LIMITS;DEBUG1JSRPSTRDB'(',0}LDABUFAD+1JSRPHEXLDABUFADJSRPHEXJSRPSTRDB'-',0LDABUFAD+3JSRPHEXLDABUFAD+2JSRPHEXRTS;DEBUG2JS}RPSTRDB')'DB$1E,$1E,$1E,$1E,$1EDB$1E,$1E,$1E,$1E,$1EDB$1E,0RTS;; ROUTINE TO REINITIALIZE DOS 2.0;DOSINIL}DA$704STA$00CLDA$704+1STA$00C+1JMP($00C);==REINITIALIZE ENTIRE DOS/DUP;; MESSAGES TO OPERATOR;SIGNONDC$}9B,$9B,' 'DC'M','Y','D','O','S','3',' ','d','o','u','b','l','e'DC' ','d','e','n','s','i','t','y'DC' ','A','T','A','}R','I',' ','O','S',' ',$9BDB' 'DC' ',' ',' ',' ',' ',' ','s','y','s','t','e','m'DC' ','d','i','s','k',' ','b','u','i}','l','d','e','r'DC' ',' ',' ',' ',' ',' ',' ',$9B,$9BDB0;MSG01DB'LOADING MDOS.OBJ',0MSG02DB'LOADING MDUP.OBJ',0}LOADEDDB$1E,$1E,$1E,$1E,$1EDB$1E,$1E,$1E,$1E,$1EDB$1E,$1E,$1E,$1E,$1EDB$1E,$1E,$1E,$1E,$1EDB$1E,$1E,'ED',$FE,$}9B,0MSG03DB'Moving DOS/DUP into place',$9B,0MSG04DB'PRESS 'DC'S','T','A','R','T'DB' TO INITIALIZE NEW DOS',$9B,0}MSG05DB'PRESS 'DC'S','T','A','R','T'DB' TO ENTER NEW DOS.',$9B,0;NOFILDB'Cannot open Object File',$9B,0NOHDRDB}'Invalid Header in Object File',$9B,0ABORTEDDB'I/O Error, load aborted',$9B,0;; BUFFER FOR PATCHING A RUNNING DOS;MAX}ADDS2MINADDS2SAVCDS1BUFADDS6;FOR ADDRESSESBUFFERDSSTART-$0700;; EXECUTION FORCED, LOAD RUN ADDRESS;;ORG$}02E0;DWSTART;run address;ENDSTARTR ADDRESSESBUFFERDSSTART-$0700;; EXECUTION FORCED, LOAD RUN ADDRESS;;ORG$+MYDOS 4.51 -- Released June 14, 1989MYDOS 4.51 restores some of the"features" of 4.3, including beingwritten in Atari AMA }C syntax (thatis, compatible with MADMAC and myown A65 assemblers). This seems moreconsistent than MAC/65. See thefollowi }ng list for the changedcode. Like 4.50, it mostly fixesbugs in features that never workedright in the past. the changes ar }every minor.Changes from 4.50 to 4.51 --1.Lock/Unlock work the way they used to. Query is the default.2.A bug inser }ted into the program load code is corrected (some code that has to be resident was moved into the DUP overlay area).3. }The code to work around I/O errors deleting the program file in most BASIC program "starter"s is re- inserted (inadvert }ently removed in 4.50).4.Formatting of disks with bad sec- tors is reenabled (with warning).5.Corrected code to copy DO }S.SYS from one diskette to another (this never really worked before).6.The RAMdisk configuration code in- serted by Bo }b Puff was retained, but the old code (with specifiable I/O port) is restored for non- Axlon, non-XE compatible RAMdisk }s.7.The correction to keep the VTOC of other disks from being corrupt- ed when I/O errors occurred while writing a VTO }C was worse than the problem (any I/O error scrambles all VTOCs with output files open). Perhaps the best fix is to ret }ry forever? Anyway, this is still a problem area.8.And, of course, the assembler A65 is included. The executable code } in MYDOS 4.51 was all assembled using A65.Copying DOS.SYS -- we now . . .1) load the 3 boot sectors into RAM from }the source disk.2) copy the actual file, renaming it "diamond"OS.SYS on the destina- tion disk.3) write the 3 boot se }ctors to the destination drive (updating the sector link mask, link location and sector size flag).4) rename "diamo }nd"OS.SYS to DOS.SYS (updating the sector size flag and the starting sector number of DOS.SYS).To do (before 1990 }, at least):1. Add script (batch file) support.2. Enable BASIC if no cartridge is installed and the [B] command is i }ssued. Then, disable BASIC if the [L] or [N] commands are issued.Any volunteers?Enjoy,Charles MarslettUsenet: }chasm@killer.dallas.tx.usCompuserve: 73317,3662June 16, 1989issued.Any volunteers?Enjoy,Charles MarslettUsenet: @ TITLE 'LARGE DISK FMS' ; ; Copyright 1984, Charles Marslett, Wordmark Systems ; ; Permission is granted by the author for }any use whatsoever of this ; code, so long as this notice remains in the source code, and so ; long as the source to th}is routine, however modified or unmodified, ; is made available for a nominal cost. ; LIST C,G,I ; ; DISK I/O EQUATES ; }DKADDR = $31 ;SIO ADDRESS OF FIRST DISK DRIVE (D1:) TODK = $80 ;STATUS BYTE FOR A DATA TRANSFER TO THE DISK FROMDK = $40 ;STA}TUS BYTE FOR A DATA TRANSFER FROM THE DISK ; READ = 'R' ;SIO COMMAND EQUATE FOR READING A DISK WRITE = 'P' ;SIO COMMAND EQUAT}E FOR WRITING A DISK RDSTAT = 'S' ;SIO COMMAND EQUATE FOR READING THE DRIVE STATUS WRITEV = 'W' ;SIO COMMAND EQUATE FOR WRITI}NG A DISK with VERIFY FMTCMD = '!' ;SIO COMMAND TO FORMAT A DISKETTE ; LK128 = 125 ;LOCATION OF 128 BYTE SECTOR LINK LK256 = }253 ;LOCATION OF 256 BYTE SECTOR LINK ; WARMST = $0008 DOSVEC = $000A DOSINI = $000C ; ORG $0020 ICHIDZ DS 1 ICDNOZ DS 1 ICC}OMZ DS 1 ICSTAZ DS 1 ICBALZ DS 1 ICBAHZ DS 1 ICPTLZ DS 2 ICBLLZ DS 1 ICBLHZ DS 1 ICAX1Z DS 1 ICAX2Z DS 1 DS 2 CURFCB DS 1 DA}TBYT DS 1 ; ORG $0031 CHKSUM DS 1 BUFR DS 2 ; ORG $0043 FMSZPG DS 2 DIRDSP = FMSZPG DIRSEC = FMSZPG+1 CURFNO DS 1 FMSBPT DS} 2 TMP1 DS 1 TMP2 DS 1 ; ; DEFINITIONS FOR THE ATARI ROM EXECUTIVE ; DSKTIM = $0246 RUNADR = $02E0 INIADR = $02E2 MEMTOP = $}02E7 DVSTAT = $02EA ; ; SIO COMMAND BUFFER DEFINITION ; ORG $0300 DDEVIC DS 1 DUNIT DS 1 DCOMND DS 1 DSTATS DS 1 DBUFLO DS }1 DBUFHI DS 1 DTIMLO DS 2 DBYTLO DS 1 DBYTHI DS 1 DAUX1 DS 1 DAUX2 DS 1 ; ; I/O SYSTEM DEFINITIONS ; HATABS = $031A ;BASE O}F THE DYNAMIC HANDLER TABLE ; ; CIO COMMAND TABLE BASE DEFINITIONS (FOR IOCB $00) ; ORG $0340 ICHID DS 1 ICDNO DS 1 ICCOM D}S 1 ICSTA DS 1 ICBAL DS 1 ICBAH DS 1 ICPTL DS 1 ICPTH DS 1 ICBLL DS 1 ICBLH DS 1 ICAX1 DS 1 ICAX2 DS 1 ICSPR DS 4 ; ; CARTRI}DGE SUBSYSTEM DEFINITIONS ; CARINIT = $BFFE ;LOCATION OF INIT VECTOR CARTEST = $BFFC ;LOCATION OF FLAGS CARRUN = $BFFA ;LO}CATION OF RUN VECTOR ; ; 800XL MAP CONTROL ; MAPREG = $D301 ; ; OTHER I/O PORT DEFINITIONS ; NMIEN = $D40E ; ; ROM VECTORS} ; DSKINV = $E453 ;SINGLE DENSITY DISK I/O ENTRY POINT SIOV = $E459 ;SERIAL I/O O.S. ENTRY POINT ; INCLUDE D:MDOS1.ASM ;DA}TA AND CODE THAT REMAINS FIXED ; INCLUDE D:MDOS2.ASM ;FILE SYSTEM FUNCTIONS ; INCLUDE D:MDOS3.ASM ;INTERNAL DISK I/O ROUTIN}ES ; INCLUDE D:MDOS4.ASM ;UTILITY SUBROUTINES ; BOOTND END ;START DUP HERE! INCLUDE D:MDOS3.ASM ;INTERNAL DISK I/O ROUTINO;================================================= ;= MYDOS BOOT CODE == ;================================================}= ; ; DISK BOOT SECTORS (3) ; ORG $0700 ;DOS.BOOT LOADS AT 0700 BOOTFL DB 'M' ;INDICATE MYDOS 4.5 OR LATER BOOTL DB 3 ;NUMBE}R OF SECTORS IN THE BOOT BOOTAD DW BOOTFL ;ADDRESS OF BOOT CODE IN RAM BOOTIN DW INIT JMP INBOOT ;JUMP TO THE BOOT CONTINUAT}ION FILES DB 3 ;NUMBER OF FILES THAT MAY BE OPEN AT ONCE ;DRIVES = * ;USED TO BE BIT PATTERN FOR DRIVES RAMDKU DB $09 ;RAM DI}SK UNIT # ;BUFALC = * ;USED TO BE BUF. ALLOC. DIR. DEFAULT DB 1 ;DEFAULT UNIT NUMBER DOSEND DW BOOTND ;ADDRESS OF THE FIRST B}YTE OF FREE MEM. SECDAT DB 1 ;1=128 BYTE SECTOR/2=256 BYTE SECTOR DOSLOC DW 4 ;SECTOR ADDRESS OF DOS.SYS DLINK DB LK128 ;OFFS}ET TO THE SECTOR LINK FIELD DOSAD DW BASE ;ADDRESS TO LOAD DOS.SYS INTO ; INBOOT LDY DOSAD ;SET UP START OF DOS AS BUFFER ADD}RESS LDA DOSAD+1 JSR BTSET ;LOW ADDR IN Y, HIGH IN A ; LDA DOSLOC+1 LDY DOSLOC ;PUT DOS DISK ADDRESS INTO (A,Y) ; ; DOS.S}YS INPUT LOOP ; INITLP CLC ;CLEAR CY, 'DO A READ' LDX SECDAT ;GET CODE FOR SECTOR SIZE BEQ NODOS ;IF ZERO, NO DOS ON DISK!} JSR DKIO ;INVOKE DISK I/O ROUTINE BMI NODOS ;IF AN ERROR, RETURN NO-DOS ERROR LDY DLINK ;POINT TO LINK LDA (FMSZPG),Y ;C}HECK FOR NEXT LINK (10-BITS) ANDCD AND #$03 ;BEING ZERO, PHA ;SAVE UPPER BYTE OF ADDRESS INY ORA (FMSZPG),Y ;IF SO, LOADI}NG IS COMPLETE BEQ BOOTXT LDA (FMSZPG),Y ;ELSE, IT'S THE ADDRESS OF NEXT SECTOR PHA ;SAVE LOWER BYTE ON STACK JSR MVBUFR} ;THEN ADJUST THE BUFFER POINTER IN DCB PLA TAY ;RESTORE LOWER BYTE TO Y-REG PLA ;RECOVER UPPER BYTE OF DISK ADDRESS BC}C INITLP ;AND CONTINUE LOADING ; NODOS LDA #$C0 ;NO BOOT PROGRAM ERROR CODE DB $A0 ;SKIP SINGLE BYTE (LDY #) ; BOOTXT PLA DO}SXIT ASL A ;SET CARRY, CONVER CODE TO FINAL VALUE TAY ;PUT CODE INTO Y-REG RTS ;AND EXIT ; ; MOVE BUFFER POINTERS TO NEXT} AREA TO BE LOADED ; MVBUFR LDA DLINK CLC ADC FMSZPG ;ADD DLINK TO THE CURRENT BUFFER ADDRESS TAY ;LOW BYTE TO Y-REG LDA} FMSZPG+1 ADC #0 BTSET STY FMSZPG STA FMSZPG+1 BUFSET STY DBUFLO ;STORE LOW BYTE INTO DCB STA DBUFHI ;THEN UPPER BYTE RTS} ; ; PERFORM DISK READ(CY=0) OR WRITE (CY=1) ; DKIO STA DAUX2 ;STORE UPPER BYTE OF SECTOR ADDRESS STY DAUX1 ;THEN LOWER BYTE} DKIO2 LDY #3 LDA #READ BCC SETRTY ;IF CY=0, READ INTO RAM LDA WRCMDB ; SETRTY STY TMP1 ;SET NUMBER OF TRIES DKFME STA DCO}MND CLC LDA #WRITEV ;CLC AND CONSTANT FOR POKERS WRCMDB = *-1 STY DTIMLO LDA #128 ;ASSUME A 128-BYTE SECTOR SIZE DEX BE}Q STBUFL LDX DAUX2 ;SECTOR > 256? BNE SET256 LDX DAUX1 CPX #4 ;SECTOR > 3 BCC STBUFL ;IF NOT SET256 ASL A ;MAKE A 256 BY}TE SECTOR SIZE STBUFL STA DBYTLO ROL A STA DBYTHI LDY #DKADDR ;PUT DISK DEVICE CODE INTO DCB STY DDEVIC IORTRY DEC TMP1 }BMI DIOXIT LDX DCOMND INX TXA LDX #FROMDK ;ASSUME DATA ==> DISK AND #$06 BNE ISREAD ;IF NOT X0,X7,X8 OR XF, OK LDX #TO}DK ;ELSE, DATA ==> DISK ISREAD STX DSTATS ;RESTORE STATUS TO DCB JSR SIOV ;DO THE I/O OPERATIONS DEY BMI IORTRY ;IF NOT OK}, RETRY ; DIOXIT LDX CURFCB ;ELSE, LOAD FCB OFFSET AND STATUS INY TYA RTS ; ; FIXED RAM DEFINITIONS IN BOOT SECTORS ; DIUN}IT DS 1 ;UNIT NO. OF CURRENT DIRECTORY CDIREC DS 2 ;SECTOR NO. OF CURRENT DIRECTORY HOLFN DS 1 STATE DB $70 ;DUP loaded, MEM.}SAV inactive, Warmstart ; bit 7 -- MEM.SAV in use ; bit 6 -- DUP.SYS loaded ; bit 5 -- AUTORUN.SYS already run } ; bit 4 -- Initial BUILD active ; STKPSV DS 1 ;SAVED STACK POINTER ORG $07C0 ;MUST MATCH DUP LOCATION ; TRACKS DB 35,40},80,77 ;TRACKS IN EACH DISK FORMAT ; SECSIZ DB 0,0,0,0 ;BUFFER SIZE TABLE DB 0,0,0,0 ; DRVDEF DB $52,$52 ;DRIVE CONFIGURATI}ON TABLE: DB $D2,$D2 ;BIT 7=1 => NO DRIVE DB $D2,$D2 ;BIT 6=1 => ATARI 810 DRIVE DB $D2,$D2 ;BIT 5-4 IS (0=35, 1=40, ; } 2=80, 3=77 TRACKS(8") ;BIT 3=1 => DOUBLE DENSITY ;BIT 2-1 IS DRIVE STEP RATE ;BIT 0=1 => DOUBLE SIDED ; ; DOS.SYS }PROGRAM FOLLOWS ; DKEPT DW DKOPEN-1 DW DKCLOS-1 DW DKREAD-1 DW DKWRIT-1 DW DKSTAT-1 DW DKXIO-1 ; ORG $07E0 ; ; IDENTIFY} DRIVE TYPES ; INIT LDA #LOW[361] STA CDIREC LDA #HIGH[361] STA CDIREC+1 ; ; IDENTIFY DRIVE TYPES ; LDX #8 IDRVLP STX DU}NIT JSR ZERDVS ;ASSUME THE DRIVE IS NOT PRESENT LDA DRVDEF-1,X BMI NXTDRV ;IF NOT DECLARED, WE ARE DONE ; JSR JSTRD ;E}LSE, READ ITS STATUS BEQ NXTDRV ;IF ABSENT, GO ON TO THE NEXT ONE LDY #9 WOTCPY LDA WOTDCB,Y STA DDEVIC+2,Y DEY BPL WOT}CPY LDA DRVDEF-1,X CMP #$40 BCS NXTDRV ;IF NOT CONFIGURABLE, CONTINUE LDY SECSIZ-1,X JSR SETDRV ;TELL IT ABOUT MY CONF}IGURATION ; NXTDRV DEX ;STEP TO NEXT DRIVE NUMBER BNE IDRVLP ;IF MORE, LOOK AT THEM ; ; ZERO INITIALIZED MEMORY ; LDY #M}APBUF+7-CHGMAP TXA ;NOTE X=0 HERE ZERLP1 STA CHGMAP-1,Y DEY BNE ZERLP1 INC MAP2MOD ; ; DEFINE TOP OF FMS FOR USER PROGRA}M ; LDA DOSEND STA MEMTOP LDY DOSEND+1 ; ; ALLOCATE FILE SECTOR BUFFERS ; LDX #15 ;MAX OF 16 SECTOR BUFFERS DKBFLP CPX F}ILES ;EMPTY BUFFERS DONE? BCC ALCBUF DEC BUFFLG,X BMI DKBFSQ ALCBUF TYA STA SBTABU,X INY DKBFSQ DEX ;BUMP BUFFER COUN}TER BPL DKBFLP ;IF NOT CONTINUE LOOPING STY MEMTOP+1 ;DEFINE TOP OF MEMORY USED ; ; SET UP HANDLER VECTOR ; FNDHND INX IN}X INX LDA HATABS-2,X ;END OF THE HANDLER TABLE? BEQ NOHAND ;THEN INSTALL IT HERE CMP #$44 ;A 'D' ALREADY PRESENT? BNE }FNDHND ;NO, CONTINUE LOOKING, ELSE OVERWRITE IT ; NOHAND LDA #$44 ;WRITE AT END OF TABLE OR CURRENT "D" ENTRY STA HATABS-2},X LDA #LOW[DKEPT] ;STASH MYDOS ENTRY VECTOR STA HATABS-1,X LDA #HIGH[DKEPT] STA HATABS,X ;BUILD HANDLER VECTOR JMP DUPI}NV ;DONE, INITIALIZE DUP [overwritten by MDUP] ; ; DOS NON-ZERO PAGE RAM ALLOCATIONS ; CHGMAP DS 1 CURMAP DS 1 MAP2 DS 1 MAP}2MOD DS 1 LSTSEC DS 2 LSTIOCB DS 1 ; ; MYDOS FCB STRUCTURE (ALMOST THE SAME AS ATARI DOS 2.0) ; FCBFNO DS 1 FCBOTC DS 1 ;OPE}N TYPE CODE FCBFLG DS 1 MAXLEN DS 1 CURLEN DS 1 BUFNO DS 1 CURSEC DS 2 LNKSEC DS 2 SECCNT DS 2 DIRBAS DS 2 ;BASE ADDRESS OF C}UR. SECTOR SAVSEC DS 2 FCBLEN = 16 DS 7*FCBLEN ;SPACE FOR THE REMAINING 7 IOCBs ; BUFFLG DS 16 ;IF 0, BUFFER NOT IN USE SBTA}BU DS 16 ;UPPER BYTE OF THE SECTOR BUFFER ADDRESS MAPBUF DS 512 ;SPACE ALLOCATED FOR VTOC DIRBUF = MAPBUF ;SPACE ALLOCATED TO} READ DIRECTORIES FNAME DS 12 CURMP DS 1 ; BASE = * HDTAB DW 0,0,0,0 ;8 LOGICAL HARD DRIVES OF DW 0,0,0,0 ;UP TO 65535 SECTO}RS EACH ; ; ;NOTE: this table is referenced by DUP.SYS, and should not be moved! ; ; DOS CONFIGURATION CODE ; ; CONTROL BLOCK} TO BE WRITTEN TO A DRIVE TO CONFIGURE IT ; WOTDCB DB $4E,$40 DW DIRBUF,1 DW 12,4 ; ; THE CONFIGURATION CODE, FORCES A DRI}VE INTO THE APPROPRIATE CONFIGURATION ; SETDRV AND #$3F ;EXTRACT CONF. BITS STA TMP1 STY TMP2 JSR SIOV ;READ CURRENT CON}FIGURATION BMI JSTRD LDA TMP1 LDY TMP2 LSR A PHA ;SAVE REMAINING BITS AND #3 ;EXTRACT STEP RATE CODE STA DIRBUF+1 }LDA #0 STA DIRBUF+2 ROL A STA DIRBUF+4 ;STORE DOUBLE SIDED FLAG TYA ;GET DENSITY LSR A STA DIRBUF+6 ;STORE UPPER BYTE} OF SECTOR SIZE ROR A STA DIRBUF+7 ;THEN LOWER BYTE ROL A ASL A ASL A STA DIRBUF+5 PLA LSR A LSR A LSR A ;POSITION} TRACK COUNT FIELD TAY LDA TRACKS,Y ;GET NUMBER OF TRACKS STA DIRBUF AND #$04 ;SEE IF 77 TRACK 8 IN. PHA LSR A ORA DI}RBUF+5 ;MERGE D/DENSITY WITH 8 IN. FLAG STA DIRBUF+5 PLA ASL A ;CONVERT TO 0 OR 8 ADC #18 ;SECTOR COUNT = 18 OR 26 STA} DIRBUF+3 LDY DUNIT LDA HDTAB-1+8,Y BEQ TOSIOV STA DIRBUF+2 ;SIZE = SECTORS/TK LDA HDTAB-1,Y STA DIRBUF+3 ;LOW BYTE OF }SIZE LDA #1 STA DIRBUF ;ONE TRACK/DRIVE TOSIOV INC DCOMND ;CHANGE COMMAND TO WRITE LDA #$80 STA DSTATS ;SET DIRECTION }-> DISK JSR SIOV ;WRITE OPTION TABLE TO DRIVE ; JSTRD LDA #RDSTAT STA DCOMND JSR DSKINV LDX DUNIT TYA BMI ZERDVS LDA }DVSTAT ASL A ;SECTOR SIZE=256? ASL A ASL A LDA #1 ADC #0 SETSIZ STA SECSIZ-1,X RTS ; ZERDVS LDA #0 BEQ SETSIZ ;ALWAY}S BRANCHES! ; ; DOS RAMDISK CODE (moved here starting with version 4.5) ; ; RAM DISK I/O HANDLER (POS. IND. CODE) ; MAPAGE D}B $E3,$E7,$EB,$EF DB $83,$87,$8B,$8F DB $C3,$C7,$CB,$CF DB $A3,$A7,$AB,$AF ; DB $93,$97,$9B,$9F DB $D3,$D7,$DB,$DF DB $}B3,$B7,$BB,$BF DB $F3,$F7,$FB,$FF ; DB $E3,$E7,$EB,$EF DB $83,$87,$8B,$8F DB $C3,$C7,$CB,$CF DB $A3,$A7,$AB,$AF ; DB $9}3,$97,$9B,$9F DB $D3,$D7,$DB,$DF DB $B3,$B7,$BB,$BF DB $F3,$F7,$FB,$FF ; VALSEC PHA TYA ORA #$80 LSR A STA BUFR+1 SEI} ;DISABLE INT-S LDA #0 STA NMIEN ;DISABLE NMI-S ROR A STA BUFR PLA TAY LDA MAPREG ORA #$1C STA CHKSUM ORA #$7C AN}D MAPAGE,Y STA MAPREG ;SELECT RAMDISK DATA PAGE ; LDA DBUFLO ;USER BUFFER ADDRESS GOES HERE STA BUFR+2 LDA DBUFLO+1 STA }BUFR+3 LDY #0 PLP BCC RREADL ;CY=0 IF READ RWRITL LDA (BUFR+2),Y STA (BUFR),Y INY BPL RWRITL BMI RIOX ; RDKIO STY DAUX}1 ;*** FOR FORMAT CODE *** CPY #$80 ROL A CMP #4 RDKLMT = *-1 ;NUMBER OF 16K PAGES IN RAMDISK BCC VALSEC ;CALCULATE MEM. }ADDR. PLP LDA #139 BMI RERROR ; RREADL LDA (BUFR),Y STA (BUFR+2),Y INY BPL RREADL ; RIOX LDA CHKSUM ;FORCE REAL RAM PAG}E STA MAPREG ;BEFORE EXITING LDA #$C0 STA NMIEN ;RE-ENABLE NMI CLI ;ENABLE INTERRUPTS LDA #1 ;RETURN '1' IN Y-REG RERRO}R STA DSTATS ;AND IN STATUS BYTE LDX CURFCB ;RESTORE FCB ADDR TAY RTS ;THEN EXIT ; STEPBP LDA DBUFLO EOR #$80 STA DBUFL}O BMI TSTEOD INC DBUFHI ; TSTEOD LDY DAUX1 RTS ORE FCB ADDR TAY RTS ;THEN EXIT ; STEPBP LDA DBUFLO EOR #$80 STA DBUFL2; ; DISK OPEN ROUTINE ; DKOPEN JSR WBITMP ;Fix nasty bug! [Bob Puff] JSR SETUP ;SET UP BUF PTRS, ETC. JSR GETFNM ;GET D }RIVE ID OR FILE NAME FROM BUFFER LDA ICAX1Z ;GET TYPE OF OPEN FROM IOCB STA FCBOTC,X AND #$02 ;TEST DIRECTORY READ FLAG  } BEQ DKOPN1 JMP LSTDIR ;IF SET, GO HANDLE DIRECTORY FORMATTING ; DKOPN1 STA SAVSEC,X STA SAVSEC+1,X ;CLEAR SAVSEC JSR SFD }IR PHP ;SAVE STATUS RETURNED BCS OPNEW LDA #$10 ;MAKE SURE THIS IS NOT A DIRECTORY JSR GETFLAG BNE DIROPN ;IF A DIRE }CTORY, GO HANDLE IT SEPERATELY OPNEW LDY ICAX1Z CPY #8 BEQ OPNOP ;IF OPEN FOR OUTPUT CPY #4 BEQ OPNIN ;IF OPEN FOR INPU }T CPY #12 BEQ OPNUP ;IF OPEN FOR READ/WRITE (UPDATE) CPY #9 BEQ OPNAP ;IF OPEN FOR OUTPUT/APPENDED DIROPN JMP ERRCMD ;}IF NONE OF THE ABOVE, IT IS AN ERROR! ; OPNAP PLP ;OPEN APPEND BCS OPNCR0 JSR TSTLOK JSR INITYP ;READ ALL THE SECTORS IN }THE FILE LDA DIRBUF+1,Y STA SECCNT,X LDA DIRBUF+2,Y STA SECCNT+1,X APPRD JSR RDNXTS BCC APPRD ;IF NOT EOF, READ ANOTHER } LDA MAXLEN,X JSR LENSET ;SET LENGTHS FOR OUTPUT LDA SECCNT,X BNE SGLDEC DEC SECCNT+1,X SGLDEC DEC SECCNT,X ;ALLOW FOR SE}CTOR REWRITTEN JMP OPOUTX ; OPNUP PLP ;OPEN UPDATE (OUTPUT) BCS OPNER1 JSR TSTLOK OPNOWR JSR INSTRT JMP DONE ; OPNIN PLP} ;OPEN INPUT BCC OPNOWR OPNER1 LDA #170 ;FILE NOT FOUND BMI EROXIT ; OPNOP PLP ;OPEN (NORMAL) OUTPUT BCS OPNCR JSR REMO}VE JMP GET1ST ; OPNCR0 DEC FCBOTC,X OPNCR LDA HOLFN STA CURFNO BMI OPDIRF GET1ST JSR ALLOC ; LDA ICAX2Z ;IF OUTPUT, TYPE }OF FILE AND #$24 ;SAVE LOCKED & FORMAT BITS (with 4.5, DOS I no-more) EOR #$43 ;MERGE IN DEFAULT CODE (DOS II, UNLOCKED) L}DY MAPBUF ;WHICH TYPE DISK? CPY #3 ;IF >2 THEN MYDOS BCC LLINKS ORA #$04 ; LLINKS PHA JSR RDCFNO ;SELECT PROPER SECTOR IN} DIRECTORY SEC JSR ENTNAME ;ENTER NAME INTO IT LDA LNKSEC+1,X STA DIRBUF+4,Y LDA LNKSEC,X STA DIRBUF+3,Y PLA JSR SAV}FLAG JSR INITYP JSR TONXT OPOUTX LDA #$80 STA FCBFLG,X JSR TSTDOS ;FILE NAME = DOS.SYS? BNE JDONE LDY CURSEC,X LDA CU}RSEC+1,X JSR SETDOS ;IF SO, UPDATE BOOT SECTORS ; LDA DOSAD STA FMSZPG LDA DOSAD+1 STA FMSZPG+1 BNE OWTDOS ;NOTE: DOS} CANNOT START ON ZERO-PAGE ; OPDIRF LDA #169 EROXIT JMP AEXIT ; LWTDOS JSR WRNXTS ;AUTOMATICALLY WRITE DOS.SYS OUT OWTDOS LD}Y #0 ;IF WE OPEN "DOS.SYS" FOR A WRITE CDOSBF LDA (FMSZPG),Y ;(THIS IS BECAUSE DOS 2.0 WOULD BLOW STA (FMSBPT),Y ; ITSELF A}WAY IF A REAL WRITE FROM THE INY ; DOS AREA WAS ATTEMPTED, AND WE HAVE CPY DLINK ; TO REMAIN COMPATIBLE). BCC CDOSBF T}YA STA CURLEN,X JSR MVBUFR CPY DOSEND SBC DOSEND+1 BCC LWTDOS JDONE JMP DONE ; ; READ DATA FROM A FILE ; DKREAD JSR SETU}P ;SETUP BUFFER POINTERS, ETC. LDA FCBOTC,X AND #$02 ;TEST THE DIRECTORY I/O FLAG BEQ RDFILE JMP DIRRD ;JUMP IF THE SP}ECIAL CASE OF A DIRECTORY READ ; RDFILE LDA CURLEN,X CMP MAXLEN,X BCC RDSGBT ;IF NOT AT SECTOR BOUND., READ A BYTE AT A TI}ME BCS RDASNT ;ELSE, CHECK FOR READ MODE AND BUFFER SIZE ; RDASLP LDA ICCOMZ AND #$02 BEQ RDSGBT ;IF NOT BINARY I/O READ } A BYTE AT A TIME LDY DLINK DEY RDSCLP LDA (FMSBPT),Y ;SIMULATED BURST I/O (with unrolled loop) STA (ICBALZ),Y DEY LDA (!}FMSBPT),Y STA (ICBALZ),Y DEY LDA (FMSBPT),Y STA (ICBALZ),Y DEY LDA (FMSBPT),Y STA (ICBALZ),Y DEY BNE RDSCLP LDA (FM"}SBPT),Y ;NUM OF DATA BYTES IS MULTIPLE OF 4 + 1 STA (ICBALZ),Y JSR BUFADJ ;ADJUST BUFFER PTR BY 125 OR 253 RDASNT JSR RDNX#}TS ;READ IN THE NEXT SECTOR BCS RETEOF ;REPORT EOF/ERROR IF NECESSARY LDA ICBLLZ+1 BNE RDASLP ;AND REPEAT THE LOOP IF >$} 256 BYTES LEFT ; RDSGBT TAY LDA (FMSBPT),Y ;FETCH A DATA BYTE FROM THE BUFFER STA DATBYT ;AND RETURN IT TO CIO INY TYA %} STA CURLEN,X ;BUMP CURRENT BUFFER LENGTH EOR MAXLEN,X ORA LNKSEC,X ORA LNKSEC+1,X ;TEST FOR THE LAST BYTE OF THE FILE BN&}E JDONE LDA #3 ;IF IT IS, REPORT THIS IS THE LAST BYTE DB $2C ; RETEOF LDA #136 ;RETURN END OF FILE STATUS JMP AEXIT ; ;'} WRITE DATA TO A FILE ; DKWRIT STA DATBYT ;SAVE THE DATA BYTE (IF IT IS IN ACC) LDY ICDNO,X STY ICDNOZ ;INSURE ICDNOZ IS (}SET UP (BASIC DOES NOT!) JSR SETUPW LDA FCBOTC,X AND #$08 BEQ CANTWR ;ERROR OUT IF ILLEGAL TO WRITE (BASIC AGAIN!) LDA )}CURLEN,X TAY CMP MAXLEN,X BCC SKBURST ;SKIP AROUND IF NOT THE END OF THE SECTOR WRASLP JSR WRNXTS ;WRITE A SECTOR OF DA*}TA BCS RETEOF ;ERROR OUT IF NO MORE DISK SPACE LDY STKPSV LDA $0102,Y CMP #$C0 ;IF FROM BASIC (RETURN ADDRESS < $C000) +} BCC BASWRT ;PASS SINGLE BYTES LDA FCBOTC,X ;Fix bug in open/update vs. burst I/O AND #$04 ;[Bob Puff, again!] BNE BASWR,}T LDA ICCOMZ ;IF RECORD I/O, PASS SINGLE BYTES ALSO AND #$02 BEQ BASWRT LDY ICBLLZ+1 ;AND IF THE BUFFER HOLDS FEWER THAN-} 256 BYTES BEQ BASWRT ;PASS SINGLE BYTES AS WELL LDY MAXLEN,X DEY WRSCLP LDA (ICBALZ),Y ;ELSE, DO SIMULATED BURST I/O ST.}A (FMSBPT),Y DEY LDA (ICBALZ),Y STA (FMSBPT),Y ;BUT ONLY UNROLL 2 ENTRIES FOR WRITES! DEY ;(WE GOT VERY LITTLE RAM TO W/}ASTE!) BNE WRSCLP LDA (ICBALZ),Y STA (FMSBPT),Y JSR BUFADJ LDA (ICBALZ),Y STA DATBYT JMP WRASLP ; BASWRT LDY #0 SKBURS0}T LDA DATBYT INC CURLEN,X STA (FMSBPT),Y LDA #$40 ORA FCBFLG,X ;FOR UPDATE MODE, SAY THE SECTOR WAS MODIFIED STA FCBFLG,1}X BNE TODONE ;BRANCH ALWAYS! ; CANTWR JMP ERRCMD ; BUFADJ CLC LDA MAXLEN,X STA CURLEN,X ADC ICBALZ STA ICBALZ BCC RBAO2}K INC ICBALZ+1 RBAOK SEC LDA ICBLLZ SBC MAXLEN,X STA ICBLLZ BCS RBLOK DEC ICBLLZ+1 RBLOK RTS ; ; RETURN FILE STATUS ; D3}KSTAT JSR SETUP ;SET UP RETURN ADDRESS, ETC. JSR LFFILE ;FIND IF FILE IS THERE, ETC. JSR TSTLOK ;IS IT LOCKED? TODONE JM4}P DONE ;RETURN TO CALLER ; ; CLOSE FILE (WRITING ANY PENDING SECTOR) ; DKCLOS JSR SETUP LDA FCBOTC,X AND #$08 ;OUTPUT ALL5}OWED? BEQ CLROTC ;IF NOT, JUST EXIT ROL FCBFLG,X BCC CKFLSC JSR REWRIT ;REWRITE THE LAST SECTOR JSR RRDIR LDA SECCNT,6}X LDY DIRDSP STA DIRBUF+1,Y LDA SECCNT+1,X STA DIRBUF+2,Y LDA DIRBUF,Y AND #$FE ;NOT OPEN FOR OUTPUT ANY MORE JSR SAV7}FLAG LDA SAVSEC,X ORA SAVSEC+1,X BEQ CLROTC CPX LSTIOCB BEQ FAPPD JSR INITYP ;READ ALL THE SECTORS AGAIN APPLP JSR RDNX8}TS BCC APPLP ;NOT EOF YET BCS TIELNK FAPPD LDA LSTSEC STA CURSEC,X LDA LSTSEC+1 STA CURSEC+1,X TIELNK CLC JSR RWDISK L9}DA DLINK STA CURLEN,X LDA SAVSEC,X LDY SAVSEC+1,X JSR SAVLNK CLROTE BPL CLROTC LDA #163 ;FAILURE IS A SYSTEM ERROR JMP:} AEXIT CLROTC LDA #$FF STA ICHID,X LDA #0 STA FCBOTC,X JMP FREDON ; CKFLSC ROL FCBFLG,X BCC CLROTC JSR WRDISK JMP CLRO;}TE ; INITYP LDA #$06 JSR GETFLAG LSR A ROR A ROR A ROR A ORA FCBOTC,X STA FCBOTC,X LDA DIRBUF+3,Y STA LNKSEC,X LDA <}DIRBUF+4,Y STA LNKSEC+1,X LDA CURFNO STA FCBFNO,X LDA #0 STA FCBFLG,X STA CURLEN,X STA SECCNT,X STA SECCNT+1,X RTS ;=} ; DOS XIO ROUTINES ; ; Sorry about the lack of comments in some parts of this file, ; I just never had to figure this co>}de out after I wrote it (:-)! ; NODIRF LDA #176 ;FILE NOT A DIRECTORY JMP AEXIT ; PIKDIR LDY #0 LDA #':' FDVND INY CMP (I?}CBALZ),Y BNE FDVND INY LDA (ICBALZ),Y CMP #'@' BCC SETRDIR CMP #'Z'+1 BCC GFNDIR CMP #'_' BCC SETRDIR CMP #'z'+1 B@}CS SETRDIR GFNDIR JSR LFFILE ;FIND NEW DEFAULT DIRECTORY JSR INITYP JSR TONXDR BEQ NODIRF ;IF NOT A DIRECTORY LDA DIRBAA}S+1,X TAY LDA DIRBAS,X SAVDEF STY CDIREC+1 ;UPDATE ADDRESS OF DIR. STA CDIREC LDA ICDNOZ STA DEFAULT ;UPDATE UNIT NUMBEB}R BPL TOFDN ; SETRDIR LDA #LOW[361] LDY #HIGH[361] BPL SAVDEF ; RENAME JSR LFFILE ;GET OLD NAME, DRIVE, VALIDATE LDY #11C} STEMPL LDA FNAME-1,Y STA MAPBUF+256,Y DEY BNE STEMPL RNLOOP JSR TSTLOK ;CANNOT RENAME IF LOCKED JSR TDDOS ;TEST FOR DOD}S GONE! LDY TMP2 JSR GETNAM ;GET NEW NAME CLC JSR ENTNAME ;OVERWRITE NAME IN DIR. JSR WDIRBK ;REWRITE DIRECTORY TO DIE}SK ; JSR TSTDOS ;NEW NAME DOS.SYS? BNE REPLDS ;NO, LOOK AT NEXT LDY DIRDSP LDA DIRBUF+4,Y ;SAVE FILE LOCATION ON THE SF}TACK PHA LDA DIRBUF+3,Y PHA ; ;;; JSR SYSSET ;Use the MAP buffer [IS THIS NECESSARY???] ; CLC ; == READ LDX #1 ; == G}SECTOR SIZE CODE (1=128, 2=256) LDA #0 LDY #1 ; == SECTOR #1 JSR DKIO ;Read it ; LDA SECDAT STA MAPBUF+SECDAT-$0700 PH}LA STA MAPBUF+DOSLOC-$0700 PLA STA MAPBUF+DOSLOC+1-$0700 ; ;;; LDA #$00 ;[AND IS THIS REALLY NECESSARY???] ;;; STA MAPBUFI}+STATE-$0700 ; SEC ; == WRITE LDX #1 ; == SECTOR SIZE CODE (1=128, 2=256) JSR DKIO2 ;Write it (same sector as I read bJ}efore) ; LDA #$FF ;Then make sure we reread the directory buffer STA DIUNIT ; REPLDS LDY #11 RTEMPL LDA MAPBUF+256,Y STA K}FNAME-1,Y DEY BNE RTEMPL JSR CSFDIR ;TO RENAME BCC RNLOOP TOFDN JMP FREDON ; DELETE JSR LFFILE DELLP JSR REMOVE ;FLUSH L}THE SECTORS JSR RRDIR ;REREAD DIRECTORY BLOCK JSR TDDOS ;DOS.SYS DELETED? LDA #$80 JSR SAVFLAG ;REWRITE DIRECTORY BLOCM}K JSR CSFDIR BCC DELLP ;IF ANOTHER FOUND, BCS TOFDN ;ELSE, WRAP UP AND EXIT ; REMOVE JSR TSTLOK ;ONCE HAD 'OPVTOC' CALLN} FIRST JSR INITYP JSR TONXDR BNE DELDIR JSR CHASE ; FREELP JSR FREE JSR RDNXTS BCC FREELP RTS ; INVDEL LDA #175 ;DIREO}CTORY NOT DELETABLE JMP AEXIT ; LOCK LDA #$20 DB $2C ;BIT ABS (SKIP 2 BYTES) ; UNLOCK LDA #$00 STA DATBYT JSR LFFILE ;FP}IND FILE AND VERIFY WRITABLE LKULKL LDA #$DF ;STRIP OFF OLD BIT 5 JSR GETFLAG ORA DATBYT ;AND REPLACE WITH NEW JSR SAVFLQ}AG JSR CSFDIR BCC LKULKL BCS TOFDN ; DELDIR LDY #-11 LDA #'?' DELSET STA FNAME+11-256,Y INY BNE DELSET JSR SFDIR BCC R}INVDEL ; LDA #8 STA DATBYT JSR TONXT DELDRL JSR FREE JSR INCCSEC DEC DATBYT BNE DELDRL JMP GETFNM ; POINT LDY FCBFLG,XS} BMI ERRCMD ; LDA ICSPR+1,X CMP CURSEC+1,X BNE PNTREAD LDA ICSPR,X CMP CURSEC,X BEQ PNTSME PNTREAD TYA BEQ PNTCLN ;IT}F SECTOR UNMODIFIED JSR WRDISK LDA #0 STA FCBFLG,X PNTCLN LDA ICSPR+1,X STA LNKSEC+1,X LDA ICSPR,X STA LNKSEC,X JSR CHU}ASE ;READ SECTOR POINTED TO BCS BADPNT ; PNTSME LDA ICSPR+2,X CMP MAXLEN,X BCS PNTEQL PNTLST STA CURLEN,X JMP DONE ; PNTV}EQL BEQ PNTLST ;IF POINTING AT LAST BYTE BADPNT LDA #166 ;INVALID POINT LOCATION DB $AE ; ERRCMD LDA #168 ;INVALID IOCB PW}ARAMETER JMP AEXIT ; NOTE LDA CURSEC,X STA ICSPR,X LDA CURSEC+1,X STA ICSPR+1,X LDA CURLEN,X STA ICSPR+2,X JMP DONE ; X}DKXIO JSR SETUP LDA ICCOMZ ;GET COMMAND BYTE CMP #254 BEQ FORMAT CMP #43 ;ADD "MKDIR" CODE FOR SpartaDOS(?) [Bob Puff] Y} BCS ERRCMD ;IF INVALID COMMAND SBC #32-1 BCC ERRCMD TAY LDA VECTBH,Y PHA LDA VECTBL,Y PHA RTS ;VECTOR TO PROPER RZ}OUTINE ; VECTBH DB HIGH[RENAME-1],HIGH[DELETE-1] DB HIGH[MKDIR-1],HIGH[LOCK-1] DB HIGH[UNLOCK-1],HIGH[POINT-1] DB HIGH[NOT[}E-1],HIGH[DKLOAD-1] DB HIGH[ERRCMD-1],HIGH[PIKDIR-1] DB HIGH[MKDIR-1] ;extra vector to MKDIR [Bob Puff] ; VECTBL DB LOW[REN\}AME-1],LOW[DELETE-1] DB LOW[MKDIR-1],LOW[LOCK-1] DB LOW[UNLOCK-1],LOW[POINT-1] DB LOW[NOTE-1],LOW[DKLOAD-1] DB LOW[ERRCMD]}-1],LOW[PIKDIR-1] DB LOW[MKDIR-1] ; ; DOS FORMAT ROUTINES ; FORMAT JSR WBITMP ;WRITE OUT ANY PENDING VTOC SECTORS ; ldy #9^} ;Force format to match current density WOTCP2 lda WOTDCB,y ;set up DCB for specified density [Bob Puff] sta DDEVIC+2,y de_}y bpl WOTCP2 ldx ICDNOZ cpx RAMDKU beq WOTRAM ;don't do it for RAMdisks ; ldy SECSIZ-1,x lda DRVDEF-1,x jsr SETDRV `} ;set density WOTRAM ldx CURFCB ;restore X reg ; LDY #0 TYA ;THEN INITIALIZE NEW BIT MAP (VTOC) CLRMAP STA MAPBUF,Y STa}A MAPBUF+256,Y INY BNE CLRMAP ; LDA #2 STA MAPBUF ;start out as a DOS 2.0 disk LDA #$FF STA (FMSBPT),Y INY STA (FMSBb}PT),Y ;PRESUME NO BAD SECTORS IF BUFFER IS UNMODIFIED LDY ICDNOZ CPY RAMDKU BEQ RAMFMT ;IF RAMDISK, SKIP EVERYTHING LDA c}FMSBPT+1 LDY FMSBPT JSR BUFSET ;SET UP BUFFER POINTER FOR SIO CALL LDX #1 STX TMP1 ;ALLOW ONE TRY ONLY LDA #$22 ;PRESd}UME 1050 D/D FORMAT NEEDED LDY ICAX2Z ;GET AUX2 BYTE BMI FMTOK ;MINUS --> NO FORMAT REQUIRED BNE NMLFMT ;AUX2 NONZERO, e}NORMAL FORMAT WITH SIZE DEFINED LDY ICAX1Z ;(AUX2,AUX1) = 1? DEY BEQ FT1050 ;YES, FORMAT WITH A $22 COMMAND ; NMLFMT ldxf} DUNIT lda SECSIZ-1,X ;PUT SECTOR SIZE CODE (1 OR 2) INTO X tax lda #FMTCMD ;AUX IS 0, must not be 1050 d/d FT1050 STA DAg}UX1 ;MAKE SURE WE SECTOR > 3 LDY DSKTIM ;DISK TIMEOUT VALUE (RETURNED IN STATUS) JSR DKFME ;ENTER DKIO AT FORMAT ENTRY q}B%DOS SYSB )BUILD OBJBDSBUILD ASMBCHANGES BMDOS ASMBJMDOS1 ASMBMDOS2 ASMBaMDOS3 ASMB. MDOS4 ASMB$:MDOS OBJB^MDUP ASMB{MDUP1 ASMB$MDUP2 ASM6MDUP3 ASM0MDUP4 ASM"MDUP5 ASM48MDUP6 ASMVlMDUP7 ASM;MDUP OBJ$2READ ME BPL FMTOK ;Accepting 144 errors here removed [Bob Puff] JMP AEXIT ;RETURN ERROR CODE IF ANY OCCURRED ; RAMFMT STA CURSEC,Xr} ;STUFF PROPER NUMBER OF SECTORS INTO CURSEC CLC ;(256-BYTE PAGES * 2 SINCE SECTOR SIZE IS 128) ADC RDKLMT LSR A ROR CUs}RSEC,X BNE NOTDEF ;FAIL IF NOT 256 SECTORS OR MORE (need 370) ; ; SUCCESSFUL FORMAT, CREATE VTOC AND EMPTY DIRECTORY ; FMTOt}K ;Bob Puff disabled the marginal format code ; ldy #0 ;check for a bad format ; lda (FMSBPT),y ; and (FMSBPT),y ;first u}two bytes $FF? ; cmp #$FF ; beq FMTOK2 ;yep, continue ; lda #173 ;otherwise format error ; bne FMEXIT ; FMTOK2 JSR INVUNITv} ;Can we do this (asks Bob Puff) JSR DELDOS LDA ICAX1Z STA CURSEC,X LDA ICAX2Z AND #$7F ;DISK MUST HAVE 256 SECTORS Bw}NE NOTDEF ;IF SIZE SPECIFIED, USE IT LDY ICDNOZ LDA HDTAB-1,Y ;IF NOT AND THIS IS A HARD DISK STA CURSEC,X ;USE THE SYSTEx}M DEFINED SIZE LDA HDTAB+8-1,Y BNE NOTDEF BIT DVSTAT ;1050 DRIVE? BPL FIGSIZ ;NO, FIGURE SIZE THEN LDA #LOW[1040] ;YESy}, FORCE TO 1040 SECTORS STA CURSEC,X LDA #HIGH[1040] BNE NOTDEF ; FIGSIZ LDA DRVDEF-1,Y AND #$31 ;EXTRACT TRACK COUNT FLz}AGS LSR A PHP LSR A LSR A TAY LDA NOSECS,Y ;AND USE DRIVE DEFAULT SECTOR COUNT STA CURSEC,X LDA NOSECS+1,Y PLP BCC {}NOTDEF ;IF NOT DOUBLE SIDED, THIS IS IT ASL CURSEC,X ROL A ;ELSE, DOUBLE IT ; NOTDEF STA CURSEC+1,X CMP #4 ;NEED 16 BIT|} LINKS? BCC SHORTS ;NO, SHORT FORMAT OK INC MAPBUF ;YES, FORCE LONG FORMAT (DOS3) SHORTS JSR FNDBIT ;FIND LAST BIT MAP S}}ECTOR LDA TMP2 BNE GT246 ;IF PAST 256TH MAP BYTE BIT DLINK ;SINGLE DENSITY? BMI FDBDEN CPY #0 BPL FDBDEN GT246 STA MA~}P2 CLC ADC #3 STA MAPBUF FDBDEN LDA #HIGH[-9] STA MAPBUF+4 LDA #LOW[-9] STA MAPBUF+3 ;START WITH 9 FREE SECTORS UN-FREE}! FLOOP JSR FMTFRE JSR DECCSEC CMP #4 ;BOOT SECTORS YET? BNE FLOOP ;IF NOT, CONTINUE DEALLOCATING LDA CURSEC+1,X BNE F}LOOP ; ; ALLOCATE BAD SECTORS ; [Bob Puff replaced this with code to set FMSBPT to 1, since he ; disallows bad sectors] ; L}DY #0 CLRBDLP LDA (FMSBPT),Y STA CURSEC,X INY LDA (FMSBPT),Y STA CURSEC+1,X INY AND CURSEC,X CMP #$FF CLC BEQ MAPDON}E STY TMP1 JSR DECCNT JSR FNDLBIT EOR #$FF BCC CLRBD1 AND MAPBUF+256,Y STA MAPBUF+256,Y BCS CLRBD2 CLRBD1 AND MAPBUF,}Y STA MAPBUF,Y CLRBD2 LDY TMP1 BNE CLRBDLP SEC LDY #173*2-256 ;NO $FFFF => BAD FORMAT MAPDONE TYA ROR A STA FMSBPT ;PO}SITIVE VALUE = NUMBER OF BAD SECTORS ; ; [End of code that can be optionally deleted] ; LDA #$00 STA MAPBUF+55 LDA #$7F S}TA MAPBUF+56 LDY #44 ;START ALLOC. OF VTOC HERE LDA MAPBUF SEC SBC #2 ;GET NUMBER OF SECTORS BIT DLINK ;(SINGLE DENSI}TY?) BMI MPNSD ;IF NOT, M-3 ASL A ;IF SO, M*2-5 MPNSD TAX DEX ;MOVE COUNT TO X ; ALCMPL LDA #$FF ALCMAP DEX BMI SMBSI}Z PHA JSR DECCNT PLA ASL A BNE ALCMAP STA MAPBUF+10,Y DEY BPL ALCMPL ;BRANCH ALWAYS! ; SMBSIZ STA MAPBUF+10,Y LDA M}APBUF+3 ;MARK EMPTY SIZE, TOO STA MAPBUF+1 LDA MAPBUF+4 STA MAPBUF+2 JSR FMTMAP ;WRITE MAP TO DISK ; ; CREATE AN EMPTY }DIRECTORY ; LDA #LOW[361] LDY #HIGH[361] CLRDIR JSR SETDIR ;RESET THE DIRECTORY BASE SECTOR TYA CLRDLP STA DIRBUF,Y ;ZERO} THE DIRECTORY BUFFER INY BNE CLRDLP ; LDA #7 STA DIRSEC CLRDL2 JSR WDIRBK ;THEN WRITE ALL 8 SECTORS OUT DEC DIRSEC BP}L CLRDL2 LDY BUFNO,X LDA #0 STA BUFNO,X STA BUFFLG-1,Y ;FORMAT DONE, FREE THE INTERNAL BUFFER LDA FMSBPT JMP AEXIT ; NO}SECS DW 35*18,40*18,80*18,77*26 ; SETDIR STA DIRBAS,X TYA STA DIRBAS+1,X LDY #0 RTS ; ; DOS BINARY LOAD CODE (LOAD AND OP}TIONALLY EXECUTE A PROGRAM) ; DKLOAD LDA ICAX1Z STA ICPTLZ ;SAVE PROGRAM NAME BUFFER POINTER CMP #$08 BCS TOERRC ;IF WRI}TE, REPORT ERROR ; LDA #LOW[TORTS] STA RUNADR LDA #HIGH[TORTS] ;ASSUME RUNN ADDRESS IS ABSENT STA RUNADR+1 LDA #4 STA I}CAX1Z LDA ICHID,X ;IOCB OPEN? BPL CCFILE JSR DKOPEN ;IF NOT, OPEN IT BMI DKLERV JSR WDREAD ;READ ONE WORD OF THE HEAD}ER BEQ CCFILE LDY #180 ;NO $FFFF, HEADER ERROR CODE BMI DKLERV ; TOERRC LDY #168 ;INVALID IOCB RTS ; GETTXT LDA #LOW[TO}RTS] STA INIADR LDA #HIGH[TORTS] ;FOR EACH SEGMENT, RECLEAR THE INIT VECTOR STA INIADR+1 TXTLP JSR DKREAD DKLERV BMI DKLER}R LDY #0 STA (ICBALZ),Y INC ICBALZ BNE DECLEN INC ICBAHZ DECLEN LDA ICBLLZ BNE DECLOW DEC ICBLHZ DECLOW DEC ICBLLZ BN}E TXTLP LDA ICBLHZ BNE TXTLP LDA ICBAHZ CMP #HIGH[INIADR] BNE CCFILE ; LDA ICPTLZ ;IF NO INITS, LSR A BCS CCFILE ;S}KIP TO NEXT PAGE TXA ;ELSE SAVE IOCB PHA LDY #256-12 CPSICB LDA ICHIDZ-256+12,Y STA ICHID,X ;SAVE THE 12-BYTE IOCB ENT}RY INX INY BNE CPSICB PLA TAX PHA JSR DOINIT ;AND CALL INIT FUNCTION PLA TAX PHA LDY #256-12 CPRICB LDA ICHID,X };THEN RESTORE THE 12-BYTE IOCB STA ICHIDZ-256+12,Y INX INY BNE CPRICB PLA TAX ; CCFILE JSR WDREAD ;READ THE SEGMENT ST}ART ADDRESS BEQ CCFILE STA ICBALZ STY ICBAHZ JSR WDREAD ;READ THE SEGMENT END ADDRESS SEC ADC #0 BCC CCSUBT INY CCSU}BT SEC SBC ICBALZ ;CALCULATE THE LENGTH TO LOAD INTO RAM STA ICBLLZ TYA SBC ICBAHZ STA ICBLHZ BCS GETTXT ;BRANCH IF V}ALID LENGTH (GET DATA BYTES) LDY #181 ;ELSE, MEMORY WRAP ERROR BMI DKLERR ; WDXIT PLA PLA DKLERR TYA PHA JSR DKCLOS ;C}LOSE THE PROGRAM FILE PLA TAY ;AND RETURN ANY ERROR CODE RTS ; ; READ A WORD FROM THE PROGRAM FILE AND COMPARE IT WITH }$FFFF ; WDREAD LDA #0 STA ICBLLZ STA ICBLHZ ;SET LENGTH TO ZERO JSR DKREAD ;READ A BYTE BMI WDEOF PHA JSR DKREAD ;RE}AD THE SECOND BYTE BMI WDEOF1 TAY PLA CPY #$FF ;UPPER BYTE $FF? BNE TORTS ;NO, THEN WORD IS NOT $FFFF CMP #$FF ;YES,} IS LOWER BYTE $FF? TORTS RTS ;IF BOTH $FF, RETURN ZERO FLAG ; WDEOF1 PLA WDEOF CPY #136 ;IS THIS END OF FILE? BNE WDXIT } ;IF NOT, RETURN ERROR CODE PLA PLA ;ELSE, GET RID OF RETURN ADDR LDA ICPTLZ LSR A LSR A PHP JSR DKCLOS ;CLOSE FILE} AND SET Y=1 PLP BCS TORTS ;EXIT IF NO-RUN SPECIFIED JMP (RUNADR) ;THEN GO TO RUN ADDRESS ; ; INVOKE INIT FOR EVERY BLOC}K OF INPUT CODE (USUALLY JUST AN RTS) ; DOINIT JMP (INIADR) ;CALL INDIRECT ; ; XIO FUNCTION TO CREATE A NEW DIRECTORY ; ; P}ARSE DIRECTORY NAME ; MKDIR JSR GETFNM JSR SFDIR ;FIND FILE IN DIRECTORY BCS MKDMRD LDA #172 ;FILE ALREADY EXISTS DB $A}E ;SKIP 2 BYTES DISFUL LDA #169 ;DIRECTORY FULL JMP AEXIT ; ; READ IN BIT MAP ; MKDMRD LDA HOLFN BMI DISFUL JSR RBITMP } LDY MAPBUF DEY DEY STY DATBYT ; ; FIND EIGHT SECTORS FOR DIRECTORY ; LDA #LOW[369] ;FIRST AVAILABLE SECTOR AFTER ROOT D}IR. STA CURSEC,X LDA #HIGH[369] STA CURSEC+1,X LDA #0 STA TMP1 FDIRLP INC TMP1 JSR FNDLBIT ;IS THIS SECTOR FREE? BCS }FDIR2 AND MAPBUF,Y BCC FDIR1 FDIR2 AND MAPBUF+256,Y FDIR1 BNE FDIR3 STA TMP1 FDIR3 JSR INCCSEC LDA TMP1 CMP #8 BNE FDIR}LP ; ; ALLOCATE THE SECTORS USED ; ALCDLP JSR DECCSEC JSR FNDLBIT EOR #$FF BCS ALCPG2 AND MAPBUF,Y STA MAPBUF,Y BCC AL}CPG1 ALCPG2 AND MAPBUF+256,Y STA MAPBUF+256,Y LSR MAP2MOD ALCPG1 JSR DECCNT DEC TMP1 BNE ALCDLP ; ; WRITE ALLOCATION MAP} BACK TO DISK ; JSR FMTMAP ; ; ENTER NAME AND TYPE INFO INTO PARENT DIRECTORY ; LDA HOLFN JSR SDIRBK SEC JSR ENTNAME L}DA CURSEC+1,X STA DIRBUF+4,Y LDA CURSEC,X STA DIRBUF+3,Y LDA #0 STA DIRBUF+2,Y LDA #8 STA DIRBUF+1,Y ASL A JSR SAVFL}AG ; ; THEN CLEAR NEW DIRECTORY ; LDA #1 STA FMSBPT LDA CURSEC,X LDY CURSEC+1,X JMP CLRDIR DIRBUF+1,Y ASL A JSR SAVFLa; ; DOS DIRECTORY ROUTINES ; ; OPEN A DIRECTORY (FOR USER) ; LSTDIR LDY #$80-11 SAVFNB LDA FNAME-$80+11,Y STA (FMSBPT),Y IN}Y BPL SAVFNB JSR SFDIR ;FIND A MATCH IN THE DIRECTORY BCS ENDDIR ;IF NO MORE MATCHES, REPORT FREE SPACE NXTDIR JSR FMTDI}R ;ENTRY FOUND, FORMAT INTO A TEXT STRING LDA CURFNO STA FCBFNO,X ;SAVE THE FILE NUMBER OF THE ENTRY FOUND GODONE JMP DONE} ;AND RETURN ; GOTEOD DEC DATBYT ;CONVERT EOL TO $9B (REAL EOL) STA CURLEN,X ;AND FINISH UP BNE GODONE ; DIRRD LDY #$80-1}1 RSTFNB LDA (FMSBPT),Y ;FETCH BYTES OF PREVIOUSLY PARSED DIRECTORY ENT STA FNAME-$80+11,Y INY BPL RSTFNB LDA CURLEN,X B}MI DIREOF ;EOF IF WE ALREADY REPORTED FREE SPACE TAY LDA (FMSBPT),Y STA DATBYT INC CURLEN,X CMP #$9C BEQ GOTEOD CMP #}$9B ;IS THIS END OF LINE? BNE GODONE ;IF NOT, CONTINUE FETCHING OLD BYTES LDA FCBFNO,X CMP CURFNO BNE DMSTRD CPX DIUNI}T BEQ DRDNRQ DMSTRD JSR RRDIR ;IF SO, INSURE DIRECTORY BLOCK IS IN MEMORY DRDNRQ JSR CSFDIR ;AND FIND THE NEXT ENTRY BCC }NXTDIR ;IF FOUND, LOOP BACK AND FORMAT IT ; ; NO MORE ENTRIES, REPORT FREE SECTORS LAST ; ENDDIR JSR RBITMP ;READ THE VTOC} DATA LDY #0 STY CURMAP ;FORCE A REREAD NEXT TIME LDA MAPBUF+3 LDX MAPBUF+4 ;AND STUFF THE BUFFER WITH NO. OF FREE SECTO}RS JSR CVTDEC LDX #-14 FSECL LDA FSECM+14-256,X ;FOLLOWED BY THE "FREE SECTORS" TEXT STA (FMSBPT),Y INY INX BNE FSECL }BEQ GODONE ; DIREOF JMP RETEOF ;NO MORE LINES, RETURN EOF INDICATION ; FSECM DB ' FREE SECTORS',$9C ; ; FORMAT A DIRECTORY }ENTRY FOR BASIC, ETC. ; FMTDIR LDY #' ' LDX DIRDSP LDA DIRBUF,X PHA AND #$20 BEQ D0E35 LDY #'*' ;IF SO, MARK AS LOCKED }D0E35 TYA LDY #0 STA (FMSBPT),Y PLA LDY #' ' AND #$10 BEQ NOTDIR LDY #':' NOTDIR TYA LDY #1 STA (FMSBPT),Y CPYNAML I}NY LDA DIRBUF+5,X STA (FMSBPT),Y INX CPY #13 BCC CPYNAML ; LDA #' ' STA (FMSBPT),Y LDY DIRDSP LDA DIRBUF+1,Y LDX DI}RBUF+2,Y LDY #14 ;SECTOR COUNT STARTS HERE ; ; CONVERT A 16-BIT INTEGER TO A 4 OR 5 DIGIT NUMBER ; CVTDEC STX TMP2 STA TMP}1 LDX #HIGH[10000] LDA #LOW[10000] JSR MKDGT2 CMP #'0' BNE SKIP5 DEY SKIP5 LDX #HIGH[1000] LDA #LOW[1000] JSR MKDGT2 } LDA #100 ;FOR THE SHORT STUFF JSR MAKDGT LDA #10 JSR MAKDGT TXA ADC #'0'+10 STA (FMSBPT),Y INY LDA #$9B ;TERMINATE} LINE STA DATBYT STA (FMSBPT),Y LDA #0 LDX CURFCB STA CURLEN,X RTS ; ; CREATE A DIGIT AND STORE IT INTO THE DIRECTORY }BUFFER ; MAKDGT LDX #0 ;IF SUBTRAHEND < 256, ZERO UPPER BYTE MKDGT2 STX DIRDSP STA DIRSEC STY DATBYT LDY #'0' SEC DGTLP2} LDA TMP1 SBC DIRSEC TAX LDA TMP2 SBC DIRDSP BCC DGTXIT STA TMP2 STX TMP1 INY BCS DGTLP2 ; DGTXIT TYA LDY DATBYT S}TA (FMSBPT),Y INY RTS ; ; PARSE A FILE NAME WITH WILD CARD CHARACTERS ('*' AND '?') ; GETNM2 iny ;look for ">" in lda (}ICBALZ),y ;the start of cmp #'>' ;the filename beq GETNAM ;(for SpartaDOS compatibility) dey ;[Bob Puff] bne GETNAM };branch always ; GETFNM LDX CURFCB LDY #HIGH[361] LDA #LOW[361] JSR SETDIR INY LDA (ICBALZ),Y INY CMP #':' ;DEFAULT D}IRECTORY? BNE GETNM2 ;IF NOT, CHECK FOR SPARTA ">" DEY STY TMP1 LDY DEFAULT STY ICDNOZ TYA STA ICDNO,X JSR SETUPD L}DA CDIREC LDY CDIREC+1 JSR SETDIR LDY TMP1 ; GETNAM LDX #-11 INY AFTSTR LDA (ICBALZ),Y CMP #'*' BNE TSTPER LDA #'?' I}NY QLOOP STA FNAME+11-256,X INX BPL TOXITC ;END OF EXTENSION? PERFND CPX #-3 ;END OF FILE NAME? BNE QLOOP ;NO MORE -?-S} BEQ AFTSTR ; TSTPER CMP #'.' ;A PERIOD? BNE TSTCHR ;IF NOT, CHECK FOR INDIVIDUAL CHARACTERS LDA #' ' ;IF SO, FILL WITH} SPACES INY BNE PERFND ; TSTCHR CMP #'?' BCC ENDCHR ;IF < '?', CHECK FOR DIGIT CMP #'Z'+1 ;ELSE, UPPER CASE LETTER, '?'}, OR '@'? BCC GOTCHR CMP #'_' BCC ENDCHR ;IF CARET, BACKSL. OR BRACKETS CMP #'z'+1 ;LOWER CASE, ACCENT OR UNDERSCORE? }BCC GOTCHR ENDCHR CPX #-11 ;IF FIRST CHAR, ERROR BEQ ERRCHR ;NO BYTES IN FILE NAME CMP #'0' ;ELSE, A DIGIT? BCC FILLNM } ;IF NOT, THIS IS END OF NAME CMP #':' BCS FILLNM ; GOTCHR STA FNAME+11-256,X INY INX BMI AFTSTR ; TOXITC LDA (ICBALZ),Y} TSTDIR CMP #':' ;LOOK FOR SUBDIRECTORY BEQ MYDIR ;IF MYDOS SYNTAX CMP #'>' ;OR SPARTA SYNTAX BNE XITCHR ;IF FINISHED,} RESTORE FCB PTR TO X AND EXIT MYDIR STY TMP2 JSR SFDIR ;ELSE, FIND FILE BCS FNER1 ;NO SUCH FILE JSR TONXDR BEQ FNER1 }LDY TMP2 BNE GETNAM FNER1 LDA #174 ;IF NOT, RETURN ERROR 174 DB $2C ;BIT ABS (SKIP 2 BYTES) ; ERRCHR LDA #165 JMP AEXIT ; }FILLNM PHA LDA #' ' FILLLP STA FNAME+11-256,X INX BMI FILLLP PLA JMP TSTDIR ; ; RETURN WITH NON-ZERO FLAG IF FILE IS A }DIRECTORY ; TONXDR LDA #$10 ;FILE FOUND, A DIRECTORY? JSR GETFLAG BEQ TONXIT ;IF NOT, SET ZERO FLAG LDA DIRBUF+3,Y ;IF S}O, MOVE POINTERS TO THE NEW LEVEL STA DIRBAS,X LDA DIRBUF+4,Y STA DIRBAS+1,X LDA #$10 ;AND CLEAR THE ZERO FLAG TONXIT RT}S ; ; ENTER A NAME INTO THE DIRECTORY AT DIRBUF[DIRDSP] ; ENTNAME PHP LDX #-11 LDY DIRDSP NAMELP LDA FNAME+11-256,X ;LOAD }THE MASK CHARACTER CMP #'?' BNE STORIT ;IF NOT '?', SAVE IT AS IT APPEARS PLP PHP BCC NOSTOR ;IF CY CLEAR, LEAVE THE C}HARACTERS UNCHANGED LDA #' ' ;IF CY SET, CONVERT '?'S TO SPACES STORIT STA DIRBUF+5,Y NOSTOR INY INX BMI NAMELP PLP LDY} DIRDSP XITCHR LDX CURFCB RTS ; SFDIR JSR WBITMP ;INSURE BIT MAP IS SAFE LDX #255 STX HOLFN STX CURFNO INX STX DAUX2 }INX STX DAUX1 LDX #READ STX DCOMND JSR SYSSET ;SET UP POINTERS FOR SYSTEM BUFFER I/O ; LDA ICDNOZ CMP RAMDKU BEQ CSFD}IR ;IF RAMDISK, FORGET DENSITY CHECK ldx CURFCB ;IF A ROOT DIRECTORY ACCESS, READ BOOT SECTOR lda DIRBAS,X ;IF IN A SUBDI}RECTORY, ASSUME DENSITY IS OK cmp #LOW[361] ;[Bob Puff] bne CSFDIR ;;; lda DIRBAS+1,X ;Only occasionally will we get an ext}ra read! ;;; cmp #HIGH[361] ;;; bne CSFDIR ; JSR DSKINV ;ELSE, READ THE FIRST BOOT SECTOR BMI ERRX JSR INVUNIT ;UPDATE D}RIVE CONFIGURATION ; CSFDIR INC CURFNO ;READ NEXT 16-BYTE DIR. BLOCK LDA CURFNO JSR BSECDS ;CONVERT TO SECTOR AND DISPLAC}EMENT XITCH1 BCS XITCHR BNE NOREAD ;IF DISP>0, PROCESS BLOCK JSR RDIRBK ;IF DISP=0, READ SECTOR ; NOREAD LDY DIRDSP LDA }DIRBUF,Y BEQ FNDOLD ;ZERO IS END OF DIRECTORY (NO MORE ENTRIES) BMI FNDOLD ;NEGATIVE IS EMPTY SLOT (MAY HAVE MORE ENTRIES}) ; ; HANDLE DOS 2.5 FILES ; and #$DF ;preserve lock flag cmp #3 ;is this DOS 2.5 + file? bne NOD25 ;nope lda #$41 ;}otherwise, kludge the eor DIRBUF,Y ;flag to make $42 sta DIRBUF,Y ;and save lock. ; NOD25 AND #$01 ;IGNORE ANY FILE THAT I}S MARKED "OPEN" BNE CSFDIR LDX #-11 CPNXCH LDA FNAME+11-256,X CMP #'?' BEQ WCMTCH ;EVERYTHING MATCHES "?" CMP DIRBUF+5,}Y BNE CSFDIR ;NO MATCH, LOOK AT THE NEXT DIRECTORY ENT WCMTCH INY INX BMI CPNXCH CLC BCC XITCHR ;ENTRY FOUND, RETURN W}ITH CY=0 ; FNDOLD LDX HOLFN BPL KPOLD ;IF AN EMPTY SLOT IS ALREADY FOUND, DO NOTHING LDX CURFNO STX HOLFN ;ELSE SAVE THI}S ONE, ITS THE FIRST! KPOLD TAX BMI CSFDIR ;IF NOT END OF THE DIRECTORY, KEEP LOOKING ERRX SEC BCS XITCH1 ;ELSE, ENTRY NO}T FOUND, RETURN WITH CY=1 ; ; DOS I/O ROUTINES ; ; DISK SECTOR I/O ROUTINES ; WRDISK SEC ;FMS DISK WRITE ENTRY RWDISK LDY }FMSBPT ;DATA SECTOR READ/WRITE ENTRY LDA FMSBPT+1 JSR BUFSET LDA CURSEC+1,X LDY CURSEC,X FMDKIO PHP LDX DUNIT CPX RAMD}KU BEQ RDKIO1 PLP pha ;ALLOW FOR DENSITY CHANGE IN FORMAT, ETC. lda SECSIZ-1,X ;[Bob Puff] tax pla JMP DKIO ; RDKIO1} JMP RDKIO ;ABSOLUTE DISK I/O ROUTINE WAS MOVED TO LOW RAM ; EXTEND JSR ALLOC LDA FCBOTC,X LSR A BCC REWRIT DEC FCBOTC,X} JSR WTRICK JMP WRTTST ; REWRIT LDY LNKSEC+1,X LDA LNKSEC,X JSR SAVLNK WRTTST BMI RTBADF INC SECCNT,X BNE TONXT INC SE}CCNT+1,X ; TONXT LDA LNKSEC,X ;MAKE NEXT SECTOR STA CURSEC,X ;NEW CURRENT SEC. LDA LNKSEC+1,X STA CURSEC+1,X LDA #0 STA }LNKSEC,X ;ZERO LINK STA LNKSEC+1,X LENSET STA CURLEN,X ;ZERO CURRENT OFFSET LDA DLINK ;GET THE LINK LOC. STA MAXLEN,X ;MA}KE IT MAX. LEN. CLC ;CLEAR CY FOR LATER READ RTS ; RDNXTS LDA FCBFLG,X BEQ CHASE ; WRNXTS LDA FCBFLG,X BMI EXTEND ASL }A BPL RDNXTS ASL A STA FCBFLG,X JSR WRDISK BPL RDNXTS ; RTBADF JMP HWERR ;RETURN HARDWARE ERROR CODE IF PRESENT ; SAVLN}K PHA TYA LDY DLINK STA (FMSBPT),Y PLA INY STA (FMSBPT),Y INY LDA CURLEN,X NOBIT STA (FMSBPT),Y LDY FCBOTC,X BMI LE}N16 ;16-BIT LENGTH? LDA FCBFNO,X ASL A ASL A LDY DLINK ORA (FMSBPT),Y STA (FMSBPT),Y LEN16 JMP WRDISK ; WTRICK LDA LNK}SEC,X STA SAVSEC,X LDA LNKSEC+1,X STA SAVSEC+1,X STX LSTIOCB LDA CURSEC,X STA LSTSEC LDA CURSEC+1,X STA LSTSEC+1 JMP} WRDISK ; INSTRT JSR INITYP ; CHASE LDA LNKSEC,X ORA LNKSEC+1,X BEQ NOLINK JSR TONXT ;SET CY=0, FUNC=READ JSR RWDISK BM}I RTBADF ;CANNOT READ SO BAD FILE NUMBER(ERR=164) LDY DLINK LDA FCBOTC,X ;16-BIT LINK? ORA #$7F BMI LNGLNK LDA (FMSBPT)},Y LSR A LSR A CMP FCBFNO,X BNE XLINKED LDA #$03 LNGLNK AND (FMSBPT),Y STA LNKSEC+1,X INY LDA (FMSBPT),Y STA LNKSEC,}X INY LDA (FMSBPT),Y STA MAXLEN,X DRDXIT CLC RTS ; XLINKED LDA ICCOM,X CMP #FMTCMD ;IS THIS A FORMAT? BNE FNOERR NOLIN}K SEC RTS ; ; READ OR WRITE A DIRECTORY BLOCK ; RRDIR LDA FCBFNO,X ; SDIRBK STA CURFNO RDCFNO LDA CURFNO JSR BSECDS ; RDIRB}K JSR WBITMP ;TAKE CONTROL OF SYSTEM BUFFER CLC DB $A9 ;LDA # (SKIPS 1 BYTE) WDIRBK SEC RWDBK PHP LDX CURFCB ;PUT FCB N}O. IN X STX DIUNIT ;SAVE THE DIR. BUFFER IOCB JSR SYSSET CLC LDA DIRSEC ADC DIRBAS,X TAY LDA DIRBAS+1,X ADC #0 ;MUL}TIPLE DIRS. REQ. THIS [ChasM] PLP SYSRW JSR FMDKIO BPL DRDXIT LDA #163 ;BIT MAP R/W ERROR, RETURN SYSTEM ERR. CODE DB $A}E ;SKIP 2 BYTES ; FNOERR lda #164 sta DSTATS jmp HWERR ;FILE NUMBER MISMATCH ; ; READ OR WRITE THE DISK VTOC (BIT MAP) ; }RBITMP LDA CURMAP CMP ICDNOZ BEQ MAPXIT ;SKIP READ IF WHAT WE WANT IS ALREADY THERE JSR WBITMP ;ELSE, REAL I/O, SAVE CUR}RENT BUFFER CONTENTS ; LDA #0 TAY ZMAP STA MAPBUF,Y ;ZERO ENTIRE 512 STA MAPBUF+256,Y ;BYTES OF MAP BUF. DEY BNE ZMAP C}LC JSR RWBMAP ;THEN READ 128 OR 256 BYTES OF VTOC DATA ; LDY #$FF STY DIUNIT ;INDICATE MAP (NOT DIR) IS LOADED STY MAP2} ;INDICATE SECOND PAGE OF MAP IS UNLOADED INY STY CHGMAP ;INDICATE MAP IS UNCHANGED INY STY MAP2MOD STY CURMP ; MAPCLR} STA CURMAP ;AND SAVE DRIVE NUMBER MAP APPLIES TO MAPXIT RTS ; WBITMP LDA CHGMAP BEQ MAPCLR ;IF MAP NOT CHANGED, SKIP WRIT}ING IT STA DUNIT FMTMAP LDA #0 STA CHGMAP ;ELSE MARK IT UNUSED STA CURMAP lda DUNIT ;save drive # [Bob Puff] pha SEC } JSR RWBMAP pla ;then restore it [Bob Puff] sta DUNIT ; WRNXTM LDA MAP2MOD BNE NOMPI2 ;IF THE PAGE BUFFER IS CLEAN, JU}ST EXIT LDA #$FF ;ELSE, WRITE IT TO DISK PHA LDA MAP2 INC MAP2MOD SEC BCS MUSTWM ; RDNXTM CMP MAP2 ;READ A PAGE INTO }THE SECOND PAGE BUFFER BEQ NOMAPI ;IF IT IS ALREADY THERE, JUST EXIT PHA JSR WRNXTM ;ELSE, WRITE THE CURRENT PAGE (IF NE}CESSARY) PLA ;AND READ THE NEW ONE PHA CLC ;BY FALLING INTO MUSTWM WITH CY=0 ; MUSTWM PHA LDA #HIGH[MAPBUF+256] LDY }#LOW[MAPBUF+256] JSR BUFSET ;SET UP THE BUFFER POINTER FOR 2ND PAGE PLA ; OF THE VTOC BUFFER JSR MAPIOC ;ISSUE I/O RE}QUESTS PLA STA MAP2 ;UPDATE SECOND BUFFER ID BYTE NOMAPI RTS ; RWBMAP JSR SYSSET ;SET UP BUFFER POINTERS FOR SYSTEM BUF I}/O LDA #0 MAPIOC PHP pha ldx DUNIT ;NOTE: THE CURRENT I/O MAY NOT BE TO THE lda SECSIZ-1,X ;FCB BEING ACCESSED! tax };[Bob Puff] pla cpx #2 ;256 BYTE SECS? beq MAPDDS ASL A ;128, CHANGE PAGE NUMBER TO PAIR NUMBER MAPDDS EOR #$FF SEC A}DC #LOW[360] TAY cpx #2 ;128 OR 256 BYTE SECTORS? beq DDMAPX ;IF 128, READ 2 SECTORS TO FILL BUFFER LDA #HIGH[360] PLP} PHP JSR SYSRW ;READ OR WRITE THE FIRST SECTOR LDA MAPBUF CMP #3 ;IF DOS 2.0 DISK, READ ONE SECTOR BCC XITMBF ;EVEN I}N SINGLE DENSITY JSR STEPBP DEY DDMAPX LDA #HIGH[360] PLP PHP JSR SYSRW ;READ OR WRITE THE SECOND (OR ONLY) SECTOR XITM}BF PLP NOMPI2 LDA ICDNOZ STA DUNIT ;RESTORE THE USER DRIVE NUMBER TO DUNIT, RTS ;SINCE I/O MAY HAVE BEEN TO ANOTHER DRIV }E ; SYSSET LDA #HIGH[MAPBUF] LDY #LOW[MAPBUF] JMP BUFSET ; ; ROUTINE TO STEP TO THE NEXT DIRECTORY ENTRY (UNTIL WE RUN OUT }) ; BSECDS LDY #0 STY DIRDSP LSR A ROR DIRDSP LSR A ROR DIRDSP LSR A ROR DIRDSP ;(FILE NUMBER MOD 8) * 16 IS OFFSET I }N SECTOR STA DIRSEC ;FILE NUMBER/8 IS SECTOR OFFSET ; CMP #8 ;END OF DIRECTORY? DEY BCS BSECXT ROR DIRDSP BSECXT RTS I|; ; DOS ALLOCATION ROUTINES ; ; FREE A SECTOR FOR LATER USE ; FREE JSR RBITMP ;MAKE SURE WE HAVE THE RIGHT MAP STA CHGMAP F" }MTFRE INC MAPBUF+3 ;BUMP LOW BYTE OF FREE SECTOR COUNT BNE FREE0 ;IF NO CARRY INC MAPBUF+4 FREE0 JSR FNDBIT PHA LDA TMP2"} BEQ SBMP1 STY TMP2 CMP CURMP ;BEFORE FIRST HOLE? BCS SBMP2 ;NO, LEAVE UNCHANGED STA CURMP ;YES, NEW FIRST HOLE SBMP2"} JSR RDNXTM LDY TMP2 LSR MAP2MOD ;MARK MAP PAGE2 DIRTY PLA ORA MAPBUF+256,Y STA MAPBUF+256,Y RTS ; SBMP1 PLA ORA MAPB"}UF,Y STA MAPBUF,Y RTS ; ; FIND BIT ASSOCIATED WITH A SECTOR ON THE DISK ; FNDBIT LDA CURSEC,X AND #7 ;EXTRACT THE BIT NUMB"}ER TAY SEC LDA #0 FREE1 ROR A ;POSITION CARRY TO THE BIT TO FLIP DEY BPL FREE1 PHA ;SAVE THE BIT MASK ; LDA CURSEC,X "} CLC ADC #10*8 ;ALLOW FOR 10 BYTE HEADER TAY ;SAVE LOW BYTE LDA CURSEC+1,X ADC #0 ;PROPOGATE CARRY LSR A STA TMP2 TYA"} ROR A LSR TMP2 ROR A LSR TMP2 ROR A TAY ; PLA ;RESTORE THE BIT MASK RTS ; ; ALLOCATE AN UNUSED SECTOR TO A FILE ; A"}LLOC JSR RBITMP STA CHGMAP LDY #10 LDA #0 STA TMP2 ALL1 CMP MAPBUF,Y ;ANY BITS LEFT? BNE SECFN1 ;IF SO INY BNE ALL1 ;"} SEC LDA MAPBUF SBC CURMP SEC SBC #3 STA TMP1 ALLCK BMI ALGONE LDA CURMP STA TMP2 JSR RDNXTM LDA #0 TAY ALL2 CMP M"}APBUF+256,Y BNE SECFN2 ;IF FREE SECTOR IN SECOND PART OF MAP INY BNE ALL2 INC CURMP ;TO NEXT SECTOR OF BIT MAP DEC TMP"}1 BPL ALLCK ; ALGONE DEC CURMP DFERR LDA #162 ;DISK FULL ERROR CODE JMP AEXIT ;IF THIS IS IT, ERROR-EXIT ; SECFN1 SEC LD"}X #$AF ;I.E., -8*10 - 1 ALL3 ROR A INX CMP MAPBUF,Y BCC ALL4 CLC BNE ALL3 ALL4 EOR MAPBUF,Y STA MAPBUF,Y BPL ALL7 ; S"}ECFN2 SEC LDX #$AF ;I.E., -8*10 - 1 ALL5 ROR A INX CMP MAPBUF+256,Y BCC ALL6 CLC BNE ALL5 ALL6 LSR MAP2MOD EOR MAPBUF"}+256,Y STA MAPBUF+256,Y ; ALL7 TYA ASL A ROL TMP2 ASL A ROL TMP2 ASL A ROL TMP2 STA TMP1 TXA ADC TMP1 LDX CURFCB "}STA LNKSEC,X LDA TMP2 ADC #$FF STA LNKSEC+1,X DECCNT LDA MAPBUF+3 BNE NOBOR DEC MAPBUF+4 NOBOR DEC MAPBUF+3 CLC RTS ; "}; SIMULATE OLD STYLE BIT FINDER ; FNDLBIT JSR FNDBIT PHA ;SAVE MASK LDA TMP2 ;FIRST PAGE? BEQ FNDPG0 STY TMP2 ;SAVE "}OFFSET IN PAGE CMP DATBYT BCS DFEJMP JSR RDNXTM ;READ IN PROPER PAGE LDY TMP2 ;THEN RESTORE A AND Y REGS PLA SEC ;S"}ET CY (PAGE 1 BUFFER USED) RTS ; FNDPG0 PLA ;RESTORE SAVED MASK CLC ;AND CLR CY (SAY PAGE 0) RTS ; DFEJMP JMP DFERR ; "}DECCSEC LDA CURSEC,X BNE ALCPG0 DEC CURSEC+1,X ALCPG0 DEC CURSEC,X RTS ; INCCSEC INC CURSEC,X BNE DELDIN INC CURSEC+1,X " }DELDIN RTS ; ; DOS MISC. SUBROUTINES ; ; SET UP STATE VARIABLES ON ENTRY ; SETUP LDY ICDNOZ ;GET UNIT NO. SETUPW STX CURFCB "!} TSX INX INX STX STKPSV ;SAVE POINTER TO RETURN ADDR ON STACK SETUPD STY DUNIT ;COPY UNIT NO. TO DCB LDA #1 CPY RAMDKU ""}BEQ UFIXED ;RAMDISK SECTOR SIZE IS ALWAYS 128 BYTES LDA SECSIZ-1,Y BEQ INVUNIT ;IF NOT CURRENTLY VALID UNIT, TEST FOR DENSI"#}TY UFIXED STA SECDAT ;OTHERWISE, STORE CORRECT DENSITY DATA LSR A ROR A ROR A ORA #$7D ;UPDATE THE LINK POSITION IN THE D"$}ISK SECTOR STA DLINK ; LDX CURFCB LDY BUFNO,X ;GET THE BUFFER NUMBER BNE RSETUP LDY FILES ;IF ONE IS NOT ALLOCATED IN"%}Y SFORB DEY BEQ NOSECB ;ALLOCATE ONE, OR ABORT THE OPERATION NOW LDA BUFFLG-1,Y BNE SFORB LDA #$80 STA BUFFLG-1,Y TYA "&} STA BUFNO,X RSETUP LDA DOSEND ;==SBTABL STA FMSBPT LDA SBTABU-1,Y STA FMSBPT+1 RTS ; INVUNIT JSR JSTRD BNE UFIXED ; NOU"'}NIT LDA #160 ;RETURN ST=160, DRIVE NOT PRESENT DB $AE ;SKIP TO JMP INSTRUCTION NOSECB LDA #161 ;RETURN ST=161, NO MORE FILE "(}BUFFERS JMP AEXIT ; ; REMOVE DOS POINTER FROM BOOT SECTORS ; TDDOS JSR TSTDOS ;MUST WE UPDATE BOOT? BNE NODOSX ;NO, RETURN")} ; DELDOS LDY #0 ;YES, REMOVE DOS POINTER FROM BOOT BEQ UPDBT ; ; ADD DOS POINTER TO BOOT SECTORS ; SETDOS STY DOSLOC STA "*}DOSLOC+1 LDY SECDAT UPDBT LDA DUNIT CMP RAMDKU BEQ TDEXIT STY SECDAT LDA STATE PHA LDA DEFAULT PHA LDA #$00 STA STA"+}TE ;NOTHING IS IN MEMORY YET LDY #$FF LDA FCBOTC,X BMI NOAND ;LONG LENGTH FIELD? LDY #$03 ;IF NOT, USE ONLY 10 BITS NO",}AND STY ANDCD+1 LDA #HIGH[BOOTFL] LDY #LOW[BOOTFL] JSR BUFSET LDY #0 STY DAUX2 ; WSECL INY STY DAUX1 LDX #1 STX DEFAU"-}LT SEC JSR DKIO2 JSR STEPBP CPY BOOTL BNE WSECL ; PLA STA DEFAULT PLA STA STATE LDY ICDNOZ STY DUNIT LDA SECSIZ-1".},Y STA SECDAT NODOSX RTS ; ; TEST FOR FILE NAME = 'DOS.SYS' ; TSTDOS LDY #256-11 LDX DIRDSP TDLOOP LDA DIRBUF+5,X EOR DOS"/}SYS-256+11,Y BNE TDEXIT INX INY BNE TDLOOP TDEXIT LDX CURFCB TAY RTS ; DOSSYS DB 'DOS SYS' ; ; FIND AT LEAST ONE F"0}ILE MATCHING GIVEN NAME ; LFFILE JSR GETFNM ;EXTRACT FILE NAME FROM BUFFER STY TMP2 ;SAVE IT FOR -RENAME- JSR SFDIR ;FIND F"1}IRST MATCHING FILE IN DIR LDA #170 ;IF NONE, RETURN ERROR 170 BCS AEXIT ;ELSE, RETURN RTS ; ; RETURN ERROR IF FILE IS LOC"2}KED ; TSTLOK LDA #$20 ;CHECK BIT 5 JSR GETFLAG BEQ TDEXIT LDA #167 ;FILE LOCKED ERROR = 167 DB $AE ;SKIP 2 BYTES ; ; RET"3}URN WITH NO ERROR ; DONE LDA #1 ;NORMAL COMPLETION ; ; RETURN ERROR CODE IN ACC TO CIO (IN Y) ; AEXIT LDX STKPSV ;RESTORE ST"4}ACK POINTER TXS LDX CURFCB ;RESTORE IOCB OFFSET TO X-REG STA ICSTA,X ;RETURN STATUS IN IOCB TAY ;RETURN STATUS IN Y-REG "5} LDA DATBYT CPY #0 RTS ; ; RETURN HARDWARE ERRORS TO CIO ; HWERR ;;; lda #0 ;fix VTOC updating bug ;;; sta CURMAP ;do we"6} really want to do this????? ;;; sta CHGMAP ;[Bob Puff] LDA DSTATS BNE AEXIT ; ; RELEASE FCB AND RETURN NO-ERROR STATUS "7}; FREDON LDX CURFCB ; LDY BUFNO,X ;FINISHED WITH THE SECTOR BUFFER, RETURN IT BEQ DONE ;IF NONE ALLOCATED, SO WHAT! LDA #0"8} STA BUFNO,X STA BUFFLG-1,Y BEQ DONE ; ; TEST OR CLEAR A BIT IN THE FLAG BYTE ; GETFLAG LDY DIRDSP AND DIRBUF,Y RTS ; ;"9} SAVE FLAG BYTE AND WRITE BACK TO DIRECTORY ; SAVFLAG LDY DIRDSP STA DIRBUF,Y JMP WDIRBK LDY DIRDSP AND DIRBUF,Y RTS ; ; \ML }  X c0C)HCCH Mhhݩh `eCDiCD`  RyH&;}W   * 1H0芢@) Y0.Ș`p`#(PMRRm ms ai &<} 0  % @ / ՠ`d   0DDԝL  &=}N@  )?HI Y0`HIJH) * J j * hJJJ )HJ h i      Y&>}S S0 i`ϣ߳ϣ߳H J3xj2h  1 &?}|9 ӭ45(420 *(0241өX.`I0 `   *i)Lvw &@} *PE 5 L~(G   r s k rsrL/ (  2L(0d( L iE0O +)$IC  &A}  H {8 q p h   j n8no CDL CFl M  L i)Llk&B}2'")*F$F$F$F$F$ F )ШF/Șl]kpqС,L/A! i)Zlk@ ܬ/i&C})( ")")k$F$F$F F$/L /lF@jj(L~kle$$%8(k()`   L i)^>jf&D}  vrC s  ) vw5g   enfo olvw L@iL>j nL Jjjji&E}i p  qEhjlrs`L:$ȱ$@+[_#{   Խut! hi    &F} I F   n-C H H c h h 8 i   L   v      , 5 &G} `L ,/  /  񰮠? ѩ/   /Lj0?MoLn njMqLp 5&H}NklLLnLoMlNL "(+ըHH`b[9z}![  % !   /&I} .   FȑF! /GF \H"+0+* ! F tLnm: J~nF  *n+)5! n&J} (, n)1JJJinj(n*o I ,0  ci  oFnȱFo=n!&K}H m zI9  9  H8ZjF? @ , 8,0 ʩ0H mh   i q D &L}DmmFLvtu`*&!C*@h n 0 *^0`C t 0l$$%()()%&M}*&J%H,@hH YhH@,h *$% *8i8$(%)0hhH nh`() t 0H t 0 h`hhh&N}&JJ n(ll  L0  /qnoHH z9 9 H H  zI9  9  Nd mH &O} y8 o n  FnoLDu F E ~EhL/luF l0BF/lɜɛ׽hE&P} v  b ~FL FREE SECTORS C H) *Fh ):FȽ F FC IH'&Q} 0 d  i:Fȩ/F.l`CD/08HDICIHȰ/F`ȱ$>.+.i qȱ$:刄H !A&R}  qHȱ$*?ȝ 2. ? [_{ ,0-:) 0$:>WI  IТ,LH  0&S}hL  t u`C ?( 0(C.` E  R e! .ti S0N EE l &T}C )0')AY  )ע ? 0E088FG \on  (HhLcL3 iJ i Lqp&U} 0=rspnqopqlk`jZj0  j nLHFhȑFȽlFi0 h FFLnpvqwg&V}neofLn pq7  o0i 0 FJJh1FqȱFpȱFk`B!08`hEE l 8. eD}tui( |&W}ʩLb!)    'cȌaȌd b`aabH8 'hdaHcd8 cH hHH &X} \h ,hc` eHh I8ih(   ] ( (!` L\CJfCJfCJfCDfC` a  H&Y}II  INdh  `h  `n)8jHniPoiJIjFIjFIjh` a I 38  8H0 I &Z} ' H L8j Y  8j NdY  &I &I &IHeH.pIiq  ` HII/ &[}Ih8`h`L"non`no`!.莿 2Jjj }.m Ȉ!m FG` ɩL n&\}e  aH Hi04 \ Ȍ  8 i ] h h!`C Y.`&]}DOS SYS I  ` ݩ.C/`.mm٤C9 `C L`C Y.`$aTITLE'MYDOS UTILITIES PROGRAM'LISTI; Copyright 1984, Charles Marslett, Wordmark Systems;; Permission is granted by *_}the author for any use whatsoever of this; code, so long as this notice remains in the source code, and so; long as t*`}he source to this routine, however modified or unmodified,; is made available for a nominal cost.;; FMS ENTRY POINTS (*a}These should not be changed lightly!);; [Data];FILES=$0709;MAX NUMBER OF OPEN DISK FILESRAMDKU=$070A;LOC OF RAM*b} DISK DRIVE NODFUNIT=$070B;CURRENT DEFAULT UNIT NUMBERSECDAT=$070E;CURRENT I/O SECTOR SIZE (1=128, 2=256)DLINK=$*c}0711;OFFSET TO THE LINK FIELD IN EACH SECTORANDCD=$0734;OFFSET TO THE MASK EXTRACTING NEXT SECTOR BITSDKIO2=$0769*d};SECTOR I/O SUBROUTINE ENTRY POINTWRCMD=$0779;ADDRESS OF WRITE COMMAND BYTE (50/57)STATE=$07BE;CURRENT STATE OF DUP*e}/MEM/AUTORUNDKTYPE=$07C4;DISK SECTOR SIZE TABLE (8 BYTES)DRVDEF=$07CC;FLOPPY DRIVE CONFIGURATION TABLE (8-BYTES)MD*f}INIT=$07E0;MDOS initialization codeMAPBUF=$0908;512-BYTE BUFFER DOWN IN RESIDENT AREAHDTAB=$0B15;HARD DISK DRIV*g}E SIZE TABLE (0 = FLOPPY)WOTDCB=$0B25;PROTOTYPE DRIVE MODE SET TABLEMAPAGE=$0BBA;Page configuration table (64-bytes*h}) in MDOS;; [Code];CONFIGR=$0B2F;CONFIGURE DRIVE SUBROUTINE ENTRYRDCONF=$0B9A;READ CONFIGURATION STATE SUBROUTI*i}NE ENTRYSTEPBP=$0C5D;STEP TO THE NEXT BOOT SECTOR BUFFER ADDRESS;;; RAM disk I/O driver patch locations;RDKLMT=$*j}0C3A;Size of RAM diskRDAD1=$0C0D;Three locations where the control addressRDAD2=$0C19; needs to be storedRDAD3*k}=$0C4CNMLMAP=$0C14;Mask (1=part of mapping register);; Starting location for the MDUP code;ORIGIN=$1AE0;FIRST *l}BYTE AFTER MDOS(19CE - 4.00);; Patches linking MDUP into MDOS;ORG$70CDWRESEND;START OF FREE MEMORY (end of reside*m}nt stuff);ORG$085EJMPINIT;DUP INITIALIZATION ENTRY POINT;;; DEFINED VALUES;CR=$9BEOF=$88;OPEN=3GETRE*n}C=5GETCHR=7PUTCHR=11CLOSE=12RENAME=32DELETE=33LOCK=35UNLOCK=36FORMAT=254;; ROM AND RAM ADDRESSES*o};CARTST=$BFFA;AUDF1=$D200AUDCTL=$D208SKRES=$D20ASERIN=$D20DSEROUT=$D20DIRQEN=$D20ESKCTL=$D20FPBCTL*p}=$D303;FASCII=$D8E6IFP=$D9AAEDITRV=$E400DSKIO=$E453CIOV=$E456SIOV=$E459SETVBV=$E45CCIOINV=$E46E;*q}WARMST=$08DOSVEC=$0ADOSINI=$0CPOKMSK=$10BRKKEY=$11RAMLO=$1A;DUNITZ=$21DCMDZ=$22DBUFZ=$24DLENZ=$*r}28DAUX1Z=$2ADAUX2Z=$2BDAUX3Z=$2C;LMARGN=$52RMARGN=$53;FR0=$D4VECTOR=$D4HDBUF=$D6BUFAD=$DABUFLEN*s}=$DCFNPTR=$DETEMP=$E0TEMP2=$E1;INBUFF=$F3;VSERIN=$20AVIMIRQ=$216CDTMV3=$21CCDTMF3=$22ASHFLOK=$*t}2BERUNAD=$2E0INITAD=$2E2MEMTOP=$2E5MEMLO=$2E7DVSTAT=$2EA;SYSTEM STATUS BUFFER;DDEVIC=$300DUNIT=$301D*u}CMD=$302DSTAT=$303DBUF=$304DTIMEO=$306DLEN=$308DAUX=$30AHATABS=$31A;IOCB=$340ICDNO=$341ICMD=$34*v}2ISTAT=$343IBUF=$344ILEN=$348IAUX=$34A;ORGORIGIN;START OF MDUP;INCLUDED:MDUP1.ASM;RESIDENT CODE;MSBA*w}SE=*;START OF NON-RESIDENT CODE;INCLUDED:MDUP2.ASM;DATA AREAS AND THE MAIN MENU;INCLUDED:MDUP3.ASM;COPY, LIST, *x}CREATE, AND DELETE FUNCTIONS;INCLUDED:MDUP4.ASM;ENTIRE DISK FUNCS (FORMAT, COPY, WRT BOOT);INCLUDED:MDUP5.ASM;PROGR*y}AM LOAD AND SAVE FUNCTIONS;INCLUDED:MDUP6.ASM;CONFIGURATION FUNCTIONS;INCLUDED:MDUP7.ASM;MISC. SUBROUTINES;DUPEND*z}=*DUPLEN=DUPEND-DUPBASEMSLEN=DUPEND-MSBASEENDMENUSLN FUNCTIONS;INCLUDED:MDUP7.ASM;MISC. SUBROUTINES;DUPEND(?;; Resident MDUP code;; INITIALIZE MYDOS INTERFACE;INITLDA#HIGH[DUPENT]STADOSVEC+1LDA#LOW[DUPENT]STADOSVEC.|};LDA#0STAFNAMELDA#$20BITSTATEBNECKMDOS;IF WARM START CHECK FOR DUP LOADED;; COLD START CODE;STASTATE.}};SET MODE TO WARMSTARTLDX#$10JSRSOPEN;RUN AUTORUN.SYS FILEDB6DB39DWAFNBMICLOSXJSRCLOSXJMP(RUNAD);.~}; CLOSE IOCBS 10 AND 20;CLOSXJSRCLOS20CLOS10LDX#$10;CLOSE IOCB 10DB$2C;SKIP 2 BYTESCLOS20LDX#$20;CLOSE I.}OCB 20CLOS2LDA#CLOSE;CLOSE ANY IOCBSCMDSTAICMD,XJMPCIOV;DBUF10LDX#$10DEFBUFSTAIBUF,XTYASTAIBUF+1,XCKM.}DOSRTS;; Moved AUTORUN.SYS filename here so SUPERARC will not think; this is >=4.3 DOS;AFNDB'D1:AUTORUN.SYS',$9B;.}; OPEN FILE;; CALLING SEQUENCE:; JSR SOPEN; DB AUX; DB CMD; DW BUFFER ADDRESS;SOPENSECDB$A9;LDA .}#IMM OPCODE;; DO A READ/WRITE TYPE I/O REQUEST;; CALLING SEQUENCE:; JSR DOIO; DB IOCBNO; DW BUFFER LENGTH;.} DB CMD; DW BUFFER ADDRESS;DOIOCLCPLASTARAMLOPLASTARAMLO+1LDY#1LDA(RAMLO),YBCCDOIO1STAIAUX,.}XBCSXTRCBDOIO1TAXINYLDA(RAMLO),YSTAILEN,XINYLDA(RAMLO),YSTAILEN+1,XXTRCBINYLDA(RAMLO),YSTAICMD,X.}INYLDA(RAMLO),YSTAIBUF,XINYLDA(RAMLO),YSTAIBUF+1,XTYACLCADCRAMLOTAYLDA#0ADCRAMLO+1PHATYA.}PHAJMPCIOV;DO I/O REQUEST;; IF NO DUP.SYS, INCREMENT DRIVE NO.;RETRYOSINCDUPSYS+1LDADUPSYS+1AND#$0FCMP#9.}BCCRTYOSVBNEGOTO1CMPRAMDKUBEQRTYOSVGOTO1LDA#'1'STADUPSYS+1RTYOSVTAXLDADKTYPE-'1',XBEQRETRYOSBNENO.}WMS;; LOAD PROGRAM FUNCTION;LDFILEJSRLDMEMLDX#$10JSRTOVECT;LOAD PROGRAM OR GO TO ITDB$2C;SKIP THE LDY #1 I.}NSTRUCTION;;*************************************;; STANDARD EXIT POINT FOR PROGRAMS;;*******************************.}******;; RESTORE DOS/DUP INIT VECTOR;DUPENTLDY#1SAVERRSTYCBSAVBITSTATEBVSGODOSBPLNOWMSJSRCLOS10JSRSOP.}ENDB$08;WRITE MEM.SAV FILEDBOPENDWNMSAVBMINOWMSJSRDOIODB$10DWMSLENDBPUTCHRDWMSBASENOWMSJSRCLO.}S10JSRSOPEN;GET DUP.SYS INTO MEMORYDB$06DB39DWDUPSYSBMIRETRYOSLDADOSINISTAINISAVLDADOSINI+1STAIN.}ISAV+1GODOSJSRCLOSXJMPDOSOS;THEN START IT UP;; SAVE MEMORY SUBROUTINE: WRITE FILE BODY, INIT AND RUN VECTORS;WDR.}JSRLDMEM;LOAD MEM.SAV IF NEED BEWDR1LDX#$10;WRITE TEXT TO DISK FILEJSRCIOVWRERROBMISAVERRLDX#LOW[INITAD]JSR.}WRVECLDX#LOW[RUNAD]JSRWRVECBITSTATEBVSGODOSBVCNOWMS;WRVECLSRTEMP;WRITE THIS 6-BYTE VECTOR?BCCRTS2;IF.} NOT, JUST RETURNSTXVECTORLDAINITAD&$FF00,XSTAVECTOR+4INXLDAINITAD&$FF00,XSTAVECTOR+5LDA#HIGH[INITAD]ST.}AVECTOR+1STAVECTOR+3;(X,A)=MIDDLE WORDSTXVECTOR+2WR6BYTJSRDOIODB$10DW6DBPUTCHRDWVECTORBMIWRERRORTS.}2RTS;; RUN AT ADDRESS;TOVECTJMP(VECTOR) ;TO 'RUN AT' ADDRESS;; LOAD MEM.SAV IF NEED BE;LDMEMBITSTATE;LOAD MEM.S.}AV?BPLNOLDMS;LDX#$20JSRSOPENDB$04DBOPENDWNMSAVBMINOLDMS;JSRDOIODB$20DWMSLENDBGETCHRDWMS.}BASE;NOLDMSJMPCLOS20;NMSAVDB'D1:MEM.SAV',$9BECDB'E:'DUPSYSDB'D1:DUP.SYS',$9BOPTDB0DUPFLAGDB0;DUP RESIDEN.}T = $80INISAVDWMDINITCBSAVDB0;ERROR CODE FROM PROG EXECUTEDFNAMEDB0DS39;ALLOW FOR 40 CHAR DEF DIR;RESENDDS$.}300;ALLOW FOR THREE FILE BUFFERSDRIVERSDS$800;ALLOW 2K FOR RESIDENT CODEDS39;ALLOW FOR 40 CHAR DEF DIR;RESENDDS$,N;;======================================================================;==================================================2}====================;; START OF NONRESIDENT PORTION OF DUP.SYS;DATADS80;ALLOCATE BUFFER FOR BIT MAP, ETC.DELIMDS12}PAR2DS20;PAR* BUFFERS EXPANDED TO 80 BYTES FROM 32PAR3DS80; BY BOB PUFF, VERSION 4.5 (PAR2 WAS OK)BOOTBUFDS3842};SPACE FOR 3 BOOT SECTORSTEMPBUFDS128;TEMPORARY BUFFER FOR FILE OPEN DENSITY INIT.;;ORGDATA+512;USE THIS ORG ONLY I2}F ABOVE ALLOCS < 512 BYTES;UNNODS1PTRDS1PTRSAVDS1IPTRDS1IPSAVDS1CBYTEDS1SECTORDS2CSRCDS1CDESDS1C2}PYTYPDS1SWPFLGDS1RCNTDS1SECSIZDS2FNPTDS1FNPT2DS1PARDS80;REAL PARAMETER (LAST)DUPBASE=*DOSSYSDB'D12}:DOS.SYS',$9B;; CLOSE (BRUTALLY) ALL IOCBS AND REOPEN SCREEN;INITIOJSRCIOINVLDX#0JSRSOPEN;OPEN SCREEN AS IOCB #2}0DB$0CDBOPENDWECSTXCDTMV3;CLEAR TIMER #3STXCDTMV3+1LDY#1LDA#3STACDTMF3;SET TIMER NOT DONE FLAGJ2}SRSETVBVWAITIMLDACDTMF3;DONE?BNEWAITIM;NO, CONTINUE LOOPINGRTS;; DISK UTILITY PROGRAM ENTRY;DOSOSCLCCLD2}LDX#-3HATLPINXINXINXLDAHATABS,X;REINSTALL E: HANDLER TOCMP#'E';AVOID DELETING BASIC PROGRAMSBNEHATLP;ST2}ARTED UP BY AUTORUN.SYSLDA#LOW[EDITRV];"E:" HANDLER SIMULATORSSTAHATABS+1,XLDA#HIGH[EDITRV];REMOVED BY BOB PUFF IN2} 4.5 [Change for scripts]STAHATABS+2,XLDX#$FFSTXBRKKEY;ENABLE BREAK KEY;LDA#HIGH[MDINIT]STADOSINI+1LDA#2}LOW[MDINIT]STADOSINI;LDA#2STALMARGN;SET MARGINSLDA#39STARMARGNLDADUPFLAGORASTATEAND#$C1CMP#$802}BNENOSWFSTAWARMSTNOSWFLDA#$40ORASTATESTASTATE;ELSE, SAY IT WAS DONELDA#$80ORAPOKMSKSTAPOKMSK;ALLOW2} BREAK INTERRUPTSSTAIRQENJSRINITIO;CLOSE ALL FILES;LDASTATEAND#1BEQSHMENJSRERRXIT;MEM.SAV ERROR CAN NOW2} BE SHOWNDB'Error loading MEM.SAV or memory!',$9B,0;SHMENLDADFUNITORA#'0'STADEFAULTLDX#28LDY#8DKSLPLDA#2}' 'STAD1STAT-2,XSTAD1STAT-1,XSTAD1STAT,XSTAD1STAT+1,XCPYRAMDKUBNECKHCD;IF NOT RAM DISKLDA#'R'BNESETU2}NI;CKHCDLDAHDTAB+8-1,YBEQGENDCD;IF NOT HARD DISKLDA#'H'SETUNISTAD1STAT,XBNEDKUNIN;GENDCDLDADKTYPE-1,YB2}EQNXTDKSLSRA;DOUBLE DENSITY?LDA#'S'BCSDKSNGD;NO, SINGLELDA#'D';YES, DOUBLEDKSNGDSTAD1STAT,XLDADRVDEF-1,2}YLSRALDA#'-'BCCDKSSDLDA#'='DKSSDSTAD1STAT+1,XDKUNINTYAORA#'0'STAD1STAT-1,XNXTDKSDEXDEXDEXDEX2}DEYBNEDKSLPJSRPRINTDB$7D;CLEAR SCREENDB'MYDOS 4.51 -- copyright 1989,'DC'W','O','R','D','M','A','R','K';DB2}$9B,'DISKS: 'D1STATDB'1S 'DB'2S 'DB'3S 'DB'4S 'DB'5S 'DB'6S 'DB'7S 'DB'8S'DB'D: = D'DEFA2}ULTDB'1:',0LDA#LOW[FNAME]LDX#HIGH[FNAME]JSRPRTMSG;JSRPRINTDB$9B,$9BDB'1-8.Dir of D1:-D8: *. Dir of D:',$2}9BDB'A. Disk Directory K. Save Memory',$9BDB'B. Run Cartridge L. Load Memory',$9BDB'C. Copy File(s) M. Run at 2}Address',$9BDB'D. Delete File(s) N. Load MEM.SAV',$9BDB'E. Rename File(s) O. Change Config.',$9BDB'F. Lock File(s)2} P. Set Density',$9BDB'G. Unlock File(s) Q. Make Directory',$9BDB'H. Write DOS Files R. Pick Directory',$9BDB'I.2} Initialize Disk S. Set RAMdisk #',$9BDB'J. Duplicate Disk V. Set Verify Flag',$9BDB' ',$9B,0LDYCBSAVBPLMENUSL2}JSRCIOER1;IF LOAD ERROR, REPORT IT;; SELECT MENU FUNCTION;MENUSLLDX#$FFTXSINXSTXOPT;OPT=00 IF NO OPTIONSSTX2}SWPFLGSTXCBSAV;FOR DIR SCANS, SKIP NO EXTNS.JSRCLOSX;CLOSE IOCBs 10 AND 20LDX#$30JSRCLOS2;AND IOCB 30JSRPR2}INTDB'Select Item ('DC'R','E','T','U','R','N'DB' for menu):',0LDA#$40;FORCE UPPER CASESTASHFLOKORASTATES2}TASTATE;SAY DUP.SYS IN MEMORYJSRCHRGETCMP#$9BBNECKITEMJMPSHMEN;CKFDIRCMP#'1'BCCCKFDDJMPFASTDIRCKFDD2}CMP#'*'BNEBADITMJMPFASTDD;CKITEMCMP#'9'+1BCCCKFDIRCMP#'A'+NFUNCBCSBADITMSBC#'A'-1BCSITEMVBADITMLD2}A#NFUNCITEMVASLATAYLDADUPJT,YSTARAMLOLDADUPJT+1,YSTARAMLO+1JMPPRTMEN;GO TO MENU EXIT (WITH MESSAGE);T2}COMND=*UCOMND=*NSIDB'No such item!',$9B,0JMPMENUSL;DUPJTDWDIRLST-1,STCAR-1DWCPYFIL-1,DELFIL-1DWRENFIL-1,2}LKFIL-1DWULKFIL-1,WBOOT-1DWFMTDSK-1,DUPDSK-1DWSAVFIL-1,LDFIL-1DWBRUN-1,MEMSAV-1DWCONFGR-1,CHDISK-1DWMKDIR-12},SETDIR-1DWRAMDRV-1,TCOMND-1DWUCOMND-1,VERIFY-1NFUNC=[*-DUPJT]/2DWNSI-1EMSAV-1DWCONFGR-1,CHDISK-1DWMKDIR-10T;; * AND 1-8. FAST DIRECTORY LIST;FASTDDSTAPAR+2LDA#':'STAPAR+1BNEDOFDD;FASTDIRSTAPAR+1LDA#':'STAPAR6}+2DOFDDLDA#'*'STAPAR+3STAPAR+4LDA#'D'STAPARLDA#$9BSTAPAR+5;fix the 174 errors in menu [Bob Puff]STA6}CPYTYPSTADELIMBNEDODIRL;; A. DIRECTORY LIST;DIRLSTDB'Files to list, Destination?',$9B,0LDA#$9BSTACPYTYPJ6}SRGETFNJSRDEFPARDODIRLLDA#LOW[PAR]LDY#HIGH[PAR]JSRDBUF10LDX#$10STXCSRC;IOCB10 IS SOURCEJSROPDIR;OPE6}N IOCB10 AS DIRECTORY;LDA#HIGH[TEMPBUF+1]STABUFAD+1LDA#LOW[TEMPBUF+1]STABUFAD;LDA#38STABUFLENLDA#0ST6}ABUFLEN+1;LDX#$00;CDES=IOCB00LDADELIMBMICPY1FSPLDADELIMBMISGFCPYJSRGETFN2STYIBUF+$20STAIBUF+1+$206}SGFCPYLDX#$20LDA#GETCHRBNEDOCALL;CPY1FSPLDA#GETRECDOCALLSTXCDESJSRCOPYFJMPMENUSL;THEN RETURN TO CMD. L6}INE;BADRNJSRERRXITDB'Need new file name!',$9B,0CANTDVJSRERRXITDB'No drive or directories allowed in new name!',$6}9B,0;LKMSGDB'Lock ',0ULMSGDB'Unlock ',0DELMSGDB'Delete ',0;; D. DELETE FILE(S);DELFILDB'Delete what file?',$6}9B,0LDY#LOW[DELMSG]LDX#HIGH[DELMSG]LDA#DELETEBNEDOCMD;; F. LOCK FILES;LKFILDB'Lock which file?',$9B,0LDY6}#LOW[LKMSG]LDX#HIGH[LKMSG]LDA#LOCKBNEDOCMD;GET FILE NAME THEN LOCK IT;; G. UNLOCK FILES;ULKFILDB'Unlock whi6}ch file?',$9B,0LDY#LOW[ULMSG]LDX#HIGH[ULMSG]LDA#UNLOCK;DOCMDSTYSECSIZSTXSECSIZ+1PHAJSRGETFNJSRCKDSK6}LDXOPTCPX#'N';IF '/N' THEN DO IT THE EASY WAYBEQAFTCHKJSRPRINTDB'Answer ',$27,'Y',$27DB' or ',$27,'N',$27,$96}B,0PLAJSRSETSCN;RDFNJSRSCNDIRBCSDELX;IF END OF DIRECTORYLDASECSIZLDXSECSIZ+1JSRPRTMSGLDA#LOW[PAR]L6}DX#HIGH[PAR]JSRPRTMSGJSRPRINTDB'?',0JSRCHRGETCMP#'Y'BNENODELTLDX#$20JSRCIOCL;DELETE THE FILE THENN6}ODELTJMPRDFN;SMPLCMDPHAJSRGETFN;GET FILE NAMEJSRCKDSK;VERIFY A DISK FILEAFTCHKPLAISSCMDSTAICMD+$10LDX#$16}0JSRCIOCLLDAICMD+$10CMP#41BEQSETFNJDELXJMPMENUSLSETFNJJMPSETFNMJCANTDVJMPCANTDVJBADRNJMPBADRN;; E. 6} RENAME FILE(S);RENFILDB'File to rename, new name?',$9B,0JSRGETFNJSRCKDSKLDYPTRLDADELIMCMP#','BEQCKNAM26}CMP#' 'BNEJBADRNCKNAM2INYLDA(FNPTR),YCMP#':'BEQJCANTDVCMP#'>';check for sparta typeBEQJCANTDVCMP#6}'0'BCCDORENCMP#'z'+1BCCCKNAM2DORENLDA#RENAMEBNEISSCMD;; Q. MAKE A DIRECTORY;MKDIRDB'Full directory name6}?',$9B,0LDX#8STXIAUX+$10LDA#34;MAKE DIR. COMMANDJMPSMPLCMD;; R. SET DIRECTORY;SETDIRDB'Directory to be us6}ed as ',$27,'D:',$27,'?',$9B,0JSRGETFNJSRCKDSKLDYPTR;DRIVE OR NULL?CPY#4BCCCPYDNELDA#41JMPISSCMD;SETF6}NMLDX#0LDAPTREOR#4BEQZAPNAMLDY#1LDA#':'CMP(FNPTR),YBNEALLNEW;IF NOT SUBDIRECTORYFNDENDINXLDYFNAM6}E-1,XBNEFNDEND;END OF OLD DIR?STAFNAME-1,X;ALLNEWINYBEQCPYDNECMP(FNPTR),YBNEALLNEWDEX;POINT BACK AT ':6}'BEQCPY1ST;IF START, NO ':' TO PRESERVE;CPYNAMINXCPY1STINYLDA(FNPTR),YZAPNAMSTAFNAME,XBNECPYNAMJMPMENUSL6};CPYDNEJSRERRXITDB'Invalid directory!',$9B,0;; SINGLE FILE (DEVICE) COPY;TOERR1JMPCIOER1SGCOPYLDX#$10STXCS6}RC;SOURCE IS IOCB10JSRSOPENDB4;INPUTDBOPEN;OPEN FUNCTIONDWPAR;INPUT DEVICE NAMBMITOERR1JMPSGFCPY;; C.6} COPY FILES;DUPFIL=*CPYFILDB'File source, destination?',$9B,0LDA#' 'STAPAR3+2;DEFINE CHAR 3 OF DEVICE NAMELD6}A#$9BSTACPYTYPJSRGETFN;GET SOURCE FILE NAME;LDA#HIGH[DUPEND]STABUFAD+1LDA#LOW[DUPEND]STABUFAD;LDAMEM6}TOPSECSBC#LOW[DUPEND]STABUFLENLDAMEMTOP+1SBC#HIGH[DUPEND]STABUFLEN+1;JSRDEFPARLDADELIMBMISFNAMEJ6}SRGETFN2LDA#0SFNAMESTASWPFLGASLWARMSTLDAFNPTR+1STAIBUF+1+$20LDAFNPTRSTAIBUF+$20LDAPAR;DISK DEVICE?6}CMP#'D'BNESGCOPYLDA#LOW[PAR]LDY#HIGH[PAR]JSRDBUF10;LDA#'?'LDY#11QQQSTAPAR2-1,YDEYBNEQQQ;JSRC6}WFSDLDX#$10JSROPDIR;OPEN IOCB10 AS DIRECTORY;LDY#$FFCPSCL1INYLDA(FNPTR),YSTAPAR3,YBNECPSCL1CPSCL2DEY6}LDA(FNPTR),YCMP#'>';account for sparta typeBEQCPSCL3CMP#':'BNECPSCL2CPSCL3INYSTYFNPT2LDA(FNPTR),YBE6}QOPINP;LDX#0;SCAN -PAR- STARTING AT 1-ST BYTEMVMSKLDA(FNPTR),YBMIWCOPYB;1 FILESPEC COPY??CMP#'*'BEQMVNML6}CMP#'.'BCCWCOPYBBNEDOSTORLDA#' 'DEYDOSTORSTAPAR2,XINYMVNMLINXCPX#8BCCMVMSKSKPPRDINYMVEXTLDA(FNP6}TR),YBEQWCOPYBCMP#'.'BEQSKPPRD;IF A PERIOD, SKIP OVER ITCMP#'*'BEQOPINPCMP#' 'BEQWCOPYBCMP#','BEQ6}WCOPYBCMP#$9BBEQWCOPYBINYSAVBLKSTAPAR2,XINXCPX#11BCCMVEXTBCSOPINP;WCOPYJSRCWFSDOPINPJSRSCNDIRB6}ITCBYTEBMIOPINPBCCWCNEXTJMPMENUSL;WCOPYBLDA#' 'BNESAVBLKWCNEXTLDA#HIGH[PAR3]STAIBUF+$30+1LDA#LOW[PA6}R3]STAIBUF+$30;LDX#0LDYFNPT2WCNBLDLDAPAR2,XBEQTERMXCMP#'?'BNESTWCCLDADATA+2,XSTWCCSTAPAR3,YCMP6}#' 'BEQOVWRTCINYOVWRTCINXCPX#8BCCWCNBLDLDA#'.'STAPAR3,YINYWCEBLDLDAPAR2,XBEQTERMXCMP#'?'BNES6}TWCECLDADATA+2,XSTWCECSTAPAR3,YCMP#' 'BEQOVWRTEINYOVWRTEINXCPX#11BCCWCEBLDTERMXLDA#'.'CMPPAR3-1,Y6}BNENOTOVPDEYNOTOVPLDA#$9BLDXOPTCPX#'Q'BNENOQUERYLDA#'?'NOQUERYSTAPAR3,YLDA#0STAPAR3+1,Y;LDAC6}PYTYPBNEDOONELDA#LOW[PAR]LDX#HIGH[PAR]JSRPRTMSGJSRPRINTDB'-->',0LDA#LOW[PAR3]LDX#HIGH[PAR3]JSRPRTM6}SGLDAOPTCMP#'Q'BNEDOONEJSRCHRGETCMP#'Y'BNESKPCOPDOONELDAIAUX+5+$10STAIAUX+5+$20LDX#$20STXCSRC6}LDA#4STAIAUX,XLDA#LOW[PAR]LDY#HIGH[PAR]JSRDEFBUFLDA#OPENJSRSCMD;OPEN THE SOURCE FILEBMICPYERR;LDX6}#7CKFDOSLDACKDTST-1,X;File name = DOS.SYS?CMPPAR3+2,XBNENOXDOS;No, handle it normally thenDEXBNECKFDOS;; 6}COPYING DOS.SYS, SET UP FOR RENAME AND LOAD BOOT SECTORS;LDAPAR3+1STADOSRNM+1;Stash the unit number in the rename buf6}ferSTADOSSYS+1LDA#$60;Change destination name to diamond-OSSTAPAR3+3;CLC;READ BOOT SECTORSJSRDOBOOT;DO 6}BOOT I/O;; THIS REALLY COPIES THE FILE . . .;NOXDOSLDA#HIGH[PAR3]STAIBUF+$30+1LDA#LOW[PAR3]STAIBUF+$30;LDX6}#8;IOCB $30 set up for writingSTXIAUX+$30LDX#$30STXCDESLDA#GETCHRJSRCOPYF;COPY FILE;LDADOSRNM+1;NEED 6}TO RENAME DOS.SYS?BEQSKPCOP;; WRITE THE BOOT SECTORS OUT TO THE DESTINATION AND RENAME BACK TO DOS.SYS;JSRFIXUPDOS6};FIX BOOT SECTORS, WRITE THEM, AND RENAME FILELDA#0;CLEAR RENAME FLAGSTADOSRNM+1;SKPCOPLDACPYTYPBNETOEXITJMP6}WCOPYTOEXITJMPMENUSLCPYERRJMPCIOER1ILELDA#0;CLEAR RENAME FLAGSTADOSRNM+1;SKPCOPLDACPYTYPBNETOEXITJMP4+;; I. FORMAT A DISK;FMTDSKDB'Disk to FORMAT:',0JSRGETDN;GET DRIVE NUMBER OR NAMEJSRDEFPAR;LDA#HIGH[PAR]STA:}IBUF+$10+1LDA#LOW[PAR]STAIBUF+$10;LDY#1LDA(FNPTR),YSTAFMTDVN;; MAKE SURE ABOUT DRIVE NUMBER;JSRPRINT:}DB'(Press [A] for Enhanced Dns)',$9BDB'Type [Y] to Format Drive 'FMTDVNDB'0:',0;JSRCHRGETCMP#'A'BEQFMT1050:}EOR#'Y'BNEWBXDOFMTSTAIAUX+$10LDA#0LDXOPT;REAL FORMAT?CPX#'N'BNERELFMTRORARELFMTSTAIAUX+1+$10;LDA:}#FORMATSTAICMD+$10LDX#$10JSRCIOV;DO FORMAT OF DISKBPLWBXWBERRJMPCIOER1;IF ERROR, SAY SO!WBXDEYBEQALFMT:}DJSRERRXITDC'W','A','R','N','I','N','G'DB': Bad sectors on disk!',$9B,0ALFMTDJMPMENUSL;FMT1050LDA#1BNEDOFM:}T;; H. WRITE DOS/DUP TO DISK;DUPFNMDB'D1:DUP.SYS',$9BWBOOTDB'Drive to write DOS files to?',0JSRGETDNLDADUPSYS:}+1PHALDA#'1'STADUPSYS+1STANMSAV+1LDY#1LDA(FNPTR),YCMP#':'BNECANWBLDADEFAULTCANWBSTADOSSYS+1STA:}DUPFNM+1;DEY;SET UP INITIAL VALUES OF PARMS.STYOPTLDA#$80STASTATE;LDA#LOW[DOSSYS]LDY#HIGH[DOSSYS]JSR:}DBUF10LDA#8;OPEN OUTPUT=WRITE DOS.SYSSTAIAUX+$10JSRANYDEN;OPEN AND WRITE DOS.SYS (ANY DENSITY)JSRCLOS10PLAS:}TANMSAV+1STADUPSYS+1;; **** WRITE DUP.SYS HERE ****;LDY#$70LDA#LOW[DUPBASE]LDX#HIGH[DUPBASE]JSRD2B8A;LD:}A#HIGH[DUPFNM]STAIBUF+$10+1LDA#LOW[DUPFNM]STAIBUF+$10LDA#HIGH[DUPEND-1]STAHDBUF+3LDA#LOW[DUPEND-1]STAHD:}BUF+2LDA#HIGH[DUPLEN]STAHDBUF+5LDA#LOW[DUPLEN]STAHDBUF+4;LDA#0STATEMP;CLEAR 'RUN' FLAGJMPWRDUP;WRIT:}E DUP.SYS;; J. DUPLICATE A DISK;DUPDSKDB'Source, Destination (Sectors)?',$9B,0JSRGETDNLDY#1LDA(FNPTR),YAND;}#$0F;GET DRIVE NUMBERSTACSRCSTACDESLDADELIM;IF SINGLE DRIVE DUP.CMP#'('BEQSETSSZ;GO SET SECTOR SIZEJSRGE;}TDN2;ELSE, GET SECOND DRIVE NAMELDY#1LDA(FNPTR),YAND#$0FSTACDESCMPCSRC;SAME DRIVE?BNESETSSZ;YES, SINGLE ;}DRIVE DUP.LDX#$9BSTXSWPFLGSETSSZTAXLDYCSRCLDASWPFLGORA#$40;SET DUP-DISK FLAGSTASWPFLGBMIDODKDPJSRP;}RINTDB'Insert both disks, type 'DC'R','E','T','U','R','N'DB0JSRCHRGET;DODKDPJSRCWFSDLDACSRC;POINT TO SOUR;}CE DRIVEJSRGETDEN;IDENTIFY DENSITY OF SOURCE DISKETTELDYCDES;ELSE, TWO DRIVE DUP.LDXCSRCLDADKTYPE-1,XCMPDKTY;}PE-1,YBEQSAMESTYUNNOJSRSETDENLDYCDESLDXCSRCLDADKTYPE-1,XCMPDKTYPE-1,YBEQSAMEJSRERRXITDB'Drives ;}not compatible!',$9B,0SAMEASLWARMSTLSRASTASECSIZ+1RORASTASECSIZ;SET SECTOR SIZE (128 OR 256)STXDUNIT;READ;} SOURCE VTOC;LDADELIMPHALDA#$FFTAXINIBMPSTADATA+128,XSTADATA+256,XDEXBNEINIBMPPLA;BOOT COPY?CMP#;}'('BEQBLDVTOC;YES, BUILD IMAGINARY VTOCCMP#$9BBEQRDVTOC;NO, DOS COPYOOPSJSRERRXIT;ELSE, ERRORDB'Invalid opt; }ions!',$9B,0BLDVTOCJSRGETNUMCPY#'-'BNEOOPSSTADATA+3STXDATA+4JSRGETNUMCPY#')'BNEOOPSSTADATA+1STX; }DATA+2LDY#0STYPTRSTYDATA+6STYDATA+5;LDA#HIGH[DATA+10]STABUFAD+1LDA#LOW[DATA+10]STABUFAD;LDA#$FE; }D26BBLDXDATA+6CPXDATA+4BNED26CBLDXDATA+5CPXDATA+3BCSD26D2D26CBSECROLAJSRNXTSCTBNED26BB;D26D2LD; }XDATA+2CPXDATA+6BCCD26EABNED26E4LDXDATA+1CPXDATA+5BCCD26EAD26E4ASLAJSRNXTSCTBNED26D2;D26EASEC; }ROLABCSD26EASTA(BUFAD),Y;RDVTOCSECLDAMEMTOPSBCSECSIZSTABUFLENLDAMEMTOP+1SBCSECSIZ+1STABUFLEN+1;;}LDABUFLENCMP#LOW[DUPEND]LDABUFLEN+1SBC#HIGH[DUPEND]BCSENUFJSRERRXITDB'Not enough memory!',$9B,0;NXTSCT;}BCSD272ESTA(BUFAD),YLDA#$FEINCBUFADBNED272EINCBUFAD+1D272EINCDATA+5BNED2736INCDATA+6D2736RTS;EN;}UFLDAPTRBEQSKRDVT;IF POS, SKIP READING VTOCLDA#LOW[360]LDX#HIGH[360]STADAUXSTXDAUX+1LDA#LOW[DATA]LDX#;}HIGH[DATA]STADBUFSTXDBUF+1JSRRSEC1BPLNOERFDJMPCIOER1NOERFDCLCLDADATA+1ADC#12;ADD IN THE BOOT, MAP AN;}D DIR SECTORSSTADATA+1BCCCK2BIT;THEN TAKE CARE OF SECOND BIT MAP IF NEC.INCDATA+2;ELSE, BUMP UPPER BYTECK2BITL;}DADATACMP#4BCCSKRDVT;IF SINGLE SECTOR, SKIP READING SECONDINCDATA+1CLCLDADBUFADCDLENSTADBUFLDADBUF+;}1ADCDLEN+1STADBUF+1DECDAUXJSRRSEC1;SKRDVTLDA#0STADAUX+1LDA#1STADAUXLDADATA+10STACBYTELDA#8;}STAIPTRLDA#HIGH[DATA+10]STAVECTOR+1LDA#LOW[DATA+10]STAVECTOR;DORDLDAVECTORSTAPTRSAVLDAVECTOR+1STAP;}TRLDAIPTRSTAIPSAVLDACBYTESTACBSAVLDADAUXSTASECTORLDADAUX+1STASECTOR+1LDA#0STACPYTYP;SET OPERAT;}ION TO 'READ'LRSLDA#HIGH[DUPEND]STADBUF+1LDA#LOW[DUPEND]STADBUFLRS1ASLCBYTEDECIPTRBNECBITINCVECTORB;}NEPAGE1INCVECTOR+1PAGE1LDY#0LDA(VECTOR),YSTACBYTELDX#8STXIPTRCBITBITCBYTEBMIASPTLDACPYTYPASLA;};CY=0, READ; CY=1, WRITELDACSRCBCCRSECIN;ACC=DRIVE #LDACDESRSECINJSRSECTIO;READ OR WRITEIODCLCLDADBUFADC;}SECSIZSTADBUFLDADBUF+1ADCSECSIZ+1STADBUF+1ASPTLDADAUXCMPDATA+1LDADAUX+1SBCDATA+2BCCASPN;LDACP;}YTYP;END OF DRIVEBPLSTDD2;IF READ, DO WRITEJMPMENUSL;IF WRITE, THEN DONE!;ASPNINCDAUXBNEASPXINCDAUX+1ASPX;}LDABUFLEN;ELSE, END OF THE BUFFER?CMPDBUFLDABUFLEN+1SBCDBUF+1BCSLRS1;NO, GET NEXT SECTOR;LDACPYTYPBPLS;}TDD2;IF WRITE, DO NEXT READJSRCWFSDJMPDORD;STDD2BITSWPFLGBPLCKFORMJSRPRINTIDDDB'Insert DESTINATION disk, ;}press 'DC'R','E','T','U','R','N'DB0JSRCHRGETCKFORMLDA#'N'CMPOPTBEQNOFORMSTAOPTLDX#$20;IF FORMAT REQ.;}, DO ITLDA#LOW[DOSSYS]LDY#HIGH[DOSSYS]JSRDEFBUFLDA#FORMATSTAICMD+$20LDACDESORA#'0';CONVERT DRIVE NO. TO; } ASCIISTADOSSYS+1JSRCIOCLNOFORMDECCPYTYP;THEN, MAKE A WRITELDAPTRSAVSTAVECTORLDAPTRSTAVECTOR+1LDASEC;!}TORSTADAUXLDASECTOR+1STADAUX+1LDAIPSAVSTAIPTRLDACBSAVSTACBYTEJMPLRSRLDAPTRSTAVECTOR+1LDASEC8\;; K. SAVE FILE COMMAND;SAVFILDB'SAVE:filename,start,end(,init(,run))',$9B,0JSRGETFNSTYIBUF+$10STAIBUF+1+$10?#}LDAOPTPHAJSRGETNO2CPX#HIGH[DUPEND]LDY#$70BCSDSLMFGLDY#$60;FORCE MEM.SAV TO MEMORY BEFORE SAVING IMAGEDSLM?$}FGJSRD2B8AJSRGETNO2STAHDBUF+2STXHDBUF+3SECSBCHDBUFSTAHDBUF+4TXASBCHDBUF+1BPLADDOKJSRERRXITDB?%}'Invalid START-END range!',$9B,0ADDOKSTAHDBUF+5INCHDBUF+4BNEINCOKINCHDBUF+5INCOKLDA#0CPY#CRBEQNINTADJS?&}RGETNO2STAINITADSTXINITAD+1ORAINITAD+1BEQNINTADLDA#1;SET 'GOT INIT' FLAGNINTADSTATEMPCPY#CRBEQNRUNA?'}DJSRGETNO2STARUNADSTXRUNAD+1ORARUNAD+1BEQNRUNADINCTEMPINCTEMP;SET 'GOT RUN' FLAGNRUNADPLAWRDUPLDY#?(}0STYOPTDEYSTYVECTORSTYVECTOR+1;; OPEN THE PROGRAM FILE;LDY#8CMP#'A'BNEOPTOK1DECOPTINYOPTOK1STY?)}IAUX+$10LDX#$10JSRANYDEN;OPEN FILE 'OUTPUT/ANY DENSITY'BMIKIOERRLDAOPTBEQFULHDR;IF NO 'APPEND'JSRDOIO;WR?*}ITE SHORT HEADERDB$10DW4DBPUTCHRDWVECTOR+2BMIKIOERRKEXITLDAHDBUF+4STAILEN+$10LDAHDBUF+5STAILEN+1+$?+}10LDAHDBUFSTAIBUF+$10LDAHDBUF+1STAIBUF+1+$10BITSTATEBMIKMSAVJMPWDR1KMSAVJMPWDR;FULHDRJSRWR6BYTB?,}PLKEXITKIOERRJMPCIOER1;D2B8ASTAHDBUFSTXHDBUF+1STYSTATERTS;; N. LOAD PROGRAM INTO MEM.SAV;MEMSAVDB'Load?-} MEM.SAV from what file?',$9B,0LDASTATEORA#$80;TURN ON MEM.SAV FLAGBMILOADITTOMENJMPMENUSL;; L. LOAD USER FI?.}LE FUNCTION;BDLDFLLDY#180BLOWUPJMPCIOER1;LDFILDB'Load from what file?',$9B,0LDASTATEAND#$7F;TURN OFF MEM.S?/}AV FLAGLOADITSTASTATEJSRGETFNSTYIBUF+$10STAIBUF+1+$10LDXDATA+3;JUST A CR?BEQTOMENLDA#4STAIAUX+$10?0}LDX#$10JSRANYDENJSRDOIODB$10DW2DBGETCHRDWDATABMIBLOWUPLDADATAANDDATA+1CMP#$FFBNEBDLDFLLDA?1}DATA+3BEQTOMENLDAOPTEOR#'N'BEQGOTNLDA#0STAWARMSTLDA#3GOTNEOR#7STAIAUX+$10LDA#39STAICMD+$10?2}LDA#LOW[CIOV]LDX#HIGH[CIOV]BNEBRUN1;; B. RUN CARTRIDGE;STCARDB0LDA$BFFDEOR#$AASTA$BFFDCMP$BFFDBN?3}ENORAM;IF ADDRESS SPACE IS NOT RAMEOR#$AASTA$BFFD;IF RAM, NO CARTRIDGENOCARTJSRERRXITDB'NO CARTRIDGE!',$9B,0?4};NORAMLDX$BFFCBNENOCART;IF NOT ATARI CARTRIDGELDACARTSTLDXCARTST+1BRUN1STAVECTORSTXVECTOR+1LDAINISAV?5}STADOSINILDAINISAV+1STADOSINI+1LDASTATEAND#$BFSTASTATEJMPLDFILE;; M. RUN AT ADDRESS;BRUNDB'Run fro?6}m what address?',0JSRGETLINLDA(FNPTR),YCMP#$9B;NO ADDRESS?BEQBRUN2;IF SO, ABORTJSRGETNO2CPY#$9BBNEBRUN?7}2LDY#0STYWARMSTBEQBRUN1BRUN2JSRERRXITDB'Address must be 1-4 hex digits!',$9B,0JSRGETNO2CPY#$9BBNEBRUN<^;; P. CHANGE DISK FORMAT;CHDISKDB'Drive, new density:',0JSRGETDN;GET DRIVE NO.LDADELIMCMP#$9B;DRIVE NUMBER OC9}NLY?BNECHDSK2;IF SO, CHANGE DEFAULTBADPCMDJSRERRXITDB'Drive unchanged.',$9B,0CHDSK2LDYPTRLDA(FNPTR),YTAXLC:}DY#1LDA(FNPTR),YCMP#'9'BCSBADPCMDSBC#'1'-1BCCBADPCMDTAYINYSTYUNNOLDA#1CPX#'S'BEQTOSGLCPX#'C;}D'BNEBADPCMDASLATOSGLSTADKTYPE-1,YJSRDOFSINJMPSHMEN;THEN SHOW CHANGED MENU;; O. CONFIGURE SYSTEM OR DISK DC<}RIVE;CKBANKSSEI;was CHKBANKSLDY#0;This is BOB code...STY$D40E;uncommented asSTY$D20E;per usual...LDA$C=}D301PHA;We validate the memory mapping abilityLDX#$FF;of the box we are running in?CKBL1STY$D301;[Don't reallyC>} understand this, butLDA$4000; thats OK, for now, ChasM]STAMAPBUF,Y;[Bob Puff]STX$4000TXAstaMAPBUF+256,YINC?}YBNECKBL1DEXSTX$D301STX0STX$4000STX$8000STX$C000LDX#0CKBL2sty$D301lda$4000cmp#$FFbneCKBNOC@}Tinxstx$4000txaCKBNOTstaMAPBUF+256,YinybneCKBL2stxRDKLMT;ldx#1CKBL8txaldy#$FFCKBL6cmpMAPBUF+256CA},YbeqCKBFOdeycpy#$FFbneCKBL6;;;;;;nop;was a DEYCKBL9sty$D301ldaMAPBUF,Ysta$4000dey cpy#$FFbneCB}CKBL9plasta$D301lda#$C0sta$D40Elda$10sta$D20Ecli rts;CKBFOtya staMAPAGE-1,Xinx cpx#65bccCCC}KBL8ldy#$FEbneCKBL9;SPCPORTJSRPRINT;Handle non-standard port addressesDB'Control Address(HEX)?',0JSRGETLINCD}JSRGETNO2TAYORAVECTOR+1BNESAVADRbeqRAMDSU;If < $0100, ask again!jmpSAVADR;Stash the specified address;;CE} Test for RAMdisk, and configure it;GETRDKjsrPRINTdb'RAM disk present?',0jsrCHRGETldy#$FFcmp#'N'bneRAMDSUCF}jmpNOFAST;RAMDSUjsrPRINTdb'[A]xlon, [X]E or [C]ustom RAMdisk?',0jsrCHRGETcmp#'C'beqSPCPORTldy#LOW[$D301CG}]ldx#HIGH[$D301]cmp#'A'bneSAVADRldy#LOW[$CFFF]ldx#HIGH[$CFFF]cmp#'X'bneRAMDSU;Keep on trying!SAVADRCH}styRDAD1styRDAD2styRDAD3stxRDAD1+1stxRDAD2+1stxRDAD3+1cmp#'X'bneOKP0jsrCKBANKSldaRDKLMTbneOKP1CI}jsrPRINTdb'No extra memory available!',$9B,0ldy#0jmpNOFASTOKP0jmpRMDSU2;OKP1ldx#0stxNMLMAPstxFR0+1CJ}aslaaslarolFR0+1aslarolFR0+1aslastaFR0rolFR0+1jsrIFPjsrFASCIIjsrPRINTdb'Use default config CK}for ',0ldy#0OKP2lda(INBUFF),YbmiOKP3inybneOKP2OKP3and#$7Fsta(INBUFF),Yinylda#0sta(INBUFF),YldaCL}INBUFFldxINBUFF+1jsrPRTMSGjsrPRINTdb'K?',0jsrCHRGETcmp#'N'beqRMDSU2jmpDVNOQ;RMDSU2JSRPRINTDB'SCM}ize(K)?',0JSRGETLINJSRGETNUMLSRVECTOR+1RORALSRVECTOR+1RORALSRVECTOR+1RORALSRVECTOR+1RORABNESCN}AVRDSLDA#4SAVRDSSTARDKLMT;GETSEQNJSRPRINTDB'Page sequence?',0JSRGETLINJSRGETNO2CPY#CRBNEFSNUMBEQRCO}SEQDVNOQJSRPRINTDB'RAM disk drive no?',0GETRDRVJSRCHRGETLDY#9;ASSUME 9CMP#'0'BCCNOFAST;IF DIGIT, CHANGECP} RAMDISK CODECMP#'9'BCSNOFASTAND#$0FTAYNOFASTSTYRAMDKU;SET RAMDISK UNIT NO.RTS;RSEQTAYLDXPGMAP,YSTXCQ}NMLMAPCPY#3BCSCPAXSQLDASQMAP,YLDX#0CPY0ROLAROLAPHAROLAROLAROLAAND#$0CTAYCPY1LDASQTAB,YCR}STAMAPAGE,XINXINYTXAAND#3BNECPY1PLACPX#16BNECPY0CPSEQLDASQTAB,XSTAMAPAGE,XINXCPX#64BNECPSCS}EQBEQDVNOQ;CPAXSQLDX#64AXSQLDEXTXASTAMAPAGE,XBNEAXSQLBEQDVNOQ;FSNUMLDX#0PHATXAFSNCLSTADATA+256CT},XINXBNEFSNCLPLAFSLP1STXUNNOCPY#CRBEQTONMLSTADATA+256-64,XTAXLDADATA+256,XBNEBADSEQDECDATA+256,CU}XLDYPTRLDA(FNPTR),YCMP#CRBNEFSLP4JSRGETLINFSLP4JSRGETNO2LDXUNNOINXCPX#64BNEFSLP1TONMLCPXRDKLMCV}TBNEWRONGSTANMLMAPUPDLP1DEXLDADATA+256-64,XSTAMAPAGE,XTXABNEUPDLP1JMPDVNOQBADSEQJSRPRINTDB'DuplicCW}ated sequence number!',$9B,0JMPGETSEQN;WRONGJSRPRINTDB'Wrong number of entries!',$9B,0JMPGETSEQN;PGMAPDB$00,CX}$00,$00,$FF,$FF,$FFSQMAPDB$9C,$D8,$4B,$FF,$FF,$00;SQTABDB$A3,$A7,$AB,$AFDB$C3,$C7,$CB,$CFDB$E3,$E7,$EB,$EFDB$CY}83,$87,$8B,$8F;DB$A1,$A5,$A9,$ADDB$C1,$C5,$C9,$CDDB$E1,$E5,$E9,$EDDB$81,$85,$89,$8D;DB$A2,$A6,$AA,$AEDB$CCZ}2,$C6,$CA,$CEDB$E2,$E6,$EA,$EEDB$82,$86,$8A,$8E;DB$A0,$A4,$A8,$ACDB$C0,$C4,$C8,$CCDB$E0,$E4,$E8,$ECDB$80,$C[}84,$88,$8C;CONSYSJSRPRINTDB'Verify WRITEs?',0JSRDOVRFYJSRPRINTDB'Number of File Buffers?',0JSRGETLINJSRC\}GETNUMTAXBEQSKPFCTCMP#17BCSSKPFCTSTAFILES;SET NUMBER OF FILES (0-16)SKPFCTJSRGETRDKJSRMDINIT;REINITIALIC]}ZE DOS3JMPDOSOS;ZAPDRVLDA#$D2DB$2C;SKIP 2 BYTESSET52LDA#$52LDYUNNOSTADRVDEF-1,YJSRCLRHDSCONXITJMPMEC^}NUSL;CONFGRDB'Drive number or 'DC'R','E','T','U','R','N'DB':',0JSRCHRGET;GET DRIVE NUMBERCMP#$9B;IF RETURN,C_} GO TO SYSTEM CONFIGURATIONBNECONDRIVJMPCONSYSCONDRIVCMP#'9'BCCSAVDVNTOBADPJMPBADPCMDSAVDVNSBC#'1'-1BCCTC`}OBADPTAYINYSTYUNNOLDA#0;THEN ZERO CONFIGURATION BYTESTADRVDEF-1,Y;JSRPRINTDB'Remove drive?',0JSRCHRGECa}TCMP#'Y'BEQZAPDRVJSRPRINTDB'Is drive configurable?',0JSRCHRGETCMP#'Y';IF NO, SET TO $52 AND EXITBNESET5Cb}2JSRPRINTDB'High capacity drive?',0JSRCHRGETCMP#'Y'BEQGETHCDJSRPRINTDB'Is drive double sided?',0JSRCHCc}RGETCMP#'Y'BNESETSSLDA#$01JSRORDRVSETSSJSRPRINTDB'Tracks/side?',0JSRGETLINJSRGETNUMCMP#35BEQSETCd}35TAYLDA#$30CPY#77BEQSETTKSLDA#$20CPY#80BEQSETTKSLDA#$10CPY#40BNESETSSSETTKSJSRORDRVSET35JSCe}RPRINTDB'Step rate?',0JSRCHRGETCMP#'4'BCSSET35SBC#'0'-1BCCSET35ASLAJSRORDRVJSRCLRHDSJMPMENUSLCf};GETHCDJSRPRINTDB'Drive size (in sectors)?',0JSRGETLINJSRGETNUMCPX#0BEQGETHCD;INVALID SIZEPHALDYUNNOCg}LDA#$12STADRVDEF-1,YLDA#2STADKTYPE-1,YPLAJSRSETHDSJMPMENUSL;; S. Set RAMdisk Drive Number;RAMDRVDBCh}'RAM disk drive no?',0JSRGETRDRVJMPMENUSL;; V. Set Verify Flag ON or OFF;VERIFYDB'Verify WRITEs?',0JSRDOVRFYCi}JMPMENUSL;DOVRFYJSRCHRGETLDX#$57;ASSUME YES!CMP#'N'BNEDOVFYLDX#$50DOVFYSTXWRCMD;SAVE THE WRITE COMMANCj}D IN DOSRTS;ORDRVLDYUNNOORADRVDEF-1,YSTADRVDEF-1,YRTS;CLRHDSLDX#0TXASETHDSLDYUNNOSTAHDTAB-1,YTXACk}STAHDTAB+8-1,YJMPDOFSINOORADRVDEF-1,YSTADRVDEF-1,YRTS;CLRHDSLDX#0TXASETHDSLDYUNNOSTAHDTAB-1,YTXA@;; PUT A SINGLE CHARACTER ON THE SCREEN;CHRPUTLDX#PUTCHRSTXICMDLDX#0STXILENSTXILEN+1JMPCIOV;; PUT MESSAGm}GE TO THE SCREEN;PRTMSGSTARAMLOSTXRAMLO+1PRTNXTLDX#0LDA(RAMLO,X)BEQPRTXITJSRCHRPUTPRTENTINCRAMLOBNEPGn}RTNXTINCRAMLO+1BNEPRTNXTPRTXITRTS;; PRINT AN IN-LINE STRING;PRINTPLASTARAMLOPLASTARAMLO+1PRTMENJSRPRTGo}ENTLDARAMLO+1PHALDARAMLOPHARTS;; READ A BYTE FROM THE KEYBOARD;CHRGETJSRXE424;FETCH THE BYTECPY#0BMIGp}KILLRD;IF BREAK OR EOF, ABORT COMMANDCMP#'z'+1;> LOWER CASE Z?BCSNCHGCSCMP#'a';< LOWER CASE A?BCCNCHGCSSBC#Gq}$20;CONVERT TO UPPER CASENCHGCSPHA;SAVE ITCMP#$9BBEQCHRXIT;IF EOL, ECHO ITJSRCHRPUT;ELSE, ECHO ITLDA#$9B;Gr}FOLLOWED BY EOLCHRXITJSRCHRPUTPLA;RESTORE FOR PROGRAMRTS;THEN EXITKILLRDJSRCHRPUT;MOVE TO NEXT LINE ANDJMPMGs}ENUSL;EXIT WITHOUT RETURN TO COMMAND;XE424ldx#$70;Get a character from the keyboard [Bob Puff]jsrCLOS2;Close IOCBGt} $70;jsrSOPEN;Open IOCB #$70 for keyboard inputdb4dbOPENdwKDEV;jsrDOIO;get a characterdb$70;IOCB $7Gu}0dw0;Buffer length (0=return 1 byte in ACC)dbGETCHRdw0;Buffer address (unused)pha;save the character for a Gv}sec.;ldx#$70jsrCLOS2;Close IOCB $70 again;pla;get character backrts;that's all, folks!;KDEVdb'K:',$9BGw};Keyboard handler addr.;CLOSE7jsrDOIO;close IOCB #7db$70dw0db$0Cdw0 rts ;; RAW SECTOR READ/WRITE FUNCTIOGx}NS;RSEC1LDACSRCRSEC2CLC;SECTIOSTADUNITLDXSECSIZ+1INXSTXSECDATBOOT1LDX#3STXRCNTCLD1LDXSECDATPHPGy}JSRDKIO2BPLDRTSCMP#$80BEQTOERR2PLPDECRCNTBPLCLD1PHPTOERR2PLPJMPCIOER1;DRTSPLPRTS;; BOOT SECTGz}OR I/O ROUTINE (USED TO COPY DOS.SYS);DOBOOTLDA#HIGH[BOOTBUF-128]STADBUF+1LDA#LOW[BOOTBUF-128]STADBUF;INITIALG{}IZE THE BUFFER ADDRESSLDA#0;START WITH SECTOR #1STADAUX;JSRBOOTIO;JSRBOOTIO;2 CALLS, THEN FALL THROUGH (TRAG|}NSFER 3 SECTORS);BOOTIOJSRSTEPBPINYSTYDAUXJMPBOOT1;JUMP ALWAYS!;; CHECK FOR 2-COLUMN DIRECTORY LIST;CLEARIG}}TLDXCSRCLDAICMD,XCMP#GETCHRBEQCLERXITLDATEMPBUF+1CMP#'0'BCSEOFEXITLDYILEN,XCPY#20BCCSHFNLDECIG~}LEN,XLDY#-24SFTSIZLDATEMPBUF+39-256,YSTATEMPBUF+39-1-256,YINYBNESFTSIZSHFNLLDATOGGLEOR#$BBSTATOGGLSTG}ATEMPBUF+19CLERXITRTS;EOFEXITLDA#$9BCMPTOGGLBEQCLERXITDECIBUF,XINCILEN,XSTATEMPBUFRTS;TOGGLDB$9BG};; COPY ONE FILE (AS MANY MEMORY LOADS AS NEEDED);COPYFLLDXCSRCLDAILEN,XORAILEN+1,XBEQNOOUTPLDASWPFLGBPLWG}RFILELDA#LOW[IDD]LDX#HIGH[IDD]JSRPRTMSGJSRCHRGETLDXCDESJSRRESETWRFILELDXCDESBNEDOWRFIJSRCLEARITLG}DX#$00DOWRFILDAIOCB,X;OPEN?BPLPUTOUT;YES, WRITE NEXT BLOCK;LDXOPTLDA#8CPX#'A';APPEND?BNEDOPO1LDA#9G}DOPO1LDXCDESSTAIAUX,XJSRANYDEN;OPEN THE OUTPUT FILEBMITOCIOR;PUTOUTLDXCDESLDYCSRCLDAILEN,YSTAILEN,XG}LDAILEN+1,YSTAILEN+1,XLDAIBUF,YSTAIBUF,XLDAIBUF+1,YSTAIBUF+1,XLDA#PUTCHRSTAICMD,XJSRCIOCL;WRITE NG}EXT BLOCK OF DATANOOUTPLDXCSRCLDAISTAT,X;EOF?CMP#$88BEQCPYXITLDASWPFLGBPLRECOPYLDA#LOW[ISD]LDX#HIGHG}[ISD]JSRPRTMSGJSRCHRGETLDXCSRCJSRRESETJMPRECOPY;COPYFLDXCSRCSTAICMD,XLDA#$9BSTATOGGLRECOPYLDXCG}SRCLDA#0STATEMPBUF+22LDABUFADLDYBUFAD+1JSRDEFBUFLDABUFLENSTAILEN,XLDABUFLEN+1STAILEN+1,XJSRCIOVG};READ DIRECTORY DATABPLTOCPFLCPY#$88;END OF FILE?BNETOCIOR;IF ERROR, ABORTTOCPFLJMPCOPYFLTOCIORJMPCIOER1G};CPYXITLDXCDESBEQNOTCLJSRCLOS2NOTCLLDXCSRCJMPCLOS2;; FIX UP DOS COPY OPERATION;DLKMSK=*-1DB$03,$FFG}DLKLOC=*-1DB$7D,$FDFIXUPDOSLDXSECDAT;STASH SECTOR SIZE INFOSTXSECDAT-$0700+BOOTBUFLDADLKLOC,X;STASH LINK LOG}CATION IN THE SECTORSTXDLINK-$0700+BOOTBUFLDY#$14NOTRITELDA#$29;AND COMMAND CODEFNDANDINYBMINOANDCMPBOOTBUG}F-1,YBNEFNDANDLDABOOTBUF,YCMP#$03BEQANDOKCMP#$FFBNENOTRITEANDOKLDADLKMSK,X;STASH THE MASK FOR 10 BIT ORG} 16 BIT LINKSSTABOOTBUF,Y;NOANDSEC;WRITE BOOT SECTORSJSRDOBOOT;DO BOOT I/O;LDX#$30;USE THE DESTINATION IOG}CB ($30 IS ALWAYS OK)JSRSOPEN;IF COPYING DOS.SYS (REALLY 'DIAMOND'OS.SYS)DB0;AUXDBDELETE;CMDDWDOSSYS;FILEG}NAME -- DELETE EXISTING DOS.SYS;LDX#$30;USE THE DESTINATION IOCB ($30 IS ALWAYS OK)JSRSOPENDB0DBRENAMEDWDOSG}RNM;MAKE NEW ONERTS;;;SCAN DIRECTORY AND BUILD THE NEXT FILE NAME;EXIT WITH NOT-EQUAL IF AT END;SCNDIRLDA#LOW[DG}ATA]LDY#HIGH[DATA]JSRDBUF10LDA#GETRECSTAICMD+$10LDA#32STAILEN+$10LDA#0STAILEN+1+$10STACBYTE;ASSUG}ME NOT A DIRECTORYJSRCIOCL;READ A FILE NAMELDADATA+1CMP#':'BCSNOTDIRCMP#'0'BCSSCNDXNOTDIRBEQGOTSPCLDG}ADATA+10CMPCBSAVBNENOTSYSGOTSPCDECCBYTENOTSYSLDXFNPTLDY#2;MDN1LDADATA,YCMP#' 'BEQMDN2STAPAR,XIG}NXINYCPY#10BCCMDN1;MDN2LDA#'.'STAPAR,XINXLDY#10MDN3LDADATA,YCMP#' 'BEQMDN4STAPAR,XINYINXG}CPY#13BCCMDN3MDN4LDA#'.'CMPPAR-1,XBNEMDN5DEXMDN5LDA#0;TERMINATE FILE NAMESTAPAR,XCLCSCNDXRTS;GEG}TLINLDA#LOW[DATA+3]STAFNPTRSTAIBUFLDA#HIGH[DATA+3]STAFNPTR+1STAIBUF+1LDA#GETRECSTAICMDLDX#1STXILG}EN+1DEXSTXILENLDY#0STYPTR;CIOCLJSRCIOVTYABMICIOER1RTSCIOER1STYFR0LDA#0STAFR0+1JSRIFPJSRFG}ASCIILDY#0LDA(INBUFF),YSTACIERCINYLDA(INBUFF),YSTACIERC+1INYLDA(INBUFF),YAND#$7FSTACIERC+2JSREG}RRXITDB'Error -- 'CIERCDB'000',$9B,0;HEXDEFLDYDATA+3CPY#$9BBNEGETNO2RTS;GETNUMCLCDB$24;SKIP SINGLE BG}YTE;GETNO2SECRORTEMP2JSRNXTFLDSTYVECTORSTYVECTOR+1GETNDLDA(FNPTR),YINYCMP#'F'+1;IS IT A DIGITBCSGEG}TNDESBC#'0'-1;NOTE THAT CY=0BCCGETND1CMP#10;0-9?BITTEMP2BPLGOT10BCCGOT1;YES, SHIFT INTO NUMBERCMP#17G};A-F?BCSGOT16;YES, HANDLE ITGETND1SECADC#'0'-1GETNDESTYPTRTAYLDAVECTORLDXVECTOR+1RTS;GOT10BCSGETND1G}PHAASLVECTORROLVECTOR+1LDAVECTORLDXVECTOR+1ASLVECTORROLVECTOR+1ASLVECTORROLVECTOR+1CLCADCVECTOG}RSTAVECTORPLAPHPCLC;[Bob Puff]ADCVECTORSTAVECTORTXAADCVECTOR+1PLPADC#0STAVECTOR+1JMPGETND;G}GOT16SBC#7GOT1ASLVECTORROLVECTOR+1ASLVECTORROLVECTOR+1ASLVECTORROLVECTOR+1ASLVECTORROLVECTOR+1ORG}AVECTORSTAVECTORJMPGETND;; GETFN -- READ A LINE, GET FILENAME FROM IT;GETFNLDA#0STADOSRNM+1JSRGETLINBEQG}WCTSTL;; GETFN2 -- EXTRACT A FILENAME FROM A LINE ALREADY READ IN; X IS THE OFFSET IN THE BUFFER;GETFN2JSRNXG}TFLDWCTSTLLDA(FNPTR),YINYCMP#'?'BEQSETWC;IF ? OR * FOUND,CMP#'*'BNECKEOFN;SET FLAG, FIND FIRST MATCHSETWCG}LDA#0STACPYTYPBEQWCTSTL;CKEOFNCMP#$9B;IF EOL, CONTINUE WIT SINGLE FILEBEQFNSETCMP#'.'BEQWCTSTLCMP#'/G}'BCCFNSETBNEWCTSTLSLSHLPLDA(FNPTR),YCMP#'S'BNENCPSYSSTACBSAVBEQSAVEDNCPSYSCMP#'X'BNENOTSWPLDA#$G}80STASWPFLGBMISAVEDNOTSWPSTAOPT;SAVE OPTION CODESAVEDDEYLDA#0STA(FNPTR),YINYINYLDA(FNPTR),YINYCMG}P#'/'BEQSLSHLPCMP#'.'BCCFNSETCMP#$9BBEQFNSETDEY;FNSETSTYPTR;SAVE POINTER TO SECOND ARG.DEYLDA(FNPG}TR),YSTADELIMLDA#0STA(FNPTR),YTAYLDA(FNPTR),YCMP#'0'BCCDEFDRVCMP#':'BEQDEFDRVINYBCSLKFCOLTAXG}LDA#':'CMP(FNPTR),YBEQDBEFORDEYSTA(FNPTR),YTXABNEDGTCOD;LKFCOLLDA(FNPTR),Y ;SCAN FOR DRIVE IDBEQDEFG}DRVCMP#':'BEQDEVINC;DEVICE INCLUDEDINYLDA(FNPTR),YCMP#':'BEQDEVINC;DEFDRVLDA#':'DGTCODJSRDECFNPDBEFG}ORLDA#'D'JSRDECFNPDEVINCLDYFNPTRLDAFNPTR+1RTS;NXTFLDCLCLDAPTR;MOVE INDEX TO AADCFNPTRSTAFNPTRLDAG}#0TAYADCFNPTR+1STAFNPTR+1RTS;DECFNPLDYFNPTRBNEDECFP1DECFNPTR+1DECFP1DECFNPTRINCPTRLDY#0STA(FNG}PTR),YGETDN1RTS;;REQUIRE A DISK DRIVE (NO FILE SPECIFICATION);GETDN2JSRGETFN2;GET NEXT FILE NAMEJMPGETDNE;THEN G}CHECK FOR DRIVE ONLYGETDNJSRGETFNGETDNESTYIBUF+$10STAIBUF+1+$10LDY#$FFGETDNLINYTAXLDA(FNPTR),YBNEGETDNLG}CPX#':';ANY FILE NAME INCLUDED?BEQGETDN1;NO, THEN RETURNJSRERRXITDB'File name not allowed!',$9B,0;; UPDATE DEG}NSITY OF DISK IN DRIVE;GETDENCMP#':'BNEGTDEN2LDADFUNITGTDEN2AND#$0F;MAKE UNIT BINARYLDX#0STXDAUX+1INXG}STXDAUXLDX#LOW[TEMPBUF]STXDBUFLDX#HIGH[TEMPBUF]STXDBUF+1JSRRSEC2BMIGETDN3JMPRDCONF;;REQUIRE A DISK FG}ILE NAME, SAVING THE POINTER IN IOCB10;CKDSKSTYIBUF+$10STAIBUF+1+$10LDY#0LDA(FNPTR),YCMP#'D'BEQGETDN3JSRG}ERRXITDB'Not a disk file!',$9B,0;; WAIT FOR SOURCE DISK;CWFSDLDASWPFLGBMIWFSDGETDN3RTS;IF NO WAIT REQUIREDWG}FSDJSRPRINTISDDB'Insert SOURCE disk, press 'DC'R','E','T','U','R','N'DB0JSRCHRGETBITSWPFLGBVSGETDN3;IF IG}N DUP-DISKLDXCSRC;RESETLDYIOCB+1,XSTYUNNOLDAIAUX+5,XBEQNOCHGCMP#3BCSNOCHGSETDENSTADKTYPE-1,YLDX#1G}5SAVMAPLDAMAPBUF,XSTASAXMAP,XDEXBPLSAVMAPJSRDOFSINLDX#15RSTMAPLDASAXMAP,XSTAMAPBUF,XDEXBPLRSTMAPG};NOCHGRTS;SAXMAPDB0,0,0,0,0,0,0,0DB0,0,0,0,0,0,0,0;; RECONFIGURE DENSITY OR CONFIGURATION;DOFSINLDX#9DOFLOPG}LDAWOTDCB,XSTADUNIT+1,XDEXBPLDOFLOPLDX#$31STXDUNIT-1LDXUNNOSTXDUNIT;TELL SIO DRIVE TO CONFIGURELDYDG}KTYPE-1,X;GET DENSITY/SECTOR SIZELDADRVDEF-1,X;GET DRIVE SPECIFICATIONJMPCONFIGR;GO CONFIGURE DRIVE;;SET UP PAR G}AND IOCB10 FOR A DIRECTORY SCAN (MULTI-FILE ACTIVITY);SETSCNSTAICMD+$20LDA#LOW[PAR]LDX#HIGH[PAR]STAIBUF+$20STXG}IBUF+1+$20JSRSETPTRLDX#$10;OPEN IOCB10 AS DIRECTORY;OPDIRLDA#6;OPEN IOCB AS DIRECTORYSTAIAUX,X;; OPEN A FILG}E INDEPENDENT OF DRIVE DENSITY;ANYDENLDA#0STAIAUX+1,XSTAIAUX+5,XLDA#OPENJSRSCMDBPLSAVDENJMPCIOER1;SAVG}DENLDYDUNITLDADKTYPE-1,YSTAIAUX+5,XRTS;; SET UP 'PAR' FOR A WILD CARD COPY;DEFPARJSRSETPTRLDA(FNPTR),YBNG}EDEFPXSTACPYTYPSTAPAR+2,YLDA#'*'STAPAR,YSTAPAR+1,Ylda#$9B;termination!!!staPAR+2,Y;[Bob Puff]DEFPXG}RTS;SETPTRLDY#$FFSETLP1INYLDA(FNPTR),YSTAPAR,YBNESETLP1SETLP2DEYLDAPAR,Ycmp#'>';account for sparta G}typebeqSETLP3;[Bob Puff]CMP#':'BNESETLP2SETLP3INYSTYFNPTRTS;; REPORT ERROR, THEN RETURN TO MENU;ERRXITG}PLASTARAMLOPLASTARAMLO+1JSRPRTENT;WRITE ERROR MESSAGE FOLLOWING 'JSR ERRXIT'JMPMENUSL;THEN RETURN TO MENU;DG}OSRNMDB'D',0,':',$60,'OS.SYS,'CKDTSTDB'DOS.SYS',0OR MESSAGE FOLLOWING 'JSR ERRXIT'JMPMENUSL;THEN RETURN TO MENU;DD7  }^`L U ,- 1'"0 l , BLVDE`D1:AUTORUN.SYS8hhJ ȱK}HȱIȱBȱDȱEeeHHLVFF)  1F*  ,T,p-  180 3k }'  1'EK}0 R S L* U V0  ,pPF Խ٩Յ׆ 3 0`l, 180 3 k}'LD1:MEM.SK}AVE:D1:DUP.SYS*+D1:DOS.SYS n 1 C* \*`آE R'SQ )ɀK}@  *)% DError loading MEM.SAV or memory!  0+ ++++ R H+JSK}D+J-=+ 0+ʏ+,д J?}MYDOS 4.51 -- copyright 1989,˛DISKS: 1S 2S 3S 4S 5S 6S 7S 8SD: = D1:K}U 4? J?1-8.Dir of D1:-D8: *. Dir of D:A. Disk Directory K. Save MemoryB. Run Cartridge L. Load MemoryC. Copy File(sK}) M. Run at AddressD. Delete F,-ile(s) N. Load MEM.SAVE. Rename File(s) O. Change Config.F. Lock File(s) P. Set K}DensityG. Unlock File(s) Q. Make DirectoryH. Write DOS Files R. Pick DirectoryI. Initialize Disk S. Set RAMdisk #J. DuplK}icate Disk V. Set Verify Flag T -.AP=*T 0  J?Select Item ( for menu):@  Z?ɛL:+1K}LJ.*L@.:W@ ..LP?No such item!L-k.907/0R/l/32&4c78I9f8=9F0f0>-->-E*:D*D*:E**K}F*G*DC*H*<*'(Files to list, Destinat.~/ion?<* B DC* :* rD)۩ک&ܩݢ'0'0 Bde K};* @L- DNeed new file name! DNo drive or directories allowed in new name!Lock Unlock Delete Delete what file?K}0/!4Lock which file?"/#Unlock which file?/z0(/$?*@*H B CPNJ J?Answer 'Y' or 'N'h `D LA;?*@* 4?K}C* 4? J?? Z?Y AL/H B ChR AR)L-L0L.L.File to rename, new name? B C3*', ȱ:>0{K} ПFull directory name?Z"L/Directory to be used{0v1 as 'D:'? B C3*5)L/3*I: TTK}ȱޝUL- DInvalid directory!LA:* 1C*0L.File source, destination? '<* BD۩ڭ8ܭD DK}'0 B=*ߍeލdC*DЍC* ? ' C rDȱޙ'w1r2>:ȌB*C0J* .B 'ȱ/.K}* #,ɛȝ' ߰ C LA,7*0L- 'utB*'3?'' .'Ƚ'?''  .'K}PQ?''<*#C* 4? J?-->' 4?PQ Z?Yc_o :s2n3*JC*  0PD''D*`' ?K}'utz0;* @D AD<*L1L-LADisk to FORMAT: YC D*UCTލ:3 J?(Press [A] for Enhanced Dns)TyK}pe [Y] to Format Drive 0: Z?AKIYZPNj[R VLA" Do3j4: Bad sectors on disk!L-еD1:DUP.SYK}SDrive to write DOS files to? YCFH1F9:+*3P* Z wD h9Fp* _83UTD٩ةK}۩UکL 8Source, Destination (Sectors)? YC):*;*'( SC);*:k4f5*=*:*=* @=*0% J?Insert both diK}sks, type Z? C:* C;*:*/2* D;*:* DDrives not compatible!J@*j?*'H'}(h(K}y DInvalid options! B-䍀'' B)׍~''3*'''۩ک''''8g5b6* 5''~'' 58*K}8?*ܭ@*ݥD, DNot enough memory! ک''`3*Mh  }' ?LA~'i ~''}'K}~'mm   ?  '7*5*'թԥԍ4*Ս3*5*6*7*T 8* 9*c6^7<*D7*5*K}ՠԍ7*5*,7*0"<* :*;* ?m?*m@* ~' '<*"L-  <* CLA6,=*, J?Insert DESTK}INATION disk, press Z?NPP * b;* 0* A<*4*ԭ3*խ8* 9* 6*5*T_7Z87*Lh6SAVE:filename,stK}art,end(,init(,run)) BTUPH BDp` _8 B؆8օڊ DInvalid START-END range!۩ B K} B hPԄՠAPȌZ wD04P* 3 0$ڍXۍY֍T׍U,0LL [8V9LAֆ׌`LoaK}d MEM.SAV from what file? 0#L-LALoad from what file?) BTU'̩Z wD 3}'0}'-~'а'PK}INIZ'RV0II DNO CARTRIDGE!ԆխR S )LRun from whatW9R: address?K} Aɛ B DAddress must be 1-4 hex digits!Drive, new density: YC'ɛ DDrive unchanged.3*ު9K}0٨Ȍ2*SD  ADL:+xԌҭHӭ@ @ ʎӆ@ӭ@@ :  #S:N;K} @hөԥX` A̠ J?Control Address(HEX)? A Bc$L; J?RAM disk present? Z?NL< J?[A]xlon,K} [X]E or [C]ustom RAMdisk? Z?CAXÌ  L   M X, 9: ' J?No extra memory available!L JG=B>?Number of File Buffers? A B  : L*,R2* ?L-Drive number or : Z?ɛL0=9L90K}Ȍ2* J?Remove drive? Z?Y J?Is drive configurable? Z?YЂ J?High capacity drive? Z?Yy J?Is drive double sided?K} Z?Y ? J?TC>>?racks/side? A B#0M P( ? J?Step rate? Z?4/ ? ?L- J?Drive size (in sectorsK})? A BH2*h ?L-RAM disk drive no? L- Z?WNPy`2*`2*  LAD BK}HILV ??:@$?`hh A?HH` ?0{a Hɛ $? $?h` $?L-p  1? 3pHp h`K: K}3p `:*@*>* iɀ(>*(LA(`'  ? ? ] Ȍ L?:*B')0!HH((9K}@I9@)`9@DH)`;@6A:*HI`=*6 4? Z?;* D;* ?@PA ;*J wD0x;*:*HHIIDDK}EE B A:*CɈK=*٢C 4? Z?:* DL@:*B9@:*)ڤ ܝHݝI VL:@LA;* :*L}@( K}AC()01(2(A2(8 7A2B?0 1!*0 1 D`}' R XY7* A~':0H'T7*A*}' K}C* .C* }' C* .B*ʩC*`ލD'ߍEBIʎH3* V0`ԩ ؠBȱBȱ)B DErK}ror -- 000'`$8f 3CԄձG/3B.C $<68i/3*Ԧ`H&եԦ&&eԅheԅԊe(iL*B&&K}&&ԅL*BD A 3C?*<*ɛ:./2STX=*0Pȱ/.ɛ3*ލ'ި0K}#:Ȱ :ފ :ȱ: : CCD CC/C*Dޥ`3*eޅީe߅`3*` BL\C BTUȪ: DFile namK}e not allowed!: )  ) ?0+L TUD DNot a disk file!=*0` J?Insert SOURCE disk, press K} Z?,=*pӮ:*A2*O  1D AD1D+DD ` % 12*L/ bC*de K}DJKO LAO` D<*E**C*D*E*`ȱޙC*C*>:ȌA*`hh A?L-D:`OS.SYS,DOS.SYSK}-JKO LAO` D<*E**C*D*E*`ȱޙC*C*>:ȌA*`hh A?L-D:`OS.SYS,DOS.SYSHin the MDOSx files; but the code that takes care of MEM.SAV and loading DUP.SYS is in the file MDUP1.ASM. Because O}the DOS is split between two files, you must take note of the last byte the assembly of MDOS.ASM produced, and placO}e this address in the "ORIGIN = xxxx" statement in the MDUP.ASM segment, or the possibility of both files running into eL}