,ML  X c0C)HCCH Mhhݩh `eCDiCD`  RWH   * 1H0芢@) Y0.Ș`i#(PMRR\ \b Pgi 0 @ $ ࠮UY   0DDԝLHiN@ )?HI   Y0`HIJH)* J j *  hJJJ)HJ   h i    YS S0 i`ϣ߳ϣ߳H J3xj2h)1 |9 ӭ45(420 *(0241өX.`  J *^)Lkl  v*PE 5 LN(G = gh ` ghgL ( = LG(0d( L ^E0O +)$IC H K8 f e h |  _ 8cd CDLI CFa M  LG J^)La`2'")*F$F$F$F$F$ 5 )ШF/Șa]`efС,LI/A! L^)Za`@ ܬ/^)(")")`$F$F$F 5$/L /aF@__(LN`ae$$%8(`()` J 0 =LG J^)^>_f t FgCh) |kl5\   Zc[d ?akl LI@^Le>_ >L vJjjj^^ e fE]_agh`LI:$ȱ$@+[_#{ 0  Խji! ai 0 = I   U C H h  ˰ 0  F  | Le =  ,  S `LI ,/ 0 v/ | Ơ? ѩ/  S /L_0?MdLc >_MfLe N`aLGLIcLdMaNLG J"(+ըHH`Q R !   $ . FȑF! /GF \H"+0+* ! F s LIcm: J~cTF1F  *c+)5! c (, c)1JJJc(c*d I ,0  Xi Y dF4 5 ,8,0 ʩ0H =h     i D UD bbFLIvij`*&!ߍ*@h ] 0 ^0`ߍ c 0l$$%()()%*&J%H,@hH hH@,h $% 8i8$(%)0hhH ]h`() c 0H c 0 h`hhh&JJ ]( ll  LI0 |/qcdHH 99 H H  I9 9 NY =H  I8 d c  |FcdL HII/ Ih8`h`Lcdc`cd`u F E KE]LG/auF a0BF/aɜɛ׽]E F  |W  KFL FREE SECTORS CH) *Fh ):FȽ F FCIH' H0 1h0d  i:Fȩ/F.a`CD/08HDICIHȰ/F`ȱ$>.+.i ȱ$:刄H !A T Hȱ$*?ȝ 2. ? [_{ ,0-:) 0$:>WI  IТ,LIH  0hLd v i j`C ?(  0(C.` E 5! .ii  c0N EE < PC)0')AY)ע ? 0E088FG \dc  (HhLcL3 ^J ^ L}fe 0=ghecfdefa``_Z_0  _ >LXHFhȑFȽaF^0 ] FFL>ekfl\cZd[L> ef7  ?0^ 0 FJJ]1FfȱFeȱF``B!08`]EE < 8. 5D}iji( LʩLXW!)   XȌVȌY W`VVWH8 hYaHXY8 XH hHH \h hX` 5Hh I8ih( l ( l(!`L\CJfCJfCJfCDfC` |V  HII  INYh `h`c)8jHciPdijIjFIjFIjh` |V I38 8H0 I  ' H LI8jY8j NYY &I &I &IHeH.eIif  `!.莼 2Jjj }.b Ȉ!b FG` ɩLI z  e H^04 \ Ȍ  8 i h !`I0 `C Y0.`DOS SYS I  ` vݩ.C/`WV.b۩bѤC9`CLU R  ,F0(BߝDEI V0 : , BLVDE`D1:*AR18hhJ ȱHȱIȱBȱDȱEeeHHLV)  1*  ,,p-  0  &  '0   L)l, 0  &LD1:MEM.SAVE:D1:DUP.SYS,pLsLF#Խ٩Յ׆  L"C`David R. Eichel rel.ver.1/1/90OS.SYShh =L4,  VLT :C :CST)CD2:DOS.SYS n  * \*`آ R'S )ɀ@  _))% CError loading MEM.SAV or memory!  0* l*m*n*o* R Hn*JSDn*J-=o* 0m*ʈд =}MYDOS 4.53/3- Copyright 1988,˛Disks 1S- 2D- 4R D: = D1:ˢ = =1-8.Dir of D1:-D8: *. Dir of D:A. Disk Directory K. Save MemoryB. Run Cartridge L. Load MemoryC. Copy File(s) M. Run at AddressD. Delete File(s) N. Load MEM.SAVE. Rename File(s) O. Change Config.F. Lock File(s) P. Set DensityG. Unlock File(s) Q. Make DirectoryH. Write DOS Files R. Pick DirectoryI. Initialize Disk S. Set RAMdisk #J. Duplicate Disk V. Set Verify Flag  @( 0  =Select Item ( for menu):@  =ɛL)1L,*L,:W@ ,,L=No such item!L4,-0{ ПFull directory name?Z"L.Directory to be used as 'D:'? @ A(5)L.(I: ȱޝL4, CInvalid directory!L@( )0Lp-File source, destination? '( @C۩ڭ8邅ܭC BC'0 @(ߍeލd)DЍ) ? C' B Bȱޙ':>Ȍ)C0J* .B D'ȱ/.* #,ɛȝD' ߰ B ?,(0L4, 'ut)D'3?&' .'ȽD'?&'  .ٓ'Q?''(#) = =-->' =Q =YR_o (J)  0?Cݖ''BU)`''utz0( "?(L0L4,L@nDisk to FORMAT: A B)UTލ1 =(Press for Enhanced Dns)Type to Format Drive 2: =AIYZNj[R VL@L4,D2:DUP.SYSDrive to write DOS files to? AH1:*U)2T) Z B hpT) J<2UTC٩ة۩.کL;Source, Destination (Sectors)? A)((C'( A)((((( @(0% =Insert both disks, type = B ( A((/( OB(( CDrives not compatible!J)j)C'Hs''h(ɛy CInvalid options! Y@-&& Y@)׍&&(&&&۩ک&&&&8* C4&&&& C48*8)ܭ)ݥɂC, ! CNot enough memory! ک&&`(Mh  & >L@&i &&&&mm   >  &((&թԥԍ(Ս(((( ( ((C((ՠԍ((,(0"( (( >"m)m) & &("L4,  ( BL4,(, =Insert DESTINATION disk, press =N T) b( 0U) @((ԭ(խ( ( (((L4Drive, new density: AC'ɛ CDrive unchanged.(ު#90٨Ȍ(SD  |BL)xԌҭHӭ@@ ʎӆ@ӭ@@ :  $ӹ@hөԥX` Aˠ =RAM disk present? =NL;8 =xlon or E type RAMdisk? =Aό $ L   M   A1| H6: ' =No extra memory available!L;8L7 & & & =Use default config for 0)ȩ = =K? =NL8 =Size(K)? ? Y@FjFjFjFj: =Page sequence? ? [@o* =RAM disk %drive no? = 09) `9 -9**H***) 9 Ȋ)h9 @@ H'h(#''/'(ɛ ? [@(@: 3 ʽ' L8 =Duplicated sequence number!L7 =Wrong number of entries!L7K&큅쀄 =Verify WRITEs? &; =Number of File Buffers? ? Y@  6 L),R( ?;L4,Drive number or : =ɛL[99L60Ȍ( =Remove drive? =Y =Is drive configurabl'e? =YЂ =High capacity drive? =Yy =Is drive double sided? =Y 5; =Tracks/side? ? Y@#0M P( 5; =Step rate? =4/ 5; ?;L4, =Drive size (in sectors)? ? Y@H(h B;L4,RAM disk drive no? +8L4,Verify (WRITEs? &;L4, =WNPp`(`(  L|BSAVE:filename,start,end(,init(,run)) @TUH [@Cp` J< [@؆8օڊ CInvalid START-END range!۩ [@  [@ hԄՠAȌZ B04)*  0$ڍXۍY֍T׍U,0LCLC SCL@ֆ׌`Load MEM.SAV from what file? 0#L4,L@Load from what file?) @TU&̩Z B &0&-&а&INIZ'RV0II CNO CARTRIDGE!*Ԇխ  )LIRun from what address? ?ɛ [@ CAddress must be 1-4 hex digits! BHILV =`hh =HH` =0{a Hɛ = =h` =L4, > = pHH >hh`K: p `(+()( i ɀ((L@(`(BD(0>HH''>I>U>I>ɛ(ɛ (>(`͓>DH(`(HI`(v5 = =( @B( 3>@A (J B0}((HHIIDDEE B @(CɈP,(#B = =( @BL2?(B>>((ڤ ܝHݝI VL>L@(" B !B T)  B(L& R XY( @&:0H&()& ) .) & ) .)ʩ)`ލD&ߍEB-IʎH( V0`ԩ ؠL@ȱM@ȱ)N@ CError -- 000&`$8f nAԄձG/ $<68i/(Ԧ`H&եԦ&&eԅheԅԊe(iLe@&&&&ԅLe@B ? nA?*(ɛ:./2SX.(0ȱ/.ɛ(ލC'ި0#:Ȱ :ފ :ȱ: : ~AD ~Aޥ`(eޅީe߅`(` @LA @TUȪ: CFile name not allowed!: )  s( >0+L TUD CNot a disk/ file!(0` =Insert SOURCE disk, press =,(pӮ(A(O lB |BlB`1(L$ b)de BJKO L@O` B()*)))`ȱޙ)):>Ȍ)`D:`OS.0SYS,DOS.SYShh =L4,  VLT :C :C,pLsLF#Խ٩Յ׆  L"C`David R. Eichel rel.ver.1/1/90L$ b)de BJKO L@O` B()*)))`ȱޙ)):>Ȍ)`D:`OS.05ڢ 5 ~2 `kةE  42B 4  0444 2kF$k0 42 G4 224L10 B V 38<4546CT4UՍd4eL0ʍT4Ud4e Q3+t24u{zr0 V0 2 Q3L1 30L3D  8n Lu180݂݀.݃`݄݄݆݇8~٩֩׭6CשD.ץ8 42 F45 `l ȩ1ȩ:ȱM@DиUвȩPЫ6C3Нȩ.ЖȩSЏم٠8$PpE Ȣ@ML1 BLV8hhՠԐJ ȱԝHȱԝIȱԝBȱԝDȱԝEeԨeHH Vhh`@I@ȍI@ӈ@@-44I@@ȍό@Iψ@@`t5urxy0 V80a450Z50 4 5 .4 50 4 444T4Ud4e`JB V0s JKB V0]d4e4B80 column formatMDOS .M65 DOS source part 1MDOS1 .M65 " " part 2MDOS2 .M65 " " part 3MDOS3 .M65 " " part 4MDUP .M65 DUP source part 1MDUP1 .M65 " " part 2MDUP2 .M65 " " part 3MDUP3 .M65 " ? " part 4CONTENTS. What you're reading.* This file is a Diskcomm file ofthe new DOS, DUP and RAMBOOT program(RB6C.AR0). Use Bob Puff's DiskCommunicator v.3.2 to uncompact thefile into a bootable single densitydisk. It has been set@ up for use witha standard 64K XE RAMdisk as drive 4.To configue it to another size ortype of RAMdisk, just follow theinstructions in the documentationcontained in the origional v.4.50release package.ble single densitydisk. It has been setЛ MyDOS version 4.53/3 changes David R. Eichel 12/31/89 Except for the following 3 things, MyDOS 4.53/3 is functionally identical to MyDOS 4.50. As such I won't try to reBcreate the entire manual, I'll just cover the differences. You'll probibly first notice that this version defaults to a 3 character file length/free sector count instead of MyDOS's normal 4. This allows it to function wiCth programs that check for the end of the directory improperly, like TextPro, SpeedScript and the new Antic Music Processor. Four and five character file lengths/frees will still be displayed if needed Secondly you'll noDtice that there isn't any AUTORUN.SYS file. V.4.53/3 now allows multiple AUTORUNs at boot up. Any file with the extender ".AR?" will be loaded and run like an AUTORUN.SYS. It will do this for up to ten files (*.AR0 through *.AR9). TheE 8 character main filename can be anything you want, only the extender will be checked. Lastly those of us who own Atari 800s that've been expanded with Axlon type memory upgrades will be happy to know that v.4.53/3 now F functions properly with our computer's RAMdisk. The only difference between v.4.50 and v.4.53/3 as far the user is concerned is when using a custom RAMdisk format instead of a predefined one. With v.4.53/3, instead of entGering a zero as the last number in the sequence for an XE type RAMdisk and an FF for an AXLON type. You must now enter an FF for the XE and a 0 for Axlon types. This is just the opposite of what it was in v.4.50 because that last nHumber is now an AND'd number instead of an ORA'd number. Sorry about the confusion, but it was the easiest way to get the Axlon as well as the XE RAMdisk to function properly. This is ONLY if you use a custom format. The predefined seIquences (numbers 0, 1, 2 & 5) function (externally) just like they do in v.4.50. A (not too) short history of this MyDOS I've been working on this since sometime shortly after v.4.50 was releasedJ. It has gone through many stages and much testing of each. The were, in order: V.4.50/3 -my origional hack which added the 3 character file length default. This dates Kfrom March 1989 and was never released. V.4.51/3 -I wasn't aware of the Axlon problem when I did 4.50/3. I just thought I was messing something up when it didn't work right. WLhen I bothered to look at the code I found that v.4.50 was using $FF as the main RAM bank number, the correct number is 0. Fixing that wasn't a problem. But (there will always be a "but") I found it was loading the accumulator froMm the bank select address and treating it as something meaningful. This works with the XL/XE series but that address is write only with an Axlon upgrade so its read data is anything but meaningful. It then ORA'd that number with anotherN to select the main bank by toggling bits on, however ("but"'s upperclass cousin) I needed to turn bits off, not on. There simply isn't anything you can ORA a number with to get 0. So after much agonizing about changing somethingO that was specifically referred to in the origional docs, namely the critical last byte of custom RAMdisk setup, I modified the RAMdisk code to work properly by using an AND, which is why that last byte is now exactly opposite of what tPhe docs say it should be. The 2 column directory listing was now printed into fixed columns. V.4.50/3 just used spaces and 4 or 5 character files lengths caused the columns to wander. Absolute column positions fixed thisQ. The multiple autorun feature was also new to this version. Its LoMEM was $1F06 which is 29 bytes bigger than the origional 4.50's $1EE9. This was actually a little too high. Some handlers you might want to uRse require a LoMEM of $1F00 or lower. This version was released to selected members of my local users group for beta testing in August. MyDOS v.4.52/3 -While working on an "imporSved" version of Mr.Marslett's new v.4.51 I found several spots where optimizing the code would save critical bytes of memory. I became a bit discouraged during my efforts on this improved 4.51, it seemed that every time I looked at T the code it became larger, so to give myto tf a break I started adding the optimization changes I put in 4.51 to my version 4.51/3. As a result of this I brought its LoMEM down past $1F00 to $1EF3 which is only 10 bytes bigger than 4.5U0. This version dates to the end of November and was never released. MyDOS v.4.53/3 -The only bug I introduced to 4.50 was back in 4.51/3. It was a cosmetic one which involVved what happened if you hit break during a 2 column directory listing. If the 1st column had already been printed before the break, the next list would start in the 2nd column. V.4.53/3 fixes this. I reallWy wanted to bring the LoMEM down to 4.50's $1EE9 (its still $1EF3). Rather than keep playing around trying to find more RAM resident code to optimize, I decided to bend to the wishes of those who've asked me to release it as it is. X However I hold the option of releasing another version if I can find those other 10 bytes. Notes about the source code When I started working on v.4.50 I wasn't interested in making Yit a archeological dig. Code that was changed was changed and code that was removed was removed. I put a comment field at the end of every line I changed, at least an empty one, but that was about it. Since then I realized tZhe usefulness of having what I've done flagged in some unique way. So I started retrofitting the code with an inverse space in the 1st position of the comment field of each line I've changed. I also endevored to re-add those deleted lin[es in commented-out form. I have an assembly listing of the DOS code so its source is probibly pretty complete as far restoring deleted code and inverse spaces is concerned. However I don't have a list of DUP so I had to r\ely on a combination of memory and file comparison. Because of this there is a greater chance of the DUP source being incomplete as far as comment archeology goes. This only concerns comments, all of the actual DOS & DUP code is ] there, complete and ready to assemble using MAC/65. Changes to the new RAMboot This new version of the file allows you to select which functions it performs when you load it. ^ Pressing the 1 key will cause the program to exit without doing anything. This is useful for rebooting without losing the contents of your RAMdisk. Pressing the 2 key will just format the defined RAMdisk type and exit. _Use this to get the maximum ammount of RAMdisk space available to you. Pressing 3 formats the Ramdisk, copies DUP.SYS to it and sets up MEM.SAV but does NOT copy the files from the RAMDISK: subdirectory into it. This is `to speed up booting from a disk with a RAMDISK: subdirectory when you don't really need its files in you RAMdisk. Pressing any other key, or none at all, makes it function just like the pervious version of RAMBOOT.. This is  "X;save#d:MDOS.M65 MYDOS moduleLISTFLGX;(LISTFLG2EI<FALARGE DISK FMSAPX;Z>D4:MDOS1.M65d>D4:MDOS2.M65n>D4:MDOS3.M65xX; BOOTNDI+;;START DUP HERELISTFLGEIion of RAMBOOT.. This is . ;X;v.4.53/3 mods. by David R. Eichel 11/29/89 9:26 pm%X;SAVE #D4:MDOS1.M65 MYDOS module9X; Copyright 1984, Charles Marslett, Wordmark Systems(X;2IX; Permission is granted by the author for any use whatsoever of this<HX; code, so clong as this notice remains in the source code, and soFLX; long as the source to this routine, however modified or unmodified,P.X; is made available for a nominal cost.ZX;dX; DISK I/O EQUATESnX;x4DKADDR1;;SIO ADDRESS OF FIRST DISK DRIVdE (D1:)8TODK;;STATUS BYTE FOR A DATA TRANSFER TO THE DISKRDSTAT S;;SIO COMMAeND EQUATE FOR READING THE DRIVE STATUSFWRITEV W;;SIO COMMAND EQUATE FOR WRITING A DISK WITH VERIFICATION/FMTCMD !;;SIO COMMAND TO FORMAT A DISKETTEX;.LK128};;LOCATION OF 128 BYTE SECTOR LINK.LK256;;LOCATION OF 256 BYTE SECTOR LINKfX;X; ZERO PAGE EQUATESX; WARMST DOSVEC " DOSINI ,X;6 @ ICHIDZJ ICDNOZT ICCOMZ^ ICSTAZh ICBALZr ICBAHZ| ICPTLZ ICBLLZ ICBLHZ ICAX1Z ICAX2Z CURFCB DATBgYTX; CHKSUM1 BUFR2X;C FMSZPGDIRDSPFMSZPGDIRSECFMSZPG CURFNO& FMSBPT0 TMP1: TMP2DX;N.X; DEFINITIONS FOR THE ATARI ROM EXECUTIVEXX;bDSKTIMFlRUNADRvINIADRMEMTOPhDVSTATX;$X; SIO COMMAND BUFFER DEFINITIONX; DDEVIC DUNIT DCOMND DSTATS DBUFLO DBUFHI DTIMLO DBYTLO  DBYTHI DAUX1  DAUX2*X;4X; I/O SYSTEM DEFINITIONS>X;H1iHATABS;;BASE OF THE DYNAMIC HANDLER TABLERX;\8X; CIO COMMAND TABLE BASE DEFINITIONS (FOR IOCB $00)fX;p@z ICHID ICDNO ICCOM ICSTA ICBAL ICBAH ICPTL ICPTH ICBLL ICBLH ICAX1j ICAX2 ICSPRX;&X; CARTRIDGE SUBSYSTEM DEFINITIONSX;(CARINIT;;LOCATION OF INIT VECTOR$"CARTEST;;LOCATION OF FLAGS.&CARRUN;;LOCATION OF RUN VECTOR8X;BX; 800XL MAP CONTROLLX;VMAPREG`X;j!X; OTHER I/O PkORT DEFINITIONStX;~ NMIENԈX;X; ROM VECTORSX;(DSKINVS;;OLD DISK I/O ENTRY POINT$SIOVY;;SERIAL I/O ENTRY POINTX;X; DOS BOOTING CODEX;X;X; DISK BOOT SECTORS (3)X;;;DOS.BOOT LOADS AT 0700#BOOTFL AMA;l;indicate new MYDOS +BOOTL ;;NUMBER OF SECTORS IN THE BOOT/BOOTAD BOOTFL;;ADDRESS OF BOOT CODE IN RAMBOOTIN INIT(*!INBOOT;;JUMP TO THE BOOT CONTINUATION26FILES ;;NUMBER OF FILES THAT MAY BE OPEN AT ONCE<3X;DRIVES = * ;USED TO BE BITm PATTERN FOR DRIVESFRAMDKU  ;;RAM DISK UNIT #P-X;BUFALC = * ;USED TO BE BUF. ALLOC. DIR.Z#DEFAULT ;;DEFAULT UNIT NUMBERd:DOSEND BOOTND;;ADDRESS OF THE FIRST BYTE OF FREE MEM.n2SECDAT ;;1=128 BYTE SECTOR/2=256 BYTE SECTORx(DOSLOC ;;SnECTOR ADDRESS OF DOS.SYS1DLINK LK128;;OFFSET TO THE SECTOR LINK FIELD-DOSAD BASE;;ADDRESS TO LOAD DOS.SYS INTOX;8INBOOT%DOSAD;;SET UP START OF DOS AS BUFFER ADDRESS QDOSAD$ BTSET;;LOW ADDR IN Y, HIGH IN AX;QDOSLOC,%DoOSLOC;;PUT DOS DISK ADDRESS INTO (A,Y)X;X; DOS.SYS INPUT LOOPX;"INITLP,;;CLEAR CY, 'DO A READ'%$SECDAT;;GET CODE FOR SECTOR SIZE$FNODOS;;IF ZERO, NO DOS ON DISK!" DKIO;;INVOKE DISK I/O ROUTINE",GNODOS;;IF AN ERROR, RETURN NO-DOS EpRROR,%DLINK;;POINT TO LINK6,Q@FMSZPG7;;CHECK FOR NEXT LINK (10-BITS)@ANDCDM>;;BEING ZERO,J 5;;SAVE UPPER BYTE OF ADDRESST3^)L@FMSZPG7;;IF SO, LOADING IS COMPLETEh FBOOTXTr4Q@FMSZPG7;;ELSE, IT'S THE ADDRESS OF NEXT SECTOR|5;;SAVE LOWqER BYTE ON STACK2 MVBUFR;;THEN ADJUST THE BUFFER POINTER IN DCB7!?;;RESTORE LOWER BYTE TO Y-REG(7;;RECOVER UPPER BYTE OF DISK ADDRESS!DINITLP;;AND CONTINUE LOADINGX;)NODOSQ>;;NO BOOT PROGRAM ERROR CODE ;;SKIP SINGLE BYTE (LDY #r)X; BOOTXT73DOSXITT?;;SET CARRY, CONVER CODE TO FINAL VALUE?;;PUT CODE INTO Y-REG:;;AND EXITX;4X; MOVE BUFFER POINTERS TO NEXT AREA TO BE LOADEDX;&MVBUFRQDLINK0,:4OFMSZPG;;ADD DLINK TO THE CURRENT BUFFER ADDRESSD?;;LOW BsYTE TO Y-REGNQFMSZPGXO>bBTSET'FMSZPGlPFMSZPGv+BUFSET'DBUFLO;;STORE LOW BYTE INTO DCBPDBUFHI;;THEN UPPER BYTE:X;-X; PERFORM DISK READ(CY=0) OR WRITE (CY=1)X;3DKIOPDAUX2;;STORE UPPER BYTE OF SECTOR ADDRESS'DAUtX1;;THEN LOWER BYTE DKIO2%> Q>READ#DSETRTY;;IF CY=0, READ INTO RAMQ>WRITE;;Was LDA WRCMDB WRCMDB ;;Moved to here.X;%SETRTY'TMP1;;SET NUMBER OF TRIES DKFMEPDCOMND,;;CLC for later ROL A +X; LDA #WRITEV ;Changed to usave space.*(X;WRCMDB = *-1 ;Origional location.4 'DTIMLO>&Q>;;ASSUME A 128-BYTE SECTOR SIZEH0R FSTBUFL\$DAUX2;;SECTOR > 256?f HSET256p $DAUX1z(>;;SECTOR > 3DSTBUFL;;IF NOT)SET256T?;;MAKE A 256 BYTE SECTOR SIZESTBUFLPDvBYTLOU? PDBYTHI+%>DKADDR;;PUT DISK DEVICE CODE INTO DCB 'DDEVICIORTRY"TMP1 GDIOXIT $DCOMND2A"$>FROMDK;;ASSUME DATA ==> DISK M> &HISREAD;;IF NOT X0,X7,X8 OR XF, OK $>TODK;;ELSE, DATA ==> DISK$ )ISREAD&DSTATS;;REwSTORE STATUS TO DCB. SIOV;;DO THE I/O OPERATIONS8 1B GIORTRY;;IF NOT OK, RETRYL X;V 4DIOXIT$CURFCB;;ELSE, LOAD FCB OFFSET AND STATUS` 3j Ct :~ X; ,X; FIXED RAM DEFINITIONS IN BOOT SECTORS: X; ,DIUNIT;;UNIT NO. OF CURRECT DIRECTORY x.CDIREC;;SECTOR NO. OF CURRECT DIRECTORY HOLFN 5STATE p;;DUP loaded, MEM.SAV inactive, Warmstart X; bit 7 -- MEM.SAV in use X; bit 6 -- DUP.SYS loaded &X; bit 5 -- AUTORUN.SYS already run #X; bit 4 -- Initial BUILD active X; "STKPySV;;SAVED STACK POINTER X; ;;MUST MATCH DUP LOCATION X; 2TRACKS #=(=P=M;;TRACKS IN EACH DISK FORMAT( X;2 5SECSIZ =======;;BUFFER SIZE TABLE< X;F %DRVDEF R=R;;DRIVE CONFIG TABLE:P  =;;BIT 7=1 => NO DRIVEZ % z=;;BIT 6=1 => ATARI 810 DRIVEd / =;;BITS 5-4 IS TRACKS (SEE ABOVE TABLE)n X; BIT 3=1 => DOUBLE DENSITYx "X; BITS 2-1 ARE DRIVE STRP RATE X; BIT 0=1 => DOUBLE SIDED X; X; DOS.SYS PROGRAM FOLLOWS X; DKEPT DKOPEN  DKCLOS  DK{READ  DKWRIT  DKSTAT DKXIO X;  X; X; DOS INITIALIZATION CODE X; X;" 2INITQ>i;;INITIALIZE THE CURRENT DIRECTORY, 6PCDIREC;; TO THE ROOT DIRECTORY OF THE BOOT DRIVE6 Q>i@ PCDIRECJ X;T X; IDENTIF|Y DRIVE TYPES^ X;h $>r IDRVLP&DUNIT| , ZERDVS;;ASSUME THE DRIVE IS NOT PRESENT QDRVDEF9 6GNXTDRV;;IF IT IS NOT DECLARED, WAIT FOR AN ACCESS ! JSTRD;;ELSE READ IT'S STATUS *FNXTDRV;;IF ABSENT, GO TO THE NEXT ONE X; LDY #9 X;WOT}CPY LDA WOTDCB,Y X; STA DDEVIC+2,Y X; DEY X; BPL WOTCPY #X;The above was moved to SETDRV QDRVDEF9 R>@ *ENXTDRV;;IF NOT CONFIGURABLE, CONTINUE %SECSIZ9 1 SETDRV;;ELSE, TELL IT ABOUT MY CONFIGURATION X;& &NXTDRV0;;STEP ~TO NEXT DRIVE NUMBER0 "HIDRVLP;;IF MORE, LOOK AT THEM: X;D X; ZERO INITIALIZED MEMORYN X;X INITPT2%>MAPBUFCHGMAPb A;;NOTE X=0 HEREl ZERLP1PCHGMAP8v 1 HZERLP1 #MAP2MOD X; )X; DEFINE TOP OF FMS FOR USER PROGRAM X; QDOSEND PMEMTOP %DOSEND X; #X; ALLOCATE FILE SECTOR BUFFERS X; !$>;;MAX OF 16 SECTOR BUFFERS &DKBFLP(FILES;;EMPTY BUFFERS DONE? DALCBUF "BUFFLG9 GDKBFSQ ALCBUFC* PSBTABU94 3> DKBFSQ0;;BUMP BUFFER COUNTERH $IDKBFLP;;IF NOT CONTINUE LOOPINGR )'MEMTOP;;DEFINE TOP OF MEMORY USED\ X;f X; SET UP HANDLER VECTORp X;z FNDHND2 2 2 *QHATABS9;;END OF THE HANDLER TABLE? !FNOHAND;;THEN INSTALL IT HERE R>D;;A 'D' ALREADY PRESENT? !HFNDHND;;NO, CONTINUE LOOKING X; 1NOHANDQ>D;;END OF TABLE OR CURRENT 'D' ENTRY PHATABS9 (Q>DKEPT;;STASH MYDOS ENTRY VECTOR PHATABS9 Q>DKEPT "PHATABS9;;BUILD HANDLER VECTORB!;;DUPINV (dup code modifies this) ;DONE, INITIALIZE DUP CODEX;X;$'X; DOS NON-ZERO PAGE RAM ALLOCATIONS.X;8 CHGMAPB CURMAPL MAP2VMAP2MOD` LSTSECjLSTIOCBtX;~=X; MYDOS FCB STRUCTURE (ALMOST THE SAME AS ATARI DOS 2.0)X; FCBFNOFCBOTC;;OPEN TYPE CODE FCBFLG MAXLEN CURLEN BUFNO CURSEC LNKSEC SECCNT*DIRBAS;;BASE ADDRESS OF CUR. SECTOR SAVSEC FCBLEN FCBLENX;&BUFFLG;;IF 0, BUFFER NOT IN USE(6SBTABU;;UPPER BYTE OF THE SECTOR BUFFER ADDRESS2(MAPBUF;;SPACE ALLOCATED FOR VTOC<7DIRBUFMAPBUF;;SPACE ALLOCATED TO READ DIRECTORIESF FNAME P CURMPZX;dX;n BASE x/HDTAB ===;;8 LOGICAL HARD DRIVES OF) ===;;UP TO 65535 SECTORS EACHX;BX;this table is referenced by DUP.SYS, and should not be moved!X;X;X; DOS CONFIGURATION CODEX;X;=X; CONTROL BLOCK TO BE WRITTEN TO A DRIVE TO CONFIGURE ITX;WOTDCB N=@ DIRBUF=  =X;PX; THE CONFIGURATION CODE, FORCES A DRIVE INTO THE APPROPRIATE CONFIGURATIONX;""SETDRVM>?;;EXTRACT CONF. BITS, PTMP16 'TMP2@ %> ;;J WOTCPYTQWOTDCB8;;Set up SIO^PDDEVIC8;;handler toh1;; read drive'srIWOTCPY;; DCB.|% SIOV;;READ CURRENT CONFIGURATION GJSTRD QTMP1 %TMP2V?5;;SAVE REMAINING BITSM>;;EXTRACT STEP RATE CODEPDIRBUFQ>PDIRBUFU?'PDIRBUF;;STORE DOUBLE SIDED FLAGC;;GET DENSITYV?/PDIRBUF;;STORE UPPER BYTE OF SECTOR SIZEW?PDIRBUF;;THEN LOWER BYTE&U?0T?:T?DPDIRBUFN7XV?bV?l!V?;;POSITION TRACK COUNT FIELDv?"QTRACKS8;;GET NUMBER OF TRACKS PDIRBUFM>;;SEE IF 77 TRACK 8 IN.5V?/LDIRBUF;;MERGE D/DENSITY WITH 8 IN. FLAGPDIRBUF7T?;;CONVERT TO 0 OR 8 O>;;SECTOR COUNT = 18 OR 26PDIRBUF %DUNITQHDTAB8 FTOSIOV !PDIRBUF;;SIZE = SECTORS/TKQHDTAB8  PDIRBUF;;LOW BYTE OF SIZE*Q>4PDIRBUF;;ONE TRACK/DRIVE>+TOSIOV#DCOMND;;CHANGE COMMAND TO WRITEHQ>R"PDSTATS;;SET DIRECTION -> DISK\& SIOV;;WRITE OPTION TABLE TO DRIVEfX;pFX; AND THIS ROUTINE MAKES SURE IT REALLY DID HAPPEN AS WE THOUGHT!zX;JSTRDQ>RDSTAT PDCOMND DSKINV $DUNITC GZERDVS QDVSTATT?;;SECTOR SIZE=256?T?T?Q>O>SETSIZPSECSIZ9:X;ZERDVSQ>$FSETSIZ;;branch always.X;8X; DOS RAMDISK CODEBX;LX;V+X; RAM DISK I/O HANDLER (POS. IND. CODE)`X;j MAPAGEt ===~ === ===ϒ ===X; === ===ߺ === ===X; === === === ===X;  === === ===( ===2X;<VALSEC5;;Save RAMbank #FC;;Sector # (lo)PL>;;$80/2=$40ZV?;;Page # = sectordPBUFR;; (lo)/2.n=;;DISABLE INT-SxQ>PNMIEN;;DISABLE NMI-SW?;;Odd sector usesPBUFR;; top 1/2 page.7;;Res. RAMbank #? QMAPREGM>;;Calc. & savePCHKSUM;; main RAMbank.L>| MMAPAGE8%PMAPREG;;SELECT RAMDISK DATA PAGEX;*QDBUFLO;;USER BUFFER ADDRESS GOES HERE PBUFRQDBUFLO PBUFR"%>,86DRREADL;;CY=0 IF READ@RWRITLQ@BUFR7J P@BUFR7T3^ IRWRITLh GRIOXrX;|)RDKIO'DAUX1;;*** FOR FORMAT CODE ***)>U?R>/RDKLMT ;;NUMBER OF 16K PAGES IN RAMDISK!DVALSEC;;CALCULATE MEM. ADDR.8Q> GRERRORX;RREADLQ@BUFR7P@BUFR73 IRREADLX;%RIOXQCHKSUM;;FORCE REAL RAM PAGEPMAPREG;;BEFORE EXITING&Q>0PNMIEN;;RE-ENABLE NMI:.;;ENABLE INTERRUPTSDQ>;;RETURN '1' IN Y-REGN&RERRORPDSTATS;;AND IN STATUS BYTEX$CURFCB;;RESTORE FCB ADDRb?l:;;THEN EXIT3 IRREADLX;%RIOXQCHKSUM;;FORCE REAL RAM PAGEPMAPREG;;BEFORE EXITING&Q>0@ ;X;v.4.52/3 mods. by David R. Eichel 11/10/89 1:30 pm%X;SAVE#D4:MDOS2.M65 MYDOS module9X; Copyright 1984, Charles Marslett, Wordmark Systems(X;2IX; Permission is granted by the author for any use whatsoever of this<HX; code, so long as this notice remains in the source code, and soFLX; long as the source to this routine, however modified or unmodified,P.X; is made available for a nominal cost.ZX;dX; DISK OPEN ROUTINEnX;x'DKOPEN WBITMP;;fix that nasty bug!( SETUP;;SET UP BUFFER POINTERS, ETC.2 GETFNM;;GET DRIVE ID OR FILE NAME FROM BUFFER'QICAX1Z;;GET TYPE OF OPEN FROM IOCB PFCBOTC9!M>;;TEST DIRECTORY READ FLAG FDKOPN13!LSTDIR;;IF SET, GO HANDLE DIRECTORY FORMATTINGX;DKOPN1PSAVS EC9PSAVSEC9;;ZERO SAVSEC SFDIR6;;SAVE STATUS RETURNED EOPNEW*Q>;;MAKE SURE THIS IS NOT A DIRECTORY GETFLAG4HDIROPN;;IF A DIRECTORY, GO HANDLE IT SEPERATELY"OPNEW%ICAX1Z,)>6FOPNOP;;IF OPEN FOR OUTPUT@)>JFOPNI N;;IF OPEN FOR INPUTT)> ^+FOPNUP;;IF OPEN FOR READ/WRITE (UPDATE)h)> rFOPNAP;;IF OPEN AND APPEND|.DIROPN!ERRCMD;;OTHERWISE, IT IS AN ERROR!X;OPNAP8;;OPEN APPEND EOPNCR0 TSTLOK- INITYP;;READ ALL THE SECTORS IN THE FILEQ DIRBUF8 PSECCNT9QDIRBUF8PSECCNT9APPRD RDNXTS$DAPPRD;;IF NOT EOF, READ ANOTHER QMAXLEN9# LENSET;;SET LENGTHS FOR OUTPUT QSECCNT9 HSGLDEC"SECCNT9&/SGLDEC"SECCNT9;;ALLOW FOR SECTOR REWRITTEN0 !OPOUTX:X; D OPNUP8;;OPEN UPDATE (OUTPUT)N EOPNER1X TSTLOKbOPNOWR INSTRTl !DONEvX;OPNIN8;;OPEN INPUT DOPNOWROPNER1Q>;;FILE NOT FOUND GEROXITX; OPNOP8;;OPEN (NORMAL) OUTPUT EOPNCR REMOVE !GET1STX;OPNCR0"FCBOTC9 OPNCRQHOLFN PCURFNO GOPDIRF GET1ST ALLOCX; $QICAX2Z;;IF OUTPUT, TYPE OF FILE*"M>$;;SAVE LOCKED & FORMAT BITS41N>C;;MERGE IN DEFAULT CODE (DOS II, UNLOCKED)>%MAPBUF;;WHICH TYPE DISK?H)>;;IF >2 THEN MYDOSR DLLINKS\L>f X;p LLINKS5z. RDCFNO;;SELECT PROPER SECTOR IN DIRECTORY; ENTNAME;;ENTER NAME INTO ITQLNKSEC9PDIRBUF8 QLNKSEC9PDIRBUF87 SAVFLAG INITYP TONXTOPOUTXQ> PFCBFLG9! TSTDOS;;FILE NAME = DOS.SYS? H JDONE %CURSEC9QCURSEC9$' SETDOS;;IF SO, UPDATE BOOT SECTORS.X;8 QDOSADB PFMSZPGL QDOSADVPFMSZPG`0HOWTDOS;;NOTE: DOS CANNOT START ON ZERO-PAGEjX;tOPDIRFQ>~EROXIT!AEXITX;3LWTDOS WRNXTS;;AUTOMATICALLY WRITE DOS.SYS OUT/OWTDOS%>;; IF WE OPEN IT FOR WRITE (THIS5CDOSBFQ@FMSZPG7;; IS BECAUSE DOS 2.0 WOULD BLOW1P@FMSBPT7;; ITSELF AWAY IF A REAL WRITE FROM&3;; THE DOS CODE WAS ATTEMPTED AND1)DLINK;; WE ARE GOING TO REMAIN COMPATIBLE). D CDOSBFC PCURLEN9 MVBUFR )DOSENDSDOSEND  DLWTDOSJDONE!DONEX;(X; READ DATA FROM A FILE2X;</DKREAD SETUP;;SET UP BUFFER POINTERS, ETC.F QFCBOTC9P&M>;;TEST THE DIRECTORY INPUT FLAGZ!FRDFILE;;SO WE CAN HANDLE THEd .!DIRRD;; SPECIAL CASE OF A DIRECTORY READnX;xRDFILEQCURLEN9 RMAXLEN9;DRDSGBT;;IF NOT AT SECTOR BOUND., READ A BYTE AT A TIME6ERDASNT;;ELSE, CHECK FOR READ MODE AND BUFFER SIZEX;RDASLPQICCOMZM>4FRDSGBT;;IF NOT BINARY I/O READ A BYTE AT A TIME %DLINK1?RDSCLPQ@FMSBPT7;;SIMULATED BURST I/O (USING UNROLLED LOOP) P@ICBALZ71 Q@FMSBPT7 P@ICBALZ71 Q@FMSBPT7" P@ICBALZ7,16 Q@FMSBPT7@ P@ICBALZ7J1T HRDSCLP^0Q@FMSBPT7;;DATA AREA IS MULTIPLE OF 4 PLUS 1h P@ICBALZ7r0 BUFADJ;;ADJUST BUFFER POINTER BY 125 OR 253|(RDASNT RDNXTS;;READ THE NEXT SECTOR*ERETEOF;;REPORT EOF/ERROR IF NECESSARYQICBLLZ;;AND REPORT LAST BYTE IF IT IS SO! ,&X;0)RETEOFQ>;;RETURN END OF FILE STATUS: !A EXITDX;NX; WRITE DATA TO A FILEXX;b,DKWRITPDATBYT;;SAVE DATA BYTE (PERHAPS)l %ICDNO9v5'ICDNOZ;;INSURE ICDNOZ IS SET UP (BASIC DOES NOT). SETUPW;;SET UP REST OF FLAGS AND POINTERS QFCBOTC9M>8FCANTWR;;ERROR OUT IF WRITE IS ILLEG AL (BASIC AGAIN) QCURLEN9? RMAXLEN98DSKBURST;;SKIP AROUND IF NOT WRITING END OF A SECTORX;*WRASLP WRNXTS;;WRITE A SECTOR OF DATA,ERETEOF;;ERROR OUT IF NO MORE DISK SPACE %STKPSVQ8R>;;IF FROM BASIC DBASWRT;;PASS SIN GLE BYTES!QFCBOTC9;;fix open for update M>;;bug in burst I/O* HBASWRT4 QICCOMZ>M>;;AND IF RECORD I/OHFBASWRT;;PASS SINGLE BYTESR0%ICBLLZ;;AND IF THE BUFFER IS < 256 BYTES\FBASWRT;;PASS SINGLE BYTESf %MAXLEN9p1z1WRSCLPQ@I CBALZ7;;ELSE DO SIMULATED BURST I/O$P@FMSBPT7;;BY UNROLLING THE LOOP1 Q@ICBALZ7 P@FMSBPT71 HWRSCLP-Q@ICBALZ7;;BUT ONLY 2 ENTRIES FOR WRITING P@FMSBPT7 BUFADJ Q@ICBALZ7 PDATBYT !WRASLPX; BASWRT%> SKBURSTQD ATBYT #CURLEN9$ P@FMSBPT7. Q>@8 :LFCBFLG9;;FOR UPDATE, SAY THE SECTOR HAS BEEN MODIFIEDB PFCBFLG9L HTODONE;;BRANCH ALWAYS!V X;` CANTWR!ERRCMDj X;t BUFADJ,~ QMAXLEN9 PCURLEN9 OICBALZ PICBALZ DRBAOK #ICBALZ RBAOK; QICBLLZ SMAXLEN9 PICBLLZ ERBLOK "ICBLLZ RBLOK: X; X; RETURN FILE STATUS X; .DKSTAT SETUP;;SET UP RETURN ADDRESS, ETC.( ( LFFILE;;FIND IF FILE IS THERE, ETC.2  TSTLOK;;IS IT LOCKED?< "TODONE!DONE;;RETURN TO CALLERF X; P -X; CLOSE FILE (WRITING ANY PENDING SECTOR)Z X;d DKCLOS SETUPn QFCBOTC9x M>;;OUTPUT ALLOWED? FCLROTC;;IF NOT, JUST EXIT UFCBFLG9 DCKFLSC $ REWRIT;;REWRITE THE LAST SECTOR RRDIR QSECCNT9 %DIRDSP PDIRBUF8 QSECCNT 9 PDIRBUF8 QDIRBUF8 %M>;;NOT OPEN FOR OUTPUT ANY MORE SAVFLAG QSAVSEC9 LSAVSEC9 FCLROTC" (LSTIOCB, FFAPPD6 ' INITYP;;READ ALL THE SECTORS AGAIN@ APPLP RDNXTSJ DAPPLP;;NOT EOF YETT ETIELNK^ FAPPDQLSTSECh PCUR SEC9r QLSTSEC| PCURSEC9 TIELNK, RWDISK QDLINK PCURLEN9 QSAVSEC9 %SAVSEC9 SAVLNK CLROTEICLROTC "Q>;;FAILURE IS A SYSTEM ERROR !AEXIT CLROTCQ> PICHID9 Q> PFCBOTC9 !FREDON X;& CKFLSCUFCBF LG90 DCLROTC: WRDISKD !CLROTEN X;X INITYPQ>b GETFLAGl V?v W? W? W? LFCBOTC9 PFCBOTC9 QDIRBUF8 PLNKSEC9 QDIRBUF8 PLNKSEC9 QCURFNO PFCBFNO9 Q> PFCBFLG9 PCURLEN9 PSECCNT9 PSECCNT9 : X;* X; DOS XIO ROUTINES4 X;> X;H LX; Sorry about the lack of comments in this file and some of the others,R HX; I just never had to figure this code out after I wrote it (:-)!\ X;f $NODIRFQ>;;FILE NOT A DIRECTORYp !AEXITz X; PIKDIR%>  Q> : FDVND3 R@ICBALZ7 HFDVND 3 Q@ICBALZ7 R> @ DSETRDIR R> Z DGFNDIR R> _ DSETRDIR R> z ESETRDIR.GFNDIR LFFILE;;FIND NEW DEFAULT DIRECTORY$ INITYP. TONXDR8FNODIRF;;IF NOT A DIRECTORYBQDIRBAS 9L?V QDIRBAS9`-SAVDEF'CDIREC;;UPDATE ADDRESS OF DIR.j PCDIRECt QICDNOZ~ PDEFAULT;;UPDATE UNIT NUMBER ITOFDNX;SETRDIRQ>i %>i ISAVDEFX;1RENAME LFFILE;;GET OLD NAME, DRIVE, VALIDATE%> STEMPLQFNAME 8PMAPBUF81 HSTEMPL+RNLOOP TSTLOK;;CANNOT RENAME IF LOCKED  TDDOS;;TEST FOR DOS GONE! %TMP2 GETNAM;;GET NEW NAME(,2$ ENTNAME;;OVERWRITE NAME IN DIR.<& WDIRBK;;REWRITE DIRECTORY TO DISKFX;P TSTDOS;;NEW NAME DOS.SYS? ZHREPLDS;;NO, LOOK AT NEXTd %DIRDSPnQDIRBUF8x5QDIRBUF8?7& SETDOS;;ELSE, UPDATE BOOT SECTORSREPLDS%> RTEMPLQMAPBUF8PFNAME81 HRTEMPL CSFDIR;;TO RENAME DRNLOOP ETOFDNX;DELETE LFFILE $DELLP REMOVE;;FLUSH THE SECTORS" RRDIR;;REREAD DIRECTORY BLOCK" TDDOS;;DOS.SYS DELETED?,Q>6% SAVFLAG;;REWRITE DIRECTORY BLOCK@ CSFDIRJDDELLP;;IF ANOTHER FOUND,T)TOFDN!FREDON;;ELSE, WRAP UP AND EXIT^X;h0REMOVE TSTLOK;;ONCE H AD 'OPVTOC' CALL FIRSTr INITYP| TONXDR HDELDIR CHASEX;D0C6C FREE RDNXTS DD0C6C:X;'INVDELQ>;;DIRECTORY NOT DELETABLE !AEXITX; LOCKQ>  ,;;BIT ABS (SKIP 2 BYTES)X;UNLOCKQ> PDATBYT&* LFFILE; ;FIND FILE AND VERIFY WRITABLE0#LKULKLQ>;;STRIP OFF OLD BIT 5: GETFLAGD!LDATBYT;;AND REPLACE WITH NEWN SAVFLAGX CSFDIRb DLKULKLl ETOFDNvX;DELDIR%> Q> ?DELSETPFNAME 83 HDELSET SFDIR DINVDELX;Q>  PDATBYT TONXTDELDRL FREE INCCSEC "DATBYT  HDELDRL !GETFNM X;*POINT%FCBFLG94 GERRCMD>X;HQICSPR9RRCURSEC9\ HPNTREADf QICSPR9p RCURSEC9z FPNTSME PNTREADC!FPNTCLN;;IF SECTOR UNMODIFIED WRDISK Q> PFCBFLG9PNTCLNQICSPR9PLNKSEC9 QICSPR9 PLNKSEC9" CHASE;;READ SECTOR POINTED TO EBADPNTX;PNTSMEQICSPR9 RMAXLEN9 EPNTEQLPNTLSTPCURLEN9$ !DONE.X;8,PNTEQLFPNTLST;;IF POINTING AT LAST BYTEB& BADPNTQ>;;INVALID POINT LOCATIONL VX;`&ERRCMDQ>;;INVALID IOCB PARAMETERj !AEXITtX;~NOTEQCURSEC9 PICSPR9QCURSEC9PICSPR9 QCURLEN9PICSPR9 !DONEX;DKXIO SETUPQICCOMZ;;GET COMMAND BYTER> FF ORMATR>+EERRCMD;;IF INVALID COMMAND  S>  DERRCMD?( QVECTBH825< QVECTBL8F5P:;;VECTOR TO PROPER ROUTINEZX;d,VECTBH RENAME =DELETE n" MKDIR =LOCK x$ UNLOCK =POINT # NOTE =DKLOAD % DKLOAD =PIKDIR  MKDIR X;*VECTBL RENAME =DELETE  MKDIR =LOCK " UNLOCK =POINT ! NOTE =DKLOAD # DKLOAD = PIKDIR  MKDIR X;X; DOS FORMAT ROUTINESX;X;6FORMAT WBITMP;;WRITE OUT ANY PENDING VTOC SECTORS:X; LDY #9 ;Force format to match current density"GX;WOTCPY2 LDA WOTDCB,Y ;set up DCB for specified density [Bob Pu ff],X; STA DDEVIC,Y6 X; DEY@X; BPL WOTCPY2J#X;The above was moved to SETDRVT $ICDNOZ^ (RAMDKUh%FWOTRAM;;don't do it for RAMdisksr%SECSIZ9|QDRVDEF9 SETDRV;;set density!WOTRAM$CURFCB;;restore X reg%>(C;;THEN I NITIALIZE NEW BIT MAP (VTOC)CLRMAPPMAPBUF8PMAPBUF83)HCLRMAP;;ALLOCATING ALL POSSIBLE BITSX;Q>(PMAPBUF;;DEFINE IT AS A DOS 2.0 DISKQ> P@FMSBPT73=P@FMSBPT7;;PRESUME NO BAD SECTORS IF BUFFER IS UNMODIFIED %ICD NOZ& )RAMDKU0(FRAMFMT;;IF RAMDISK, SKIP EVERYTHING:QFMSBPTD(%FMSBPT;;call density junk for patchN/ BUFSET;;SET UP BUFFER POINTER FOR SIO CALLX$>b&TMP1;;ALLOW ONE TRY ONLYl(Q>";;PRESUME 1050 D/D FORMAT REQUESTv%ICAX2Z;;THEN GET AUX2 BYTE(GFMTOK;;MINUS --> NO FORMAT REQUIRED HNMLFMT%ICAX1Z;;(AUX2,AUX1) = 1?1.FFT1050;;YES, FORMAT WITH $22 COMMAND BYTENMLFMT$DUNITQSECSIZ9>+Q>FMTCMD;;AUX IS 0, must not be 1050 dd*FT1050PDAUX1;;MAKE SURE WE SEC TOR > 34%DSKTIM;;DISK TIMEOUT VALUE (RETURNED IN STATUS)& DKFME;;ENTER DKIO AT FORMAT ENTRY#IFMTOK;;delete bad sector check*FMEXIT!AEXIT;;ELSE, RETURN ERROR CODE X;?RAMFMTPCURSEC9;;STUFF PROPER NUMBER OF SECTORS INTO CURSEC 3,;;(256- BYTE PAGES * 2 SINCE SECTOR SIZE IS 128)* ORDKLMT4V?> WCURSEC9H,HNOTDEF;;FAIL IF NOT 256 SECTORS OR MORERX;\8X; SUCCESSFUL FORMAT, CREATE VTOC AND EMPTY DIRECTORYfX;p%FMTOK%>;;check for a bad formatz Q@FMSBPT7#M@FMSBPT7;;first two bytes $FF?R>FFMTOK2;;yep, continueQ>;;otherwise format error HFMEXIT.FMTOK2 INVUNIT;;MAKE SURE WE CAN DO THIS!- DELDOS;;DELETE ANY CURRENT DOS BOOT FILE QICAX1Z PCURSEC9 QICAX2Z#M>;;DISK MUST HAVE 256 SECTORS&HNOT DEF;;IF SIZE SPECIFIED, USE IT %ICDNOZ.QHDTAB8;;IF NOT AND THIS IS A HARD DISK"PCURSEC9;;USE THE DEFINED SIZEQHDTAB8$ HNOTDEF.&*DVSTAT;;ELSE, IS IT A 1050 DRIVE?8!IFIGSIZ;;NO, FIGURE SIZE THENB'Q>;;YES, FORCE TO 1040 S ECTORSL PCURSEC9V Q>` HNOTDEFjX;tFIGSIZQDRVDEF8~"M>1;;EXTRACT TRACK COUNT FLAGSV?6V?V??0QNOSECS8;;AND USE DRIVE DEFAULT SECTOR COUNT PCURSEC9QNOSECS88,DNOTDEF;;IF NOT DOUBLE SIDED, THIS IS IT T CURSEC9U?;;ELSE, DOUBLE ITX; NOTDEFPCURSEC9R>;;NEED 16 BIT LINKS? DSHORTS;;NO, SHORT FORMAT OK(*#MAPBUF;;YES, FORCE LONG FORMAT (DOS3)2,SHORTS FNDBIT;;FIND LAST BIT MAP SECTOR< QTMP2F"HGT246;;IF PAST 256TH MAP BYTEP*DLIN K;;SINGLE DENSITY?Z GFDBDENd)>n IFDBDENxGT246PMAP2,O> PMAPBUFFDBDENQ> PMAPBUF Q> 2PMAPBUF;;START WITH 9 FREE SECTORS UN-FREE!FLOOP FMTFRE DECCSECR>;;BOOT SECTORS YET?)HFLOOP;;IF N OT, CONTINUE DEALLOCATINGQCURSEC9 HFLOOPX;Q>;;success)PFMSBPT;;bad sector code deleted here"X;,Q>6>PMAPBUF7;;ALLOCATE THE ROOT DIRECTORY AND BASE VTOC SEC.@*Q>;; NOTE: ALWAYS THE SAME 9 SECTORSJPMAPBUF8T"%>,;;ST ART ALLOC. OF VTOC HERE^ QMAPBUFh;rS>;;GET NUMBER OF SECTORS|*DLINK;;(SINGLE DENSITY?)GMPNSD;;IF NOT, M-3T?;;IF SO, M*2-5 MPNSD>0;;MOVE COUNT TO XX;ALCMPLQ> ALCMAP0 GSMBSIZ5 DECCNT7T? HALCMAPPMA PBUF 81IALCMPL;;BRANCH ALWAYS!&X;0SMBSIZPMAPBUF 8:$QMAPBUF;;MARK EMPTY SIZE, TOODPMAPBUFNQMAPBUFXPMAPBUFb FMTMAP;;WRITE MAP TO DISKlX;v X; CREATE AN EMPTY DIRECTORYX; Q>i %>i3CLRDIR SE TDIR;;RESET THE DIRECTORY BASE SECTORC$CLRDLPPDIRBUF8;;ZERO THE BUFFER3 HCLRDLPX;Q> PDIRSEC1CLRDL2 WDIRBK;;THEN WRITE 8 SECTORS OF ZEROS "DIRSEC ICLRDL2  %BUFNO9Q>  PBUFNO9*2PBUFFLG8;;DONE, SO FREE UP INTE RNAL BUFFERS4 QFMSBPT> !AEXITHX;R"NOSECS #=(=P=M\X;fSETDIRPDIRBAS9pCzPDIRBAS9%>:X;X; DOS BINARY LOAD CODEX;X;.X; LOAD AND EXECUTE A BINARY FILE (PROGRAM)X;DKLOADQICAX1Z-PICPTLZ;;SAVE PROGRAM NAME BUFFER POINTERR>#ETOERRC;;IF WRITE, REPORT ERRORX;Q>TORTS PRUNADR-Q>TORTS;;ASSUME RUN ADDRESS IS ABSENT$PRUNADR.Q>8 PICAX1ZBQICHID9;;IOCB OPEN?L ICCFILEV DKOPEN;;IF NOT, OPEN IT` GDKLERVj WDREAD;;READ A HEADER WORDt FCCFILE~+%>;;NO $FFFF, REPORT HEADER ERROR CODE GDKLERVX;TOERRC%>;;INVALID IOCB:X;GETTXTQ>TORTS PINIADR:Q>TORTS;;FOR EACH SEGMENT, RE-FORCE NULL INIT CODEPINIADRTXTLP DKR EADDKLERVGDKLERR%> P@ICBALZ7  #ICBALZ HDECLEN #ICBAHZ(DECLENQICBLLZ2 HDECLOW< "ICBLHZFDECLOW"ICBLLZP HTXTLPZ QICBLHZd HTXTLPn QICBAHZxR>INIADR HCCFILEX;QICPTLZ;;IF NO INITS,V?ECCFILE;;SKIP TO NEXT PAGEA;;ELSE SAVE IOCB5 %> CPSICBQICHIDZ 8$PICHID9;;SAVE 12 BYTE IOCB ENTRY23 HCPSICB7>5"# DOINIT;;AND CALL INIT FUNCTION,76>@5J %> T1CPRICBQICHID9;;THEN RESTORE THE 12 BYTE IOCB^P ICHIDZ 8h2r3| HCPRICB7>X;&CCFILE WDREAD;;READ START ADDRESS FCCFILE PICBALZ 'ICBAHZ WDREAD;;READ END ADDRESS;O> DCCSUBT3 CCSUBT; !SICBALZ;;CALCULATE THE LENGTH PICBLLZ C& SICBAHZ0 PICBLHZ : 0EGETTXT;;BRANCH IF A VALID LENGTH (GET DATA)D %%>;;ELSE, MEMORY WRAP ERROR CODEN GDKLERRX X;b WDXIT7l 7v DKLERRC 5  DKCLOS;;CLOSE PROGRAM FILE 7 (?;;AND RETURN HIS ERROR CODE (IF ANY) : X; BX; READ A WORD FROM THE PROGRAM FIL E AND COMPARE IT WITH $FFFF X; WDREADQ> PICBLLZ PICBLHZ;;SET LENGTH TO ZERO  DKREAD;;READ A BYTE GWDEOF!5 ! DKREAD;;READ THE SECOND! GWDEOF1 !?*!74!)>;;UPPER BYTE $FF?>!,HTORTS;;IF NOT, TOTAL VALUE IS NOT $FFFFH!%R>;;UPP ER OK, IS LOWER BYTE $FF?R!.TORTS:;;RETURN ZERO FLAG IF WORD WAS $FFFF\!X;f! WDEOF17p!#WDEOF)>;;IS THIS END OF FILE?z!%HWDXIT;;IF NOT, RETURN ERROR CODE!7!"7;;ELSE, GET RID OF RETURN ADDR! QICPTLZ!V?!V?!6!# DKCLOS;;CLOSE FILE AND SET Y=1!8!$ETORTS;;EXIT IF NO-RUN SPECIFIED!+!@RUNADR:;;OTHERWISE, GO TO RUN ADDRESS!X;!FX; INVOKE INIT FOR EVERY BLOCK OF INPUT CODE (USUALLY JUST AN RTS)!X;"#DOINIT!@INIADR:;;CALL INDIRECTICPTLZ!V?!V?!6!# DKCLOS;;CLOSE FILE AND SET J ;X;v.4.53/3 mods. by David R. Eichel 11/29/89 9:32 pm$X;SAVE#D4:MDOS3.M65 MYDOS moduleX;(X; DOS MAKE DIRECTORY CODE2X;<9X; Copyright 1984, Charles Marslett, Wordmark SystemsFX;PIX; Permission is granted by the author for any us$e whatsoever of thisZHX; code, so long as this notice remains in the source code, and sodLX; long as the source to this routine, however modified or unmodified,n.X; is made available for a nominal cost.xX;-X; XIO FUNCTION TO CREATE A NE$W DIRECTORYX;X; PARSE DIRECTORY NAMEX;MKDIR GETFNM" SFDIR;;FIND FILE IN DIRECTORY EMKDMRDQ>;;FILE ALREADY EXISTS ;;SKIP 2 BYTESDISFULQ>;;DIRECTORY FULL !AEXITX;X; READ IN BIT MAPX;MKDMRDQHOLFN GD$ISFUL" RBITMP, %MAPBUF61@1J 'DATBYTTX;^'X; FIND EIGHT SECTORS FOR DIRECTORYhX;r3Q>q;;FIRST AVAILABLE SECTOR AFTER ROOT DIR.| PCURSEC9 Q>qPCURSEC9Q> PTMP1FDIRLP#TMP1" FNDLBIT;;IS THIS SECTOR FREE?$ EFDIR2 MMAPBUF8 DFDIR1FDIR2MMAPBUF8FDIR1HFDIR3 PTMP1FDIR3 INCCSEC QTMP1R> HFDIRLP&X;0 X; ALLOCATE THE SECTORS USED:X;DALCDLP DECCSECN FNDLBITXN>b EALCPG2l MMAPBUF8v PMAPBUF8 DALCPG1A$LCPG2MMAPBUF8PMAPBUF8 VMAP2MODALCPG1 DECCNT "TMP1 HALCDLPX;(X; WRITE ALLOCATION MAP BACK TO DISKX; FMTMAPX;5X; ENTER NAME AND TYPE INFO INTO PARENT DIRECTORYX;  QHOLFN SDIRBK ;* ENTNAME4QCUR$SEC9>PDIRBUF8H QCURSEC9RPDIRBUF8\Q>fPDIRBUF8pQ>zPDIRBUF8T? SAVFLAGX;X; THEN CLEAR NEW DIRECTORYX;Q> PFMSBPT QCURSEC9%CURSEC9 !CLRDIRX;$X; SIMULATE OLD STYLE BIT FINDERX;$FNDLBIT FNDBIT5;;SAVE MASKQTMP2;;FIRST PAGE?$ FFNDPG0.'TMP2;;SAVE OFFSET IN PAGE8 RDATBYTB EDFEJMPL RDNXTM;;READ IN PROPER PAGEV$%TMP2;;THEN RESTORE A AND Y REGS`7j!;;;SET CY (PAGE 1 BUFFER USED)t:~X;FNDPG07;;RESTORE$ SAVED MASK,;;AND CLR CY (SAY PAGE 0):X;DFEJMP!DFERRX;DECCSECQCURSEC9 HALCPG0"CURSEC9ALCPG0"CURSEC9:X;INCCSEC#CURSEC9  HDELDIN#CURSEC9 DELDIN:(X;2X; DOS DIRECTORY ROUTINES<X;FX;P/X; OP$EN A DIRECTORY (FOR DIRECT USER ACCESS)ZX;dLSTDIR%> nSAVFNBQFNAME 8;;PutxP@FMSBPT7;;all 11 chars3;;into FMSBPT. ISAVFNB) SFDIR;;FIND A MATCH IN THE DIRECTORY-EENDDIR;;IF NO MORE, GO REPORT FREE SPACE1NXTDIR FMTDIR;;E$LSE, FORMAT INTO TEXT STRING QCURFNO-PFCBFNO9;;SAVE FILE NUMBER OF ENTRY FOUNDGODONE!DONE;;AND RETURNX;1GOTEOD"DATBYT;;CONVERT EOL TO $9B (REAL EOL)PCURLEN9;;AND FINISH UP HGODONEX;X;DIRRD%>  FGOTEODR>;;IS THIS END OF LINE?'HGODONE;;IF NOT, CONTINUE TEXT DUMP$ QFCBFNO9 RCURFNO HDMSTRD (DIUNIT FDRDNRQDMSTRD RRDIRDRDNRQ CSFDIR DNXTDIRX;0X; NO MORE ENTRIES, REPORT FREE SECTORS LASTX;&ENDDIR RBITMP;;READ THE VTOC DATA%>&%'CURMAP;;FORCE A REREAD NEXT TIME0QMAPBUF$::$MAPBUF;;AND STUFF BUFFER WITH NUMBER OF FREE SECS.D CVTDECN$>X9FSECLQFSECM9;;FOLLOWED BY "FREE SECTORS" TEXTb P@FMSBPT7l3v2 HFSECL#FGODONE;;THEN LAST LINE IS DONEX;:DIREOF!RETEOF;;NO MORE LINES, RETURN E-O-F$ INDICATIONX;FSECM A FREE SECTORSA=X;/X; FORMAT A DIRECTORY ENTRY FOR BASIC, ETC.X;FMTDIR%> ;;space $DIRDSP QDIRBUF95M>  FNOTLCK%> *;;IF SO, MARK AS LOCKED  NOTLCKC*%>4 P@FMSBPT7>7H%> ;;spaceRM>$\ FNOTDIRf%> :p NOTDIRCz%> P@FMSBPT7 CPYNAML3QDIRBUF9 P@FMSBPT72)>  DCPYNAMLX;Q> ;;space P@FMSBPT7 %DIRDSPQDIRBUF8$DIRBUF8 !%>;;SECTOR COUNT STARTS HERE X; 8X; CONVERT A 16-BIT INTEG$ER TO A 4 OR 5 DIGIT NUMBER$ X;. CVTDEC&TMP28 PTMP1B $>'L Q>'V MKDGT2` 5;;Save this digit.j R> 0t HSKIP5~ 1 SKIP5$> Q> MKDGT2 R> 0;; 7;;Don't overwrite ESKIP4;; a non-0 5th R> 0;; char. i$f 4th HSKIP4;; = 0. 1;;Both zero. SKIP4 Q>d;;FOR SHORT STUFF MAKDGT Q> MAKDGT A O> 0 ( P@FMSBPT72 3< SKIP4AF Q>;;TERMINATE LINEP PDATBYTZ P@FMSBPT7d Q>n $CURFCBx PCURLEN9 : X; ;;IF SUBTRAHEND < 256, ZERO UPPER BYTE MKDGT2&DIRDSP PDIRSEC 'DATBYT %> 0 ; DGTLP2QTMP1 SDIRSEC > QTMP2 SDIRDSP DDGTXIT" PTMP2, &TMP16 3@ EDGTLP2J X;T DGTXI$TC^ %DATBYTh P@FMSBPT7r 3| : X; @X; PARSE A FILE NAME WITH WILD CARD CHARACTERS ('*' AND '?') X; GETNAM23;;look for ">" in Q@ICBALZ7;;the start of R> >;;the filename FGETNAM 1 HGETNAM;;branch always X; GETFNM$CURFCB %$>i Q>i SETDIR 3 Q@ICBALZ7& 30 R> :;;DEFAULT DIRECTORY?: HGETNAM2D 1N 'TMP1X %DEFAULTb 'ICDNOZl Cv PICDNO9 SETUPD QCDIREC %CDIREC SETDIR %TMP1 X; GETNAM$> 3 AFTSTRQ@ICBALZ7 R> * H$TSTPER Q> ? 3 QLOOPPFNAME 9 2 ITOXITC;;END OF EXTENSION? "PERFND(>;;END OF FILE NAME?* HQLOOP;;NO MORE -?-S4 FAFTSTR> X;H TSTPERR> .;;A PERIOD?R 4HTSTCHR;;IF NOT, CHECK FOR INDIVIDUAL CHARACTERS\ Q> ;;IF SO, FILL WITH S$PACESf 3p HPERFNDz X; TSTCHRR> ? &DENDCHR;;IF < '?', CHECK FOR DIGIT 1R> Z;;ELSE, UPPER CASE LETTER, '?', OR '@'? DGOTCHR R> _ *DENDCHR;;IF CARET, BACKSL. OR BRACKETS -R> z;;LOWER CASE, ACCENT OR UNDERSCORE? DGOTCHR %ENDCHR($> ;;IF FIRST CHAR, ERROR "FERRCHR;;NO BYTES IN FILE NAME R> 0;;ELSE, A DIGIT? (DFILLNM;;IF NOT, THIS IS END OF NAME R> : EFILLNMX;GOTCHRPFNAME 9$3.28 GAFTSTRBX;LTOXITCQ@ICBALZ7VTSTDIRR> :;;look for MYDOS`FMYD$IR;;or SpartaDOSjR> >;;directory separatort HXITCHR~MYDIR'TMP2 SFDIR;;ELSE, FIND FILEEFNER1;;NO SUCH FILE TONXDR FFNER1 %TMP2 HGETNAM'FNER1Q>;;IF NOT, RETURN ERROR 174 ,;;BIT ABS (SKIP 2 BYTES)X;ERRCHRQ> $!AEXITX; FILLNM5 Q> ;;spaceFILLLPPFNAME 92( GFILLLP27< !TSTDIRFX;P7X; RETURN WITH NON-ZERO FLAG IF FILE IS A DIRECTORYZX;d(TONXDRQ>;;FILE FOUND, A DIRECTORY?n GETFLAGx"FTONXIT;;IF NOT, SET ZERO FLAG4QDIRBU$F8;;YES, MOVE POINTERS TO THE NEW LEVEL PDIRBAS9QDIRBUF8PDIRBAS9Q>;;AND CLEAR ZERO FLAG TONXIT:X;8X; ENTER A NAME INTO THE DIRECTORY AT DIRBUF[DIRDSP]X; ENTNAME6$>  %DIRDSP2NAMELPQFNAME 9;;LOAD T$HE MASK CHARACTERR> ?'HSTORIT;;IF NOT '?', SAVE IT AS IS!8"6,3DNOSTOR;;IF CY CLEAR, LEAVE CHARACTER UNCHANGED6,Q> ;;ELSE, IF CY SET, CONVERT '?' TO ' '@STORITPDIRBUF8J NOSTOR3T2^ GNAMELPh8r %DIRDSP|XITCHR$CURFCB:$X;)SFDIR WBITMP;;INSURE BIT MAP IS SAFE$> &HOLFN &CURFNO X; INXX; STX DAUX2 X; INXX; STX DAUX1X; LDX #READX; STX DCOMNDBX;The above removed for space (found an easier way, see below)8 SYSSET;;SET UP POIN$TERS, ETC. FOR A NEW DISK ACCESS QICDNOZ RRAMDKU&.FCSFDIR;;IF RAMDISK, FORGET DENSITY CHECK!0 $CURFCB;;don't read boot sec:"QDIRBAS9;;if in subdirectoriesD$R>i;;but allow if first readN HCSFDIRX%>;;Else, read thebQ>;; firs$t bootl,;; sector (#1).v DKIO;;X;This is the easier way. GERRX( INVUNIT;;UPDATE DRIVE CONFIGURATIONX;0CSFDIR#CURFNO;;READ NEXT 16-BYTE DIR. BLOCK QCURFNO/ BSECDS;;CONVERT TO SECTOR AND DISPLACEMENTXITCHR1EXITCHR%HN$OREAD;;IF DISP>0, PROCESS BLOCK# RDIRBK;;IF DISP=0, READ SECTORX;NOREAD%DIRDSP QDIRBUF87FFNDOLD;;ZERO IS END OF DIRECTORY (NO MORE ENTRIES) ;GFNDOLD;;NEGATIVE IS EMPTY SLOT (MAY HAVE MORE ENTRIES)M>;;preserve lock flag  R>;;is$ this DOS 2.5 + file?*HNOD25;;nope4Q>A;;otherwise, kludge the>NDIRBUF8;;flag to make $42HPDIRBUF8;;and save lock.R NOD25M>\8HCSFDIR;;IF OPEN/CREATE FILE, IT IS NOT REALLY HERE!f$> pCPNXCHQFNAME 9zR> ?#FWCMTCH;;EVERYT$HING MATCHES '?'RDIRBUF84HCSFDIR;;IT DOES NOT MATCH, LOOK AT THE NEXT ONE WCMTCH32 GCPNXCH,*DXITCHR;;ENTRY FOUND, RETURN WITH CY=0X;FNDOLD$HOLFN9IKPOLD;;IF AN EMPTY SLOT IS ALREADY FOUND, DO NOTHING $CURFNO5&HOL$FN;;ELSE, SAVE THE SLOT NUMBER (FIRST EMPTY!) KPOLD>2GCSFDIR;;IF NOT END OF DIRECTORY, KEEP LOOKING ERRX;$5EXITCHR1;;ELSE, ENTRY NOT FOUND, RETURN WITH CY=1.X;8X; DOS I/O ROUTINESBX;LX;VX; DISK SECTOR I/O ROUTINES`X;j!WRDISK;;;$FMS DISK WRITE ENTRYt0RWDISK%FMSBPT;;DATA SECTOR READ/WRITE ENTRY~QFMSBPT BUFSETQCURSEC9 %CURSEC9 FMDKIO6 $DUNIT (RAMDKU FRDKIO185QSECSIZ9>7 !DKIO RDKIO1!RDKIO;;was moved...X;EXTEND AL$LOC( QFCBOTC92V?< DREWRITF "FCBOTC9P WTRICKZ !WRTTSTdX;nREWRIT%LNKSEC9x QLNKSEC9 SAVLNKWRTTSTGRTBADF #SECCNT9 HTONXT#SECCNT9X;$TONXTQLNKSEC9;;MAKE NEXT SECTORPCURSEC9;;NEW CURRENT SEC.QLNKSEC$9PCURSEC9Q>PLNKSEC9;;ZERO LINKPLNKSEC9(LENSETPCURLEN9;;ZERO CURRENT OFFSETQDLINK;;GET THE LINK LOC.PMAXLEN9;;MAKE IT MAX. LEN.",;;CLEAR CY FOR LATER READ,:6X;@RDNXTSQFCBFLG9J FCHASETX;^WRNXTSQFCBFLG$9h GEXTENDrT?| IRDNXTST? PFCBFLG9 WRDISK IRDNXTSX;8RTBADF!HWERR;;RETURN HARDWARE ERROR CODE IF PRESENTX; SAVLNK5C %DLINK P@FMSBPT773 P@FMSBPT73 QCURLEN9&NOBITP@FMSBPT70 %FCBOTC9:GLEN16;;16$-BIT LENGTH?D QFCBFNO9NT?XT?b %DLINKl L@FMSBPT7v P@FMSBPT7LEN16!WRDISKX;WTRICKQLNKSEC9 PSAVSEC9QLNKSEC9PSAVSEC9 &LSTIOCB QCURSEC9 PLSTSECQCURSEC9PLSTSEC !WRDISKX;INSTRT INITYP $X;CHASEQLNKSEC9 LLNKSEC9* FNOLINK4 TONXT;;SET CY=0, FUNC=READ> RWDISKH4GRTBADF;;CANNOT READ SO BAD FILE NUMBER(ERR=164)R %DLINK\QFCBOTC9;;16-BIT LINK?fL>p GLNGLNKz Q@FMSBPT7V?V? RFCBFNO9 HXLINKEDQ>$LNGLNKM@FMSBPT7PLNKSEC93 Q@FMSBPT7 PLNKSEC93 Q@FMSBPT7 PMAXLEN9 DRDXIT,:X;$XLINKEDQICCOM9.R>FMTCMD;;IS THIS A FORMAT?8 HFNOERRB NOLINK;L:VX;`%X; READ OR WRITE A DIRECTORY BLOCKjX;tRRDIRQFCBFNO9~$X;SDIRBKPCURFNORDCFNOQCURFNO BSECDSX;1RDIRBK WBITMP;;TAKE CONTROL OF SYSTEM BUFFER, ;;LDA # (SKIPS 1 BYTE) WDIRBK; RWDBK6$CURFCB;;PUT FCB NO. IN X&&DIUNIT;;SAVE THE DIR. BUFFER IOCB SYSSET,  QDIRSEC O$DIRBAS9?(QDIRBAS92!O>;;MULTIPLE DIRS. REQ. THIS<8FSYSRW FMDKIOP IDRDXITZ3Q>;;BIT MAP R/W ERROR, RETURN SYSTEM ERR. CODEd ;;SKIP 2 BYTESnX;xFNOERRQ> PDSTATS !HWERR;;FILE NUMBER MISMATCHX;+X; READ OR WRITE THE$ DISK VTOC (BIT MAP)X;RBITMPQCURMAP RICDNOZ.FMAPXIT;;IF WE READ WHAT IS ALREADY THERE!9 WBITMP;;ELSE, REAL I/O, SAVE CURRENT BUFFER CONTENTSX;Q>?'ZMAPPMAPBUF8;;THEN ZERO ENTIRE 512#PMAPBUF8;;BYTES OF MAP BUF.1$ HZMAP",,4 RWBMAP;;THEN READ 128 OR 256 BYTES OF VTOC DATA6X;@%>J8'DIUNIT;;INDICATE MAP IS LOADED (NOT DIRECTORY DATA)T1'MAP2;;INDICATE NO DATA IN SECOND PAGE OF MAP^3h&'CHGMAP;;INDICATE MAP IS UNCHANGEDr3| 'MAP2MOD 'CURMPX;%8MAPCLRPCURMAP;;AND SAVE DRIVE NUMBER MAP APPLIES TO MAPXIT:X;WBITMPQCHGMAP0FMAPCLR;;IF MAP NOT CHANGED, SKIP WRITING IT PDUNITFMTMAPQ>!PCHGMAP;;ELSE, MARK IT UNUSED PCURMAPQDUNIT;;save drive #5 ;;;SET CY TO IND%ICATE A WRITE3 RWBMAP;;AND CALL THE READ/WRITE SECTOR ROUTINE7;;restore drive #& PDUNIT0X;:WRNXTMQMAP2MODD)HNOMAPI2;;IF THE PAGE BUFFER IS CLEANNQ>;;JUST EXIT, ELSEX5b QMAP2l #MAP2MODv;)EMUSTWM;;WRITE IT TO DISK (CY IS SET%)X;9RDNXTMRMAP2;;READ A PAGE INTO THE SECOND PAGE BUFFER.FNOMAPI;;IF IT IS ALREADY THERE, JUST EXIT54 WRNXTM;;ELSE, WRITE CURRENT PAGE (IF NECESSARY)7;; AND READ IN THE NEW ONE5.,;; BY FALLING INTO MUSTWM WITH CY CLEAREDX;% MUSTWM5Q>MAPBUF %>MAPBUF 3 BUFSET;;SET UP BUFFER POINTERS FOR SECOND PAGE 7;; OF VTOC BUFFER# MAPIOC;;ISSUE I/O OPERATION(S) 7*7PMAP2;;UPDATE ID FOR CONTENTS OF SECOND PAGE BUFFER4 NOMAPI:>X;H9RWBMAP SYSSET%;;SET UP BUFFER POINTERS FOR SYSTEM I/ORQ>\ MAPIOC6f5p$zQSECSIZ9>7(>;;256 BYTE SECS? FMAPDDS-T?;;128, CHANGE PAGE NUMBER TO PAIR NUMBERMAPDDSN>; O>h?!(>;;128 OR 256 BYTE SECTORS?2FDDMAPX;;IF 1%28, READ 2 SECTORS TO FILL BUFFER Q>h86& SYSRW;;READ OR WRITE FIRST SECTOR QMAPBUF$.R>;;IF DOS 2.0 DISK, ONLY ONE SECTOR EVEN.!DXITMBF;; IN SINGLE DENSITY!8 STEPBPB1LDDMAPXQ>hV8`6j/ SYSRW;;READ OR WRITE SECO%ND OR ONLY SECTORt XITMBF8~NOMAPI2QICDNOZ.PDUNIT;;RESTORE USER DRIVE NUMBER TO DUNIT0:;;SINCE THIS MAY HAVE BEEN ON ANOTHER DRIVE!X;/SYSSETQ>MAPBUF;;SET UP BUFFER POINTERS%>MAPBUF !BUFSETX;EX; ROUTINE TO STEP TO THE% NEXT DIRECTORY ENTRY (UNTIL WE RUN OUT)X;BSECDS%> 'DIRDSPV? WDIRDSP V? WDIRDSPV?(9WDIRDSP;;(FILE NUMBER MOD 8) * 16 IS OFFSET IN SECTOR2+PDIRSEC;;FILE NUMBER/8 IS SECTOR OFFSET<X;FR>;;END OF DIRECTORY?P1Z6EBSECXT%;;IF SO, RETURN CARRY SET (VALUES ARE BAD!)d3WDIRDSP;;FINAL SHIFT SO NUMBER IS *16 (NOT *32)n BSECXT:xX;X; DOS ALLOCATION ROUTINESX;X;!X; FREE A SECTOR FOR LATER USEX;1FREE RBITMP;;MAKE SURE WE HAVE THE RIGHT MAP PCHGMAP9FM% TFRE#MAPBUF;;BUMP LOW BYTE OF FREE SECTOR COUNTHFREE0;;IF NO CARRY#MAPBUFFREE0 FNDBIT5 QTMP2 FSBMP1 'TMP2RCURMP;;BEFORE FIRST HOLE?"ESBMP2;;NO, LEAVE UNCHANGED,PCURMP;;YES, NEW FIRST HOLE6SBMP2 RDNXTM@ %TM% P2J"VMAP2MOD;;MARK MAP PAGE2 DIRTYT7^LMAPBUF8hPMAPBUF8r:|X; SBMP17 LMAPBUF8 PMAPBUF8:X;3X; FIND BIT ASSOCIATED WITH A SECTOR ON THE DISKX;FNDBITQCURSEC9M>;;EXTRACT THE BIT NUMBER?;Q>.FREE% 1W?;;POSITION CARRY TO THE BIT TO FLIP 1 IFREE1 5;;SAVE THE BIT MASK& X;0 QCURSEC9: ,D $O> ;;ALLOW FOR 10 BYTE HEADERN ?;;SAVE LOW BYTEX QCURSEC9b O>;;PROPOGATE CARRYl W?;;fix 65535 sector bugv PTMP2 C W? VTMP2 W? V% TMP2 W? ? X; 7;;RESTORE THE BIT MASK : X; )X; ALLOCATE AN UNUSED SECTOR TO A FILE X;!ALLOC RBITMP ! PCHGMAP!%> !Q>*! PTMP24!!ALL1RMAPBUF8;;ANY BITS LEFT?>!HSECFN1;;IF SOH!3R! HALL1\!X;f!;p! QMAPBUFz! SCURMP!;!S% >! PTMP1!ALLCKGALGONE! QCURMP! PTMP2! RDNXTM!Q>!?!ALL2RMAPBUF8!1HSECFN2;;IF FREE SECTOR IN SECOND PART OF MAP!3! HALL2"%#CURMP;;TO NEXT SECTOR OF BIT MAP" "TMP1" IALLCK$"X;."ALGONE"CURMP8"#DFERRQ>;;DISK FU%LL ERROR CODEB"%!AEXIT;;IF THIS IS IT, ERROR-EXITL"X;V" SECFN1;`"$>;;I.E., -8*10 - 1j" ALL3W?t"2~" RMAPBUF8" DALL4"," HALL3"ALL4NMAPBUF8" PMAPBUF8" IALL7"X;" SECFN2;"$>;;I.E., -8*10 - 1" ALL5W?"2"RMAPBUF8# DAL%L6 #,# HALL5#ALL6VMAP2MOD(#NMAPBUF82#PMAPBUF8<#X;F# ALL7CP#T?Z# UTMP2d#T?n# UTMP2x#T?# UTMP2# PTMP1#A# OTMP1# $CURFCB# PLNKSEC9# QTMP2#O>#PLNKSEC9#DECCNTQMAPBUF# HNOBOR#"MAPBUF#NOBOR"M%APBUF$,$:$X;"$X; DOS MISC. SUBROUTINES,$X;6$X;@$%X; SET UP STATE VARIABLES ON ENTRYJ$X;T$SETUP%ICDNOZ;;GET UNIT NO.^$SETUPW&CURFCBh$@r$2|$2$1&STKPSV;;SAVE POINTER TO RETURN ADDR ON STACK$'SETUPD'DUNIT;;COPY UNIT NO. TO DCB$Q%>$ )RAMDKU$4FUFIXED;;RAMDISK SECTOR SIZE IS ALWAYS 128 BYTES$QSECSIZ8$9FINVUNIT;;IF NOT VALID UNIT, TEST FOR CURRENT DENSITY$@UFIXEDPSECDAT;;OTHERWISE, STORE CORRECT DENSITY INFORMATION$V?$W?$W?$4L>};;AND UPDATE LINK POSITION IN% THE DISK SECTOR$ PDLINK%X;% $CURFCB%"%BUFNO9;;GET THE BUFFER NUMBER&% HRSETUP0%#%FILES;;IF ONE IS NOT ALLOCATED:%3D% SFORB1N%6FNOSECB;;ALLOCATE ONE, OR ABORT THE OPERATION NOW!X%QBUFFLG8b% HSFORBl%Q>v%PBUFFLG8%C% PBUFNO9%%RSETUPQDOSEND;;==SBTABL%3PFMSBPT;;STORE THE BUFFER POINTER FOR THIS FILE%4QSBTABU8;; IN THE ZERO PAGE POINTER "FMSBPT"%PFMSBPT%:%X;%(INVUNIT JSTRD;;TEST FOR DRIVE STATE%5HUFIXED;;IF IT IS ACCESSABLE, RETURN REAL DENSITY%X;%%0NOUNITQ>;;RETURN ST=160, DRIVE NOT PRESENT% ;;SKIP TO JMP INSTRUCTION&3NOSECBQ>;;RETURN ST=161, NO MORE FILE BUFFERS & !AEXIT&X; &+X; REMOVE DOS POINTER FROM BOOT SECTORS*&X;4&'TDDOS TSTDOS;;MUST WE UPDATE BOOT?>&HTDEXIT;;NO, RETURN%H&1DELDOS%>;;YES, REMOVE DOS POINTER FROM BOOTR& FUPDBT\&X;f&&X; ADD DOS POINTER TO BOOT SECTORSp&X;z&SETDOS'DOSLOC&PDOSLOC& %SECDAT&UPDBTQDUNIT& RRAMDKU& FTDEXIT& 'SECDAT& QDEFAULT&5&%>& QFCBOTC9&GNOAND;;LONG LE%NGTH FIELD?&!%>;;IF NOT, USE ONLY 10 BITS&NOAND'ANDCD'Q>BOOTFL'%>BOOTFL' BUFSET$'%>.' 'DAUX28' D12303B' 'DAUX1L'$>V' &DEFAULT`';j' DKIO2t' STEPBP~' )BOOTL' HD1230'7' PDEFAULT' %ICDNOZ' 'DUNIT'QSECSI%Z8' PSECDAT':'X;'STEPBPQDBUFLO'N>' PDBUFLO( GTSTEOD ( #DBUFHI(X;(TSTEOD%DAUX1((:2(X;<(%X; TEST FOR FILE NAME = 'DOS.SYS'F(X;P(TSTDOS%> Z( $DIRDSPd(TDLOOPQDIRBUF9n(NDOSSYS 8x( HTDEXIT(2(3( HTDL%OOP(TDEXIT$CURFCB(?(:(X;(DOSSYS ADOS SYSA(X;(1X; FIND AT LEAST ONE FILE MATCHING GIVEN NAME(X;(1LFFILE GETFNM;;EXTRACT FILE NAME FROM BUFFER('TMP2;;SAVE IT FOR -RENAME-)+ SFDIR;;FIND FIRST MATCHING FILE IN DIR)"Q>;;IF %NONE, RETURN ERROR 170)EAEXIT;;ELSE, RETURN"):,)X;6)%X; RETURN ERROR IF FILE IS LOCKED@)X;J)TSTLOKQ> ;;CHECK BIT 5T) GETFLAG^) FTDEXITh) Q>;;FILE LOCKED ERROR = 167r) ;;SKIP 2 BYTES|)X;)X; RETURN WITH NO ERROR)X;)DONEQ>;;NOR%MAL COMPLETION)X;)-X; RETURN ERROR CODE IN ACC TO CIO (IN Y))X;)(AEXIT$STKPSV;;RESTORE STACK POINTER)B))$CURFCB;;RESTORE IOCB OFFSET TO X-REG)"PICSTA9;;RETURN STATUS IN IOCB)?;;RETURN STATUS IN Y-REG)&QDATBYT;;POSSIBLY RETURN DATA HER%E)")>;;SET CY FLAG APPROPRIATELY*:*X;*$X; RETURN HARDWARE ERRORS TO CIO&*X;0*$HWERRQ>;;fix VTOC updating bug:* PCURMAPD* PCHGMAPN**QDSTATS;;LOAD REAL DISK I/O ERROR CODEX*'HAEXIT;;AND RETURN IT TO THE CALLERb*X;l*-X; RELEASE FCB AND R%ETURN NO-ERROR STATUSv*X;*FREDON$CURFCB*7%BUFNO9;;FINISHED WITH THE SECTOR BUFFER, RETURN IT*&FDONE;;IF NONE ALLOCATED, SO WHAT!*Q>*4PBUFNO9;;OTHERWISE, IT'S NOT ALLOCATED ANY MORE!*PBUFFLG8* FDONE*X;*+X; TEST OR CLEAR A BIT I%N THE FLAG BYTE*X;*GETFLAG%DIRDSP* MDIRBUF8*:+X; +1X; SAVE FLAG BYTE AND WRITE BACK TO DIRECTORY+X; +SAVFLAG%DIRDSP*+ PDIRBUF84+ !WDIRBK>+X;RWISE, IT'S NOT ALLOCATED ANY MORE!*PBUFFLG8* FDONE*X;*+X; TEST OR CLEAR A BIT I$4D4:MDUP1.M65"X; resident portion of DUP code>D4:MDUP2.M65>D4:MDUP3.M65X; DUPEND DUPLEND) UPENDDUPBASEMSLENDUPENDMSBASEX;" MENUSLAD3L NMLMAP X;*ORIGIN;;FIRST BYTE AFTER MDOS CODEX;>D4:MDUP1.M65"X; resident portion of DUP code>D4:MDUP2.M65>D4:MDUP3.M65X; DUPEND DUPLEND(> ;X;v.4.53/3 mods. by David R. Eichel 11/30/89 2:19 pm%X;SAVE #D4:MDUP1.M65 MYDOS module9X; Copyright 1984, Charles Marslett, Wordmark Systems(X;2IX; Permission is granted by the author for any use whatsoever of this<HX; code, so -"long as this notice remains in the source code, and soFLX; long as the source to this routine, however modified or unmodified,P.X; is made available for a nominal cost.ZX;dX; DEFINED VALUESnX;x CR EOFX; OPEN GETREC-# GETCHR PUTCHR CLOSE RENAME DELETE! LOCK# UNLOCK$ FORMATX;X; ROM AND RAM ADDRESSESX;CARTST"X;, AUDF16AUDCTL@ SKRES J SERIN TSEROUT ^ IRQENh SKCTLr-$ PBCTL|X;FASCIIؐ IFPٚEDITRV DSKIOS CIOVV SIOVYSETVBV\CIOINVnX; WARMST DOSVEC  DOSINI  POKMSK BRKKEY RAMLOX;& DUNITZ!0 DCMDZ": DBUFZ$D DLENZ-%(N DAUX1Z*X DAUX2Z+b DAUX3Z,lX;v LMARGNR RMARGNSX; FR0Ԟ VECTORԨ HDBUFֲ BUFADڼ BUFLEN FNPTR TEMP TEMP2X; INBUFFX;VSERIN  VIMIRQCDTMV3 CDTMF3**-&SHFLOK4 RUNAD>INITADHMEMTOPR MEMLO\$DVSTAT;;SYSTEM STATUS BUFFERfX;pDDEVICz DUNIT DCMD DSTAT DBUFDTIMEO DLEN DAUX HATABSX; IOCB@ ICDNOA-' ICMDB ISTATC IBUFD ILENH IAUXJX;$X; FMS ENTRY POINTS.X;8GX;Several of the following equates were changed during optimizationBX; of the DOS code.LX;V FILES `(RAMDKU ;;LOC OF RAM DISK DRIVE NOjDF-(UNIT t BSIORi~ WRCMDp STATEDKTYPEDRVDEFFMINITMDINITMAPBUF HDTAB @X;WOTDCB = $0B1A ;No longer used by DUP, moved to MDOS1.M651CONFIGR$ ;;CONFIGURE DRIVE SUBROUTINE ENTRYX; X;-)OTHERS IN THE MDUP.M65 FILEX;X;  ! RESEND;;START OF FREE MEMORYX;(S;;patch into dos here2!INIT;;DUP INIT ENTRY POINT<X;FX; PROGRAM AREAPX;Z ORIGINdX;n X; INITIALIZE MYDOS INTERFACExX;INITQ>DUPENTPDOSVE-*CQ>DUPENT PDOSVECX;Q> PFNAMEQ>  *STATE/HCKMDOS;;IF WARM START CHECK FOR DUP LOADEDX;X; COLD START CODEX;!PSTATE;;SET MODE TO WARMSTARTX; LDX #$10)X; JSR SOPEN ;RUN AUTORUN.SYS FILE"X; .BYTE 6,-+X; .BYTE 396X; .WORD AFN@X; BMI CLOSXJX; JSR CLOSXTX; JMP (RUNAD)^IX;The above was changed to the below to allow multiple AUTORUN files.hX; D1:*.ARx x = 0-9rX;|Q> 0;;Re-set AFN #PAFN;; to 0.MULTIRUN;;$>-,;;Allow multi-Q>(;; AUTORUNsPB9;; using MyDOS'sQ>4AFN;; XIO 40 cmmd. PD9;; Q>5AFN;; PE9;;Q>;;Allow RUN &PI9;; INIT vectors. V;;!GCLOSX;;Br.=*.AR# not found.#AFN;;QAFN;;R> 9--;;Done all 10?&DMULTIRUN;;Br.=not all.0X;:X; CLOSE IOCBS 10 AND 20DX;NCLOSX CLOS20XCLOS10$>;;CLOSE IOCB 10b ,;;SKIP 2 BYTESlCLOS20$> ;;CLOSE IOCB 20v!CLOS2Q>CLOSE;;CLOSE ANY IOCBSCMDPICMD9 !CIOVX;DBUF10$>-.DEFBUFPIBUF9C PIBUF9 CKMDOS:X;8AFN AD1:*AR0A=;;"AUTORUN.SYS" is now meaninglessCX; Moved AUTORUN FN so SUPERARC will not think this is >=4.3 DOSX;X; OPEN FILEX; X; CALLING SEQUENCE:X; JSR SOPEN X; DB AUX-/*X; DB CMD4X; DW BUFFER ADDRESS>X;H SOPEN;R ;;LDA #IMM OPCODE\X;f&X; DO A READ/WRITE TYPE I/O REQUESTpX;zX; CALLING SEQUENCE:X; JSR DOIOX; DB IOCBNOX; DW BUFFER LENGTHX; DB CMDX; DW BUFFER ADD-0RESSX; DOIO,7 PRAMLO7 PRAMLO%> Q@RAMLO7 DDOIO1 PIAUX9 EXTRCB$ DOIO1>. 38 Q@RAMLO7B PILEN9L 3V Q@RAMLO7` PILEN9j XTRCB3t Q@RAMLO7~ PICMD9 3 Q@RAMLO7 PIBUF9 3 Q@RAMLO7 PIBUF9 -1C , ORAMLO ? Q> ORAMLO 5 C 5 !CIOV;;DO I/O REQUEST( X;2 (X; IF NO DUP.SYS, INCREMENT DRIVE NO.< X;F RETRYOS#DUPSYSP QDUPSYSZ M>d R> n DRTYOSVx HGOTO1 RRAMDKU FRTYOSV GOTO1Q> 1 PDUPSYS RTY-2OSV> QDKTYPE 19 FRETRYOS HNOWMS X; X; LOAD PROGRAM FUNCTION X; LDFILE LDMEM $> % TOVECT;;LOAD PROGRAM OR GO TO IT  ,;;skip the LDY #1 X;" *X;*************************************, X;6 (X; STANDARD EXIT POINT FOR PROGRAM-3S@ X;J *X;*************************************T X;^ !X; RESTORE DOS/DUP INIT VECTORh X;r DUPENT%>| SAVERR'CBSAV *STATE KGODOS INOWMS CLOS10 SOPEN  ;;WRITE MEM.SAV FILE OPEN NMSAV GNOWMS DOIO   MSLEN-4 PUTCHR MSBASE NOWMS CLOS10 # SOPEN;;GET DUP.SYS INTO MEMORY&  0  ': DUPSYSD GRETRYOSN QDOSINIX PINISAVb QDOSINIl PINISAVv GODOS CLOSX !DOSOS;;THEN START IT UP X; X; X; RUN AT ADDRESS X; )TOVECT!@VE-5CTOR:;;TO 'RUN AT' ADDRESS X; X; LOAD MEM.SAV IF NEED BE X; LDMEM*STATE;;LOAD MEM.SAV? INOLDMS X; $>  SOPEN   OPEN NMSAV* GNOLDMS4 X;> DOIOH   R MSLEN\ GETCHRf MSBASEp X;z NOLDMS!CLOS20 X; NMSA-6V AD1:MEM.SAVA= EC AE:A DUPSYS AD1:DUP.SYSA= OPT  "DUPFLAG ;;DUP RESIDENT = $80 INISAV FMINIT +CBSAV ;;ERROR CODE FROM PROG EXECUTED FNAME  !';;ALLOW FOR 40 CHAR DEF DIR X; (RESEND;;ALLOW FOR 3 FILE BUFFERS-7 +DRIVERS;;ALLOW 2K FOR RESIDENT CODE MSBASE X; OPT  "DUPFLAG ;;DUP RESIDENT = $80 INISAV FMINIT +CBSAV ;;ERROR CODE FROM PROG EXECUTED FNAME  !';;ALLOW FOR 40 CHAR DEF DIR X; (RESEND;;ALLOW FOR 3 FILE BUFFERS,;S ;X;v.4.53/3 mods. by David R. Eichel 12/23/89 6:39 pm$X;SAVE#D4:MDUP2.M65 MYDOS module9X; Copyright 1984, Charles Marslett, Wordmark Systems(X;2IX; Permission is granted by the author for any use whatsoever of this<HX; code, so l19ong as this notice remains in the source code, and soFLX; long as the source to this routine, however modified or unmodified,P.X; is made available for a nominal cost.ZX;dKX;====================================================================1:==nX;x-X; START OF NONRESIDENT PORTION OF DUP.SYSX;.DATAP;;ALLOCATE BUFFER FOR BIT MAP, ETC. DELIM!PAR2P;;another bug fixed RP PAR3PX; DATA UNNO PTR PTRSAV IPTR IPSAV CBYTE SEC1;TOR CSRC CDES" CPYTYP, SWPFLG6 RCNT@ SECSIZJ FNPTT FNPT2^!PARP;;REAL PARAMETER (LAST)h DUPBASE rDOSSYS AD1:DOS.SYSA=|X;2X; CLOSE (BRUTALLY) ALL IOCBS AND REOPEN SCREENX;INITIO CIOINV1<$>" SOPEN;;OPEN SCREEN AS IOCB #0   OPEN EC&CDTMV3;;CLEAR TIMER #3&CDTMV3%>Q>$PCDTMF3;;SET TIMER NOT DONE FLAG SETVBVWAITIMQCDTMF3;;DONE?!HWAITIM;;NO, CONTINUE LOOPING&:0X;: X; DISK UTILITY PRO1=GRAM ENTRYDX;N DOSOS,X-b$>l&BRKKEY;;ENABLE BREAK KEYvX;Q>MDINITPDOSINIQ>MDINIT PDOSINIX;Q>PLMARGN;;SET MARGINSQ>' PRMARGN QDUPFLAG LSTATEM>R> HNOSWF  PWARMST NOSWFQ>@  1>LSTATE*!PSTATE;;ELSE, SAY IT WAS DONE4Q>> LPOKMSKH#PPOKMSK;;ALLOW BREAK INTERRUPTSR PIRQEN\ INITIO;;CLOSE ALL FILESfX;p QSTATEzM> FSHMEN+ ERRXIT;;MEM.SAV ERROR CAN NOW BE SHOWN- AError loading MEM.SAV or memory!A==1?X;SHMENQDFUNITL> 0 PDEFAULT$>%>DKSLPQ> ;;spacePD1STAT9 PD1STAT9PD1STAT9PD1STAT9 )RAMDKUHCKHCD;;IF NOT RAM DISK$Q> R. HSETUNI8X;BCKHCDQHDTAB8LFGENDCD;;IF NOT HARD DISKVQ> H`1@SETUNIPD1STAT9j HDKUNINtX;~GENDCDQDKTYPE8 FNXTDKSV?;;DOUBLE DENSITY?Q> SEDKSNGD;;NO, SINGLEQ> D;;YES, DOUBLEDKSNGDPD1STAT9QDRVDEF8V?Q> - DDKSSDQ> =DKSSDPD1STAT9 DKUNINC L> 0 PD1S1ATAT9 NXTDKS0(020<0F1P HDKSLPZ PRINTd };;CLEAR SCREENnb AMYDOS 4.53/3- Copyright 1988,A;;Just the name's been changed, to protect the guiltyx =ADisks A0D1STAT A1S 2S 3S 4S 5S 6S 7S 8S A= AD: = DADEF1BAULT A1:A=Q>FNAME$>FNAME PRTMSGX; PRINT =) A1-8.Dir of D1:-D8: *. Dir of D:A=+ AA. Disk Directory K. Save MemoryA=+ AB. Run Cartridge L. Load MemoryA=. AC. Copy File(s) M. Run at AddressA=,1C AD. Delete File(s) N. Load MEM.SAVA=. AE. Rename File(s) O. Change Config.A=+ AF. Lock File(s) P. Set DensityA=". AG. Unlock File(s) Q. Make DirectoryA=,. AH. Write DOS Files R. Pick DirectoryA=6- AI. Initialize Disk S. Set1D RAMdisk #A=@/ AJ. Duplicate Disk V. Set Verify FlagA=J A A==T %CBSAV^ IMENUSLh% CIOER1;;IF LOAD ERROR, REPORT ITrX;|X; SELECT MENU FUNCTIONX;MENUSL$>B2&OPT;;OPT=00 IF NO OPTIONS &SWPFLG)&CBSAV;;FOR DIR S1ECANS, SKIP NO EXTNS.! CLOSX;;CLOSE IOCBs 10 AND 20$>0 CLOS2;;AND IOCB 30 PRINT( ASelect Item ( for menu):A=Q>@;;FORCE UPPER CASE PSHFLOK LSTATE!PSTATE;;SAY DUP.SYS IN MEMORY& CHRGET0R>: HCKITEMD !SHMENN1FX;XCKFDIRR> 1b DCKFDDl !FASTDIRv CKFDDR> * HBADITM !FASTDDX;CKITEMR> 9 DCKFDIRR> ANFUNC EBADITM S> A EITEMVBADITMQ>NFUNC ITEMVT?? QDUPJT8 PRAMLO QDUPJT8 PRAMLO +!PRTMEN;;GO TO M1GENU EXIT (WITH MESSAGE)*X;4 TCOMND > UCOMND HNSI ANo such item!A==R !MENUSL\X;fDUPJT DIRLST=STCARp CPYFIL=DELFILz RENFIL=LKFIL ULKFIL=WBOOT FMTDSK=DUPDSK SAVFIL=LDFIL1H BRUN=MEMSAV CONFGR=CHDISK MKDIR=SETDIR RAMDRV=TCOMND UCOMND=VERIFYNFUNC DUPJT  NSIX;%X; * AND 1-8. FAST DIRECTORY LISTX; FASTDDPPAR Q> : PPAR$ HDOFDD. X;8 1IFASTDIRPPARB Q> :L PPARV DOFDDQ> *` PPARj PPARt Q> D~ PPAR Q> 'PPAR;;fix the 174 errors in menu PCPYTYP PDELIM HDODIRL X; X; A. DIRECTORY LIST X; /DIRLST AFiles to list, Destination?A== Q> 1J PCPYTYP GETFN DEFPAR DODIRLQ>PAR %>PAR DBUF10( $>2 &CSRC;;IOCB10 IS SOURCE< $ OPDIR;;OPEN IOCB10 AS DIRECTORYF X;P Q>DATA& Z PBUFADd Q>DATA& n PBUFADx X; Q>& PBUFLEN Q> PBU1KFLEN X; $>;;CDES=IOCB00 QDELIM GCPY1FSP [X; LDA DELIM ;Somebody who knows what the hell is going on should look at this. Bob? GSGFCPY GETFN2 'IBUF PIBUF  SGFCPY$>  Q>GETCHR HDOCALL" X;, CPY1FSPQ>GET1LREC6 DOCALL&CDES@ COPYFJ %!MENUSL;;THEN RETURN TO CMD. LINET X;^ BADRN ERRXITh ANeed new file name!A==r CANTDV ERRXIT| 9 ANo drive or directories allowed in new name!A== X; LKMSG ALock A= ULMSG AUnlock A= DELMS1MG ADelete A= X; X; F. LOCK FILES X; #LKFIL ALock which file?A== %>LKMSG $>LKMSG Q>LOCK 'HDOCMD2;;GET FILE NAME THEN LOCK IT X; X; G. UNLOCK FILES X; &ULKFIL AUnlock which file?A==& %>ULMSG0 $>ULMSG1N: Q>UNLOCKD X;N 'DOCMD2'SECSIZ;;do mass lock/unlockX &&SECSIZ;;unless /Q is specifiedb 5l GETFNv CKDSK $OPT (> Q;;Query? FDOPRM HAFTCHK;;branch either way X; X; D. DELETE FILE(S) X; %DELFIL ADelete what file?A=1O= %>DELMSG $>DELMSG Q>DELETE X; DOCMD'SECSIZ &SECSIZ 5 GETFN CKDSK* $OPT4 ((> N;;IF '/N' THEN DO IT THE EASY WAY> FAFTCHKH DOPRM PRINTR  AAnswer 'Y' or 'N'A==\ 7f SETSCNp X;z RDFN SCNDIR ED1PELX;;IF END OF DIRECTORY QSECSIZ $SECSIZ PRTMSG Q>PAR $>PAR PRTMSG PRINT A?A= CHRGET R> Y HNODELT $>  CIOCL;;DELETE THE FILE THENNODELT!RDFNX;$ SMPLCMD5. GETFN;;GET FILE NAME8 CKDSK1Q;;VERIFY A DISK FILEB AFTCHK7LISSCMDPICMDV$>` CIOCLj QICMDtR>)~ FSETFNJDELX!MENUSLSETFNJ!SETFNMJCANTDV!CANTDVJBADRN!BADRNX;X; E. RENAME FILE(S)X;-RENFIL AFile to rename, new name?A== GE1RTFN CKDSK%PTR QDELIMR> ,  FCKNAM2R> ;;space HJBADRN( CKNAM232 Q@FNPTR7<R> :F FJCANTDVPR> >;;check for sparta typeZ FJCANTDVdR> 0n DDORENx R> z DCKNAM2DORENQ>RENAME HISSCMDX;X; Q. MAKE A DIRECT1SORYX;'MKDIR AFull directory name?A==$> &IAUXQ>";;MAKE DIR. COMMAND !SMPLCMDX;X; R. SET DIRECTORYX;1SETDIR ADirectory to be used as 'D:'?A== GETFN" CKDSK,%PTR;;DRIVE OR NULL?6)>@ DCPYDNEJQ>1T)T !ISSCMD^X;hSETFNM$>rQPTR|N> FZAPNAM%>Q> : R@FNPTR7 HALLNEW;;IF NOT SUBDIRECTORY FNDEND2%FNAME9HFNDEND;;END OF OLD DIR?PFNAME9X; ALLNEW3 FCPYDNE R@FNPTR7 HALLNEW0;;POINT BACK AT 1U':')FCPY1ST;;IF START, NO ':' TO PRESERVE&X;0 CPYNAM2: CPY1ST3D Q@FNPTR7NZAPNAMPFNAME9X HCPYNAMb !MENUSLlX;vCPYDNE ERRXIT AInvalid directory!A==X;X; SINGLE FILE (DEVICE) COPYX;TOERR1!CIOER1SGCOPY$>1V&CSRC;;SOURCE IS IOCB10 SOPEN ;;INPUT OPEN;;OPEN FUNCTION PAR;;INPUT DEVICE NAM GTOERR1 !SGFCPYX; X; C. COPY FILESX;  DUPFIL *-CPYFIL AFile source, destination?A==4Q> ;;space>*PPAR3;;DEFINE CHAR 3 OF DE1WVICE NAMEHQ>R PCPYTYP\ GETFN;;GET SOURCE FILE NAMEfX;pQ>DUPENDz PBUFADQ>DUPEND PBUFADX; QMEMTOP;S>DUPEND PBUFLENQMEMTOPS>DUPENDPBUFLENX; DEFPAR QDELIM GSFNAME GET1XFN2Q>$SFNAMEPSWPFLG. TWARMST8 QFNPTRBPIBUF L QFNPTRV PIBUF `QPAR;;DISK DEVICE?jR> Dt HSGCOPY~ Q>PAR %>PAR DBUF10X;Q> ?%> QQQPPAR281HQQQX; CWFSD$>$ OPDIR;;OPEN I1YOCB10 AS DIRECTORYX; %> CPSCL13 Q@FNPTR7( PPAR382 HCPSCL1< CPSCL21F Q@FNPTR7PR> :Z FCPSCL3d R> >;;account for sparta typen HCPSCL2x CPSCL33 'FNPT2 Q@FNPTR7 FOPINPX;)$>;;SCAN -PAR- STARTING AT 1-ST BYTEMV1ZMSKQ@FNPTR7GWCOPYB;;1 FILESPEC COPY??R> * FMVNMLR> . DWCOPYB HDOSTORQ> ;;space1DOSTORPPAR293" MVNML2,(>6 DMVMSK@ SKPPRD3JMVEXTQ@FNPTR7T FWCOPYB^R> .h&FSKPPRD;;IF A PERIOD, SKIP OVER ITrR> *| FOP1[INPR> ;;space FWCOPYBR> , FWCOPYBR> FWCOPYB3SAVBLKPPAR292(>  DMVEXT EOPINPX;WCOPY CWFSDOPINP SCNDIR *CBYTE& GOPINP0 DWCNEXT: !MENUSLDX;NWCOPYBQ> ;;spaceX HSAVBLKbWCNEXTQ>PAR31\lPIBUF0v Q>PAR3 PIBUF0X;$> %FNPT2WCNBLDQPAR29 FTERMXR> ? HSTWCC QDATA9STWCCPPAR38R> ;;space FOVWRTC3 OVWRTC2 (> DWCNBLD Q> .* PPAR3843>WCEBLDQPAR29H FTERMXRR> ?\ H1]STWCECf QDATA9pSTWCECPPAR38zR> ;;space FOVWRTE3 OVWRTE2(>  DWCEBLD TERMXQ> . RPAR38 HNOTOVP1NOTOVPQ>$OPT(> Q HNOQUERYQ> ?NOQUERYPPAR38Q>$ PPAR38.X;8 QCPYTYPB HDOONEL Q>1^PARV $>PAR` PRTMSGj PRINTt A-->A=~ Q>PAR3$>PAR3 PRTMSGQOPTR> Q HDOONE CHRGETR> Y HSKPCOPDOONEQIAUXPIAUX $>  &CSRCQ>  PIAUX9 Q>PAR %>PAR( DEFBUF21_ Q>OPEN< SCMDF GCPYERRPX;Z$>dCKFDOSQCKDTST9n RPAR39x HNOXDOS0 HCKFDOS QPAR3PDOSRNMPDOSSYSQ>` PPAR3NOXDOSQ>PAR3PIBUF0 Q>PAR3 PIBUF0X;$> &IAUX0$>01` &CDES" Q>GETCHR, COPYF;;COPY FILE6X;@SKPCOPQCPYTYPJ HTOEXITT !WCOPY^TOEXIT!MENUSLhCPYERR!CIOER1rX;|X; I. FORMAT A DISKX;FMT1050Q> HDOFMTX; FMTDSK ADisk to FORMAT:A=$ GETDN;;GET DRIVE NUMBER OR NAME1a DEFPARX; Q>PARPIBUF Q>PAR PIBUFX;%> Q@FNPTR7 PFMTDVN&X;0"X; MAKE SURE ABOUT DRIVE NUMBER:X;D PRINTN& A(Press for Enhanced Dns)A=X AType to Format Drive AbFMTDVN A0:A=lX;v 1b CHRGETR> A FFMT1050N> Y HALFMTDDOFMTPIAUXQ>$OPT;;REAL FORMAT?(> N HRELFMTW?RELFMTPIAUXX; Q>FORMAT PICMD $> CIOV;;DO FORMAT OF DISK  IALFMTD*$WBERR!CIOER1;;IF ERROR, SAY SO!4A1cLFMTD!MENUSL>X;HX; H. WRITE DOS/DUP TO DISKRX;\DUPFNM AD1:DUP.SYSA=f,WBOOT ADrive to write DOS files to?A=p GETDNzQDUPSYS5Q> 1PDUPSYS PNMSAV%> Q@FNPTR7R> : HCANWB QDEFAULTCANWBPDOSSYS1dPDUPFNMX;%1;;SET UP INITIAL VALUES OF PARMS.'OPTQ> PSTATE$X;.Q>DOSSYS8%>DOSSYSB DBUF10L"Q>;;OPEN OUTPUT=WRITE DOS.SYSV PIAUX`1 ANYDEN;;OPEN AND WRITE DOS.SYS (ANY DENSITY)j CLOS10t7~ PNMSAV1ePDUPSYSX;"X; **** WRITE DUP.SYS HERE ****X;%>pQ>DUPBASE$>DUPBASE D2B8AQ>DUPFNMPIBUFQ>DUPFNMPIBUF;;Bugs fixed RPQ>DUPEND   PHDBUFQ>DUPEND  PHDBUF(Q>1fDUPLEN2 PHDBUF<Q>DUPLENF PHDBUFPQ>ZPTEMP;;CLEAR 'RUN' FLAGd!WRDUP;;WRITE DUP.SYSnX;xX; J. DUPLICATE A DISKX;2DUPDSK ASource, Destination (Sectors)?A== GETDN%> Q@FNPTR7M>;;GET DRIVE NUMBER1g PCSRC PCDES QDELIM;;IF SINGLE DRIVE DUP.R> (FSETSSZ;;GO SET SECTOR SIZE( GETDN2;;ELSE, GET SECOND DRIVE NAME%> Q@FNPTR7M> PCDES"RCSRC;;SAME DRIVE?,#HSETSSZ;;YES, SINGLE DRIVE DUP.6$>@ &SWPFLGJ SETSSZ>T %C1qBDOS SYSBDUP SYSB1RB6C AR B7RB6C2 AR0B=CONTENTS B AREAD ME BaMDOS M65B/bMDOS1 M65BAMDOS2 M65BLMDOS3 M65BMDUP M65B!MDUP1 M65BU8MDUP2 M65B5MDUP3 M65SRC^ QSWPFLGhL>@;;SET DUP-DISK FLAGr PSWPFLG| GDODKDP PRINT( AInsert both disks, type A= CHRGETX;DODKDP CWFSD QCSRC;;POINT TO SOURCE DRIVE0 GETDEN;;IDENTIFY DENSITY OF SOURCE DISKETTE%CDES;;ELSE, TWO DRIVE D1rUP. $CSRCQDKTYPE9RDKTYPE8 FSAME 'UNNO SETDEN %CDES $CSRC& QDKTYPE90 RDKTYPE8: FSAMED ERRXITN # ADrives not compatible!A==X SAMETWARMSTb V?l PSECSIZv W? )PSECSIZ;;SET SECTOR SIZE (128 OR 251s6) &DUNIT;;READ SOURCE VTOC X; QDELIM 5 Q> > INIBMPPDATA9 PDATA9 0 HINIBMP 7;;BOOT COPY? R> (!'FBLDVTOC;;YES, BUILD IMAGINARY VTOC !R>!FRDVTOC;;NO, DOS COPY !OOPS ERRXIT;;ELSE, ERROR*! AInvalid options1t!A==4!BLDVTOC GETNUM>!)> -H! HOOPSR! PDATA\! &DATAf! GETNUMp!)> )z! HOOPS! PDATA! &DATA!%>!'PTR! 'DATA! 'DATA!Q>DATA ! PBUFAD!Q>DATA ! PBUFAD!Q>!D26BB$DATA! (DATA1u" HD26CB" $DATA" (DATA$" ED26D2." D26CB;8"U?B" NXTSCTL" HD26BBV"X;`"D26D2$DATAj" (DATAt" DD26EA~" HD26E4" $DATA" (DATA" DD26EA" D26E4T?" NXTSCT" HD26D2"X;" D26EA;"U?" ED26EA" P@BUFAD7"X;# 1vRDVTOC; # QMEMTOP# SSECSIZ# PBUFLEN(#QMEMTOP2#SSECSIZ<#PBUFLENF#X;P# QBUFLENZ#R>DUPENDd#QBUFLENn#S>DUPENDx# EENUF# ERRXIT# ANot enough memory!A==#X;#NXTSCTED272E# P@BUFAD7#Q># #BUFAD# HD271w2E# #BUFAD#D272E#DATA# HD2736# #DATA# D2736:$X;$ ENUFQPTR$&FSKRDVT;;IF POS, SKIP READING VTOC"$ Q>h,$ $>h6$ PDAUX@$ &DAUXJ$ Q>DATAT$$>DATA^$ PDBUFh$ &DBUFr$ RSEC1|$ INOERFD$ !CIOER1$ NOER1xFD,$ QDATA$-O> ;;ADD IN THE BOOT, MAP AND DIR SECTORS$ PDATA$5DCK2BIT;;THEN TAKE CARE OF SECOND BIT MAP IF NEC.$##DATA;;ELSE, BUMP UPPER BYTE$CK2BITQDATA$R>$2DSKRDVT;;IF SINGLE SECTOR, SKIP READING SECOND$ #DATA$,$ Q1yDBUF% ODLEN% PDBUF% QDBUF&% ODLEN0% PDBUF:% "DAUXD% RSEC1N%X;X%SKRDVTQ>b% PDAUXl%Q>v% PDAUX% QDATA % PCBYTE%Q>% PIPTR%Q>DATA %PVECTOR%Q>DATA % PVECTOR%X;%DORDQVECTOR% PPT1zRSAV%QVECTOR%PPTR& QIPTR & PIPSAV& QCBYTE & PCBSAV*& QDAUX4& PSECTOR>& QDAUXH&PSECTORR&Q>\&$PCPYTYP;;SET OPERATION TO 'READ'f&LRSQ>DUPENDp& PDBUFz&Q>DUPEND& PDBUF&LRS1TCBYTE& "IPTR& HCBIT& #VECTO1{R& HPAGE1&#VECTOR& PAGE1%>& Q@VECTOR7& PCBYTE&$>& &IPTR&CBIT*CBYTE' GASPT' QCPYTYP'T?;;CY=0, READ; CY=1, WRITE$' QCSRC.'DRSECIN;;ACC=DRIVE #8' QCDESB'!RSECIN SECTIO;;READ OR WRITEL'IOD,V' QDBUF`' OSECSIZj' PDBU1|Ft' QDBUF~'OSECSIZ' PDBUF'ASPTQDAUX' RDATA' QDAUX' SDATA' DASPN'X;'QCPYTYP;;END OF DRIVE'ISTDD2;;IF READ, DO WRITE'!!MENUSL;;IF WRITE, THEN DONE!'X;'ASPN#DAUX( HASPX ( #DAUX(*ASPXQBUFLEN;;ELSE,1} END OF THE BUFFER?( RDBUF((QBUFLEN2( SDBUF<(ELRS1;;NO, GET NEXT SECTORF(X;P( QCPYTYPZ("ISTDD2;;IF WRITE, DO NEXT READd( CWFSDn( !DORDx(X;(STDD2*SWPFLG( ICKFORM( PRINT(3IDD AInsert DESTINATION disk, press A=( C1~HRGET(CKFORMQ> N(ROPT( FNOFORM(POPT($> ;;IF FORMAT REQ., DO IT(Q>DOSSYS(%>DOSSYS( DEFBUF) Q>FORMAT) PICMD ) QCDES")#L> 0;;CONVERT DRIVE NO. TO ASCII,)PDOSSYS6) CIOCL@)&NOFORM"CPYTYP;;THEN, MAKE A WRITEJ) Q1PTRSAVT) PVECTOR^)QPTRh)PVECTORr) QSECTOR|) PDAUX)QSECTOR) PDAUX) QIPSAV) PIPTR) QCBSAV) PCBYTE)!LRS)X;)X; P. CHANGE DISK FORMAT)X;)$CHDISK ADrive, new density:A=) GETDN;;GET DRIVE NO.) QDELIM*R>;;DRI1VE NUMBER ONLY?*"HCHDSK2;;IF SO, CHANGE DEFAULT*BADPCMD ERRXIT&* ADrive unchanged.A==0*CHDSK2%PTR:* Q@FNPTR7D*>N*%>X* Q@FNPTR7b*R> 9l* EBADPCMDv* S> 1* DBADPCMD*?*3* 'UNNO*Q>*(> S* FTOSGL*(> D* HBADPCMD*T?1*TOSGLPDKTYPE8* DOFSIN*"!SHMEN;;THEN SHOW CHANGED MENU+X; +(X; O. CONFIGURE SYSTEM OR DISK DRIVE+X; + CHKBANKS=*+%>;;This is BOB code...4+';;uncommented as>+';;per usual...H+QR+5\+$>f+ ?L1'p+Q@z+ PMAPBUF8+&1@+A+PMAPBUF8+3+H?L1+0+&+&+&@+&+&+$>+ ?L2',Q@,R>, H?NOT$,2.,&@8,AB,?NOTPMAPBUF8L,3V,H?L2`, &RDKLMTj,X;t,$>~,?L8A,%>,?L6RMAPBUF8,F?FO,1,)>,H?L6,4;;1was a DEY, ?L9', QMAPBUF8,P@,1,)>-H?L9 -7-P-Q>(-P2-Q<-PF-.P-:Z-X;d-?FOCn-PMAPAGE9x-2-(>A-D?L8-%>-H?L9-X;-X;-GETRDK PRINT- ARAM disk present?A=- CHRGET-%>-R> N- HRAM1DSU- !NOFAST.RAMDSU PRINT.' Axlon or E type RAMdisk?A=. CHRGET". %>,. $>6.R> A@. HSAVADRJ. %>T. $>^.SAVADR'RDAD1h. 'RDAD2r. 'RDAD3|. &RDAD1. &RDAD2. &RDAD3.$>;;Correct AXLON.&NMLM1AP;; type RAMdisk.$>;; error in.&NMLMAP;; v.4.50..R> A. FOKP0.$>|;;Reset mask for. &NMLMAP;; XL/XE type RD. CHKBANKS. QRDKLMT. HOKP1/ PRINT/' ANo extra memory available!A==/%>&/ !NOFAST0/OKP0!RAMDSU21:/X;D/3OKP1$>;;Was #0, but now is an AND not an ORAN/ &NMLMAPX/$>;;Still need a 0 'thob/ &FR0l/T?v/T?/ UFR0/T?/ UFR0/T?/PFR0/ UFR0/ IFP/ FASCII/ PRINT/! AUse default config for A=/%>/OKP2Q@INBUF1F7/ GOKP303 0 HOKP20 OKP3M> 0 P@INBUFF7*0340Q>>0 P@INBUFF7H0 QINBUFFR0$INBUFF\0 PRTMSGf0 PRINTp0 AK?A=z0 CHRGET0R> N0 FRAMDSU20 !DVNOQ0X;0RAMDSU2 PRINT0 ASize(K)?A=0 GETLIN0 GETNUM0VVECTOR0W?10VVECTOR0W?0VVECTOR1W?1VVECTOR1W?$1 HSAVRDS.1Q>81SAVRDSPRDKLMTB1X;L1X;V1GETSEQN PRINT`1 APage sequence?A=j1 GETLINt1 GETNO2~1)>CR1 HFSNUM1 FRSEQ1DVNOQ PRINT1 ARAM disk drive no?A=1GETRDRV CH1RGET1%> ;;ASSUME 91R> 01*DNOFAST;;IF DIGIT, CHANGE RAMDISK CODE1R> 91 ENOFAST1M>1?2(NOFAST'RAMDKU;;SET RAMDISK UNIT NO. 2:2X;2 RSEQ?(2 $PGMAP822 &NMLMAP<2)>F2 ECPAXSQP2 QSQMAP8Z2$>d2 CPY0U?n2U?x252U?2U?2U?2M1> 2?2CPY1QSQTAB82 PMAPAGE922232A2M>2 HCPY1273(>3 HCPY03CPSEQQSQTAB9"3 PMAPAGE9,3263(>@@3 HCPSEQJ3 FDVNOQT3X;^3CPAXSQ$>@h3AXSQLA;;Set up the pager3PMAPAGE9;; map for|30;; AXLON type3HAXSQL;; RA1Mdisks.3 FDVNOQ3X;3 FSNUM$>353A3FSNCLPDATA9323 HFSNCL373FSLP1&UNNO3)>CR3 FTONML4PDATA@94>4QDATA9&4 HBADSEQ04"DATA9:4%PTRD4 Q@FNPTR7N4R>CRX4 HFSLP4b4 GETLINl4FSLP4 GETNO2v4 $UNNO4214(>@4 HFSLP14TONML(RDKLMT4 HWRONG4 PNMLMAP4 UPDLP104QDATA@94 PMAPAGE94A4 HUPDLP14 !DVNOQ4BADSEQ PRINT5( ADuplicated sequence number!A== 5 !GETSEQN5X; 5WRONG PRINT*5% AWrong number of entries!A==45 !G1ETSEQN>5X;H53PGMAP =====;;Was 0,0,0,$FF,$FF,$FFR5SQMAP ==K===\5X;f5SQTAB ===p5 ===z5 ===5 ===5X;5 ===5 ===ͬ5 ===5 ===5X;5 ===5 =1==5 ===5 ===5X;5 ===6 ===6 ===6 ===$6X;.6CONSYS PRINT86 AVerify WRITEs?A=B6 DOVRFYL6 PRINTV6! ANumber of File Buffers?A=`6 GETLINj6 GETNUMt6>~6 FSKPFCT6R>6 ESK1PFCT6&PFILES;;SET NUMBER OF FILES (0-16)6SKPFCT GETRDK6 MDINIT;;REINITIALIZE DOS36 !DOSOS6X;6ZAPDRVQ>6 ,;;SKIP 2 BYTES6 SET52Q>R6 %UNNO6PDRVDEF87 CLRHDS 7CONXIT!MENUSL7X;7(CONFGR ADrive number or :A=(71 CHRGET;;GET DRIVE NUMBER27.R>;;IF RETURN, GO TO SYSTEM CONFIGURATION<7 HCONDRIVF7 !CONSYSP7CONDRIVR> 9Z7 DSAVDVNd7TOBADP!BADPCMDn7SAVDVNS> 1x7 DTOBADP7?737 'UNNO7%Q>;;THEN ZERO CONFIGURATION BYTE7PDRVDEF87X;7 PRINT17 ARemove drive?A=7 CHRGET7R> Y7 FZAPDRV7 PRINT7 AIs drive configurable?A=8 CHRGET8#R> Y;;IF NO, SET TO $52 AND EXIT8 HSET52"8 PRINT,8 AHigh capacity drive?A=68 CHRGET@8R> YJ8 FGETHCDT8 PRINT^8 AIs drive double sid1ed?A=h8 CHRGETr8R> Y|8 HSETSS8Q>8 ORDRV8SETSS PRINT8 ATracks/side?A=8 GETLIN8 GETNUM8R>#8 FSET358?8Q>08)>M8 FSETTKS8Q> 9)>P9 FSETTKS9Q>&9)>(09 HSETSS:9SETTKS ORDRVD9SET35 PRINTN9 AStep ra1te?A=X9 CHRGETb9R> 4l9 ESET35v9 S> 09 DSET359T?9 ORDRV9 CLRHDS9 !MENUSL9X;9GETHCD PRINT9" ADrive size (in sectors)?A=9 GETLIN9 GETNUM9(>9FGETHCD;;INVALID SIZE95: %UNNO :Q>:PDRVDEF8 :Q>*:PDKTY1PE84:7>: SETHDSH: !MENUSLR:X;\:#X; S. Set RAMdisk Drive Numberf:X;p:#RAMDRV ARAM disk drive no?A=z: GETRDRV: !MENUSL:X;:$X; V. Set Verify Flag ON or OFF:X;:VERIFY AVerify WRITEs?A=: DOVRFY: !MENUSL:X;:DOVRFY CH1RGET:$>W;;ASSUME YES!:R> N: HDOVFY:$>P;/DOVFY&WRCMD;;SAVE THE WRITE COMMAND IN DOS;:;X;$;ORDRV%UNNO.;LDRVDEF88;PDRVDEF8B;:L;X;V;CLRHDS$>`;Aj;SETHDS%UNNOt;PHDTAB8~;A;PHDTAB8; !DOFSIN;:DOVRFY CH03 ;X;v.4.53/3 mods. by David R. Eichel 12/23/89 6:38 pm$X;SAVE#D4:MDUP3.M65 MYDOS moduleX;(X; K. SAVE FILE COMMAND2X;<8SAVFIL ASAVE:filename,start,end(,init(,run))A==F GETFNP 'IBUFZPIBUFdQOPTn5x GETNO25(>DUPEND%>p EDSLMFG4%>`;;FORCE MEM.SAV TO MEMORY BEFORE SAVING IMAGEDSLMFG D2B8A GETNO2 PHDBUF &HDBUF; SHDBUF PHDBUFA SHDBUF IADDOK ERRXIT% AInvalid START-END range!A=="ADDOKPH5DBUF, #HDBUF6 HINCOK@ #HDBUFJ INCOKQ>T)>CR^ FNINTADh GETNO2r PINITAD|&INITADLINITAD FNINTADQ>;;SET 'GOT INIT' FLAGNINTADPTEMP)>CR FNRUNAD GETNO2 PRUNAD &RUNAD LRUNAD FNR5UNAD #TEMP#TEMP;;SET 'GOT RUN' FLAG NRUNAD7 WRDUP%>'OPT&10 'VECTOR:'VECTORDX;NX; OPEN THE PROGRAM FILEXX;b%>lR> Av HOPTOK1"OPT3OPTOK1'IAUX$>+ ANYDEN;;OPEN FILE 'OUTPUT/ANY DENSITY' GKI5OERRQOPTFFULHDR;;IF NO 'APPEND' DOIO;;WRITE SHORT HEADER   PUTCHR VECTOR GKIOERR KEXITQHDBUF PILEN  QHDBUF*PILEN4 QHDBUF> PIBUFH QHDBUFRPIBUF\ *STATEf GKMSAVp !WDR51zKMSAV!WDRX;FULHDR WR6BYT IKEXITKIOERR!CIOER1X;D2B8APHDBUF &HDBUF 'STATE:X;#X; N. LOAD PROGRAM INTO MEM.SAVX;0MEMSAV ALoad MEM.SAV from what file?A== QSTATEL>;;TURN ON MEM.SAV FLAG GLO5ADIT$TOMEN!MENUSL.X;8!X; L. LOAD USER FILE FUNCTIONBX;LBDLDFL%>VBLOWUP!CIOER1`X;j'LDFIL ALoad from what file?A==t QSTATE~M>;;TURN OFF MEM.SAV FLAGLOADITPSTATE GETFN 'IBUFPIBUF$DATA;;JUST 5A CR? FTOMENQ> PIAUX$> ANYDEN DOIO    GETCHR DATA GBLOWUP( QDATA2 MDATA<R>F HBDLDFLP QDATAZ FTOMENdQOPTnN> Nx FGOTNQ> PWARMSTQ> GOTNN> PIAUXQ>' PICM5D Q>CIOV$>CIOV HBRUN1X;X; B. RUN CARTRIDGEX; STCAR QN>"P,R6'HNORAM;;IF ADDRESS SPACE IS NOT RAM@N>JP;;IF RAM, NO CARTRIDGETNOCART ERRXIT^ ANO CARTRIDGE!A==hX;r NORAM$|5#HNOCART;;IF NOT ATARI CARTRIDGE QCARTST$CARTSTBRUN1PVECTOR&VECTOR QINISAV PDOSINIQINISAVPDOSINI QSTATEM> PSTATE !LDFILEX;X; M. RUN AT ADDRESSX;%BRUN ARun from what address?A=& 5GETLIN0 Q@FNPTR7:R>;;NO ADDRESS?DFBRUN2;;IF SO, ABORTN GETNO2X)>b HBRUN2l%>v 'WARMST FBRUN1BRUN2 ERRXIT, AAddress must be 1-4 hex digits!A==X;*X; PUT A SINGLE CHARACTER ON THE SCREENX;CHRPUT$>PUTCHR 5&ICMD$> &ILEN &ILEN !CIOVX;X; PUT MESSAGE TO THE SCREEN X;PRTMSGPRAMLO  &RAMLO*PRTNXT$>4 Q@RAMLO6> FPRTXITH CHRPUTRPRTENT#RAMLO\ HPRTNXTf #RAMLOp HPRTNXTz PRTXIT:X;X; PRINT AN IN-LINE 5STRINGX; PRINT7 PRAMLO7 PRAMLOPRTMEN PRTENT QRAMLO5 QRAMLO5: X; #X; READ A BYTE FROM THE KEYBOARD X;$ !CHRGET XE424;;FETCH THE BYTE. )>8 +GKILLRD;;IF BREAK OR EOF, ABORT COMMANDB R> z;;> LOWER CASE5 Z?L ENCHGCSV R> a;;< LOWER CASE A?` DNCHGCSj S> ;;CONVERT TO UPPER CASEt NCHGCS5;;SAVE IT~ R> FCHRXIT;;IF EOL, ECHO IT  CHRPUT;;ELSE, ECHO IT Q>;;FOLLOWED BY EOL CHRXIT CHRPUT 7;;RESTORE FOR PROGRAM :;;THEN EXIT )KILLRD 5CHRPUT;;MOVE TO NEXT LINE AND +!MENUSL;;EXIT WITHOUT RETURN TO COMMAND X; *XE424 CLOSE7;;get a chr from keyboard & SOPEN;;Open #7 for keyboard input =OPEN KDEV  DOIO;;get a character  p===== 5;;save it for a sec( C5;;save error stat2 5< CLOSE7F 7;;get error stats againP ?Z 7;;get character backd :;;that's all, folks!n KDEV AK:A=;;handler addr.x X; CLOSE7 DOIO;;close IOCB #7  p=== == : X; %X; RAW SECTOR READ/WRITE FUNCTIONS X; 5RSEC1QCSRC RSEC2, X; SECTIOPDUNIT Q> PRCNT 6 CLD1$SECSIZ 2 8" 6, BSIOR6 IDRTS@ R>J FTOERR2T "RCNT^ ICLD1h TOERR28r !CIOER1| X; DRTS8 : X; 'X; CHECK FOR 2-COLUMN DIRECTORY LIST X; CLEARIT$5CSRC QICMD9 R>GETCHR FCLERXIT QDATA& R> 0 EEOFEXIT %ILEN9 )> DSHFNL "ILEN9& %>0 SFTSIZQDATA8: PDATA8D 3N HSFTSIZX SHFNLQCOLMN;;Alternate 2b N>;; column listl PCOLMN;; between col.v 5PU;; #2 & #21 QTOGGL N> PTOGGL R>;;Only bother if FSHFNL.3;; were on the QDATA;;1st column. R>;;3-char sec cnt? HSHFNL.2;;Br.=4 char. Q> ;;Clear extra CR PDATA;; w/a space. SHFNL.2;; QT5OGGL;;Re-set A reg. SHFNL.3;; PDATA CLERXIT: X; EOFEXIT* Q>4 RTOGGL> FCLERXITH "IBUF9R #ILEN9\ PDATA'f :p X;z TOGGL  COLMN ;;Scrn column #21 X; 4X; COPY ONE FILE (AS MANY MEMORY LOADS AS NEEDED) 5X; COPYFL$CSRC QILEN9 LILEN9 FNOOUTP QSWPFLG IWRFILE Q>IDD $>IDD PRTMSG CHRGET $CDES RESET$WRFILE$CDES. HDOWRFI8 CLEARITB$>LDOWRFIQIOCB9;;OPEN?V"IPUTOUT;;YES, WRITE NEXT BLOCK`X;j5$OPTtQ>~(> A;;APPEND? HDOPO1Q> DOPO1$CDES PIAUX9! ANYDEN;;OPEN THE OUTPUT FILE GTOCIORX;PUTOUT$CDES %CSRC QILEN8 PILEN9 QILEN8 PILEN9  QIBUF8 PIBUF9 QIBUF8( PIBUF92 Q>PUTCHR< P5ICMD9F$ CIOCL;;WRITE NEXT BLOCK OF DATAPNOOUTP$CSRCZQISTAT9;;EOF?dR>n FCPYXITx QSWPFLG IRECOPY Q>ISD $>ISD PRTMSG CHRGET $CSRC RESET !RECOPYX;COPYF$CSRC PICMD9Q>;;Init TOGGL &PTOGGL5;; COLMN for useQ>;; in 2 columnPCOLMN;; dir. list.RECOPY$CSRC"Q>,PDATA6 QBUFAD@ %BUFADJ DEFBUFT QBUFLEN^ PILEN9hQBUFLENr PILEN9| CIOV;;READ DIRECTORY DATA ITOCPFL)>;;END OF FILE?H5TOCIOR;;IF ERROR, ABORTTOCPFL!COPYFLTOCIOR!CIOER1X;CPYXIT$CDES FNOTCL CLOS2'QDOSRNM;;NEED TO RENAME DOS.SYS? FNOTCL7 SOPEN;;IF COPYING DOS.SYS (REALLY 'DIAMOND'OS.SYS)  DELETE$ DOSRNM;;DELETE EXISTING DO5S.SYS SOPEN& 0 OPEN: DOSSYS;;MAKE NEW ONED SOPEN;;and close DOS.SYSN = ==;;writingXQ>;;CLEAR RENAME FLAGbPDOSRNMlNOTCL$CSRCv !CLOS2X;X;1X; SCAN DIRECTORY AND BUILD THE NEXT FILE NAME#X; EXIT WITH NOT-E5QUAL IF AT ENDX;SCNDIRQ>DATA%>DATA DBUF10 Q>GETREC PICMDQ>  PILENQ>PILEN "PCBYTE;;ASSUME NOT A DIRECTORY CIOCL;;READ A FILE NAME  QDATA*R> :4 ENOTDIR>R> 0H ESCNDXRNOTDIRFGOT5SPC\ QDATA f RCBSAVp HNOTSYSzGOTSPC"CBYTENOTSYS$FNPT%>X;MDN1QDATA8R> ;;space FMDN2 PPAR923)>  DMDN1X; MDN2Q> . PPAR92%> $MDN3QDATA8.R> ;;space8 FMDN4B PPAR9L3V2`)> j5 DMDN3t MDN4Q> .~ RPAR9 HMDN50!MDN5Q>;;TERMINATE FILE NAME PPAR9, SCNDX:X;GETLINQ>DATA  PFNPTR PIBUFQ>DATA  PFNPTR PIBUF  Q>GETREC PICMD$>( &ILEN20< &ILENF%>5P'PTRZX;dCIOCL CIOVnCx GCIOER1:CIOER1'FR0Q> PFR0 IFP FASCII%> Q@INBUFF7 PCIERC3 Q@INBUFF7 PCIERC3 Q@INBUFF7M> PCIERC" ERRXIT, AError -- A6CIERC A000A==@X;J5HEXDEF%DATAT)>^ HGETNO2h:rX;| GETNUM, $;;SKIP SINGLE BYTEX; GETNO2; WTEMP2 NXTFLD 'VECTOR'VECTORGETNDQ@FNPTR73R> F;;IS IT A DIGIT EGETNDES> 0;;NOTE THAT CY=0 DGETND1 R> ;;0-9? *5TEMP2 IGOT10&!DGOT1;;YES, SHIFT INTO NUMBER0 R>;;A-F?:EGOT16;;YES, HANDLE ITD GETND1;N O> 0XGETNDE'PTRb?l QVECTORv$VECTOR:X;GOT10EGETND15 TVECTORUVECTOR QVECTOR$VECTOR TVECTORUVECTO5R TVECTORUVECTOR, OVECTOR  PVECTOR7 6*,4 OVECTOR> PVECTORHAROVECTOR\8fO>pPVECTORz !GETNDX; GOT16S>GOT1TVECTORUVECTOR TVECTORUVECTOR TVECTORUVECTOR TVECTOR5UVECTOR LVECTOR PVECTOR !GETNDX;0X; GETFN -- READ A LINE, GET FILENAME FROM ITX;$ GETFNQ>.PDOSRNM8 GETLINB FWCTSTLLX;V>X; GETFN2 -- EXTRACT A FILENAME FROM A LINE ALREADY READ IN`-X; X IS THE OFFSET IN 5THE BUFFERjX;tGETFN2 NXTFLD~WCTSTLQ@FNPTR73R> ?FSETWC;;IF ? OR * FOUND,R> *'HCKEOFN;;SET FLAG, FIND FIRST MATCH SETWCQ> PCPYTYP FWCTSTLX;0CKEOFNR>;;IF EOL, CONTINUE WIT SINGLE FILE FFNSETR> . FWCTSTL5 R> / DFNSET HWCTSTL(SLSHLPQ@FNPTR72R> S< HNCPSYSF PCBSAVP FSAVEDZNCPSYSR> Xd HNOTSWPnQ>x PSWPFLG GSAVED!NOTSWPPOPT;;SAVE OPTION CODE SAVED1Q> P@FNPTR733 Q@FNPTR73R> / FSLSHLPR> . D5FNSETR> FFNSET1"X;,+FNSET'PTR;;SAVE POINTER TO SECOND ARG.61@ Q@FNPTR7J PDELIMTQ>^ P@FNPTR7h?r Q@FNPTR7|R> 0 DDEFDRVR> : FDEFDRV3 ELKFCOL>Q> : R@FNPTR7 FDBEFOR1 P@FNPTR7A HDGTCOD5X;&LKFCOLQ@FNPTR7;;SCAN FOR DRIVE ID FDEFDRV&R> :0FDEVINC;;DEVICE INCLUDED:3D Q@FNPTR7NR> :X FDEVINCbX;lDEFDRVQ> :vDGTCOD DECFNPDBEFORQ> D DECFNPDEVINC%FNPTR QFNPTR:X; NXTFLD,QPTR;;MOVE INDE5X TO A OFNPTR PFNPTRQ>? OFNPTR PFNPTR :X; DECFNP%FNPTR* HDECFP14 "FNPTR>DECFP1"FNPTRH#PTRR%>\ P@FNPTR7f GETDN1:pX;z2X; REQUIRE A DISK DRIVE (NO FILE SPECIFICATION)X;&GETDN2 GETFN2;;GET N5EXT FILE NAME&!GETDNE;;THEN CHECK FOR DRIVE ONLYGETDN GETFNGETDNE'IBUFPIBUF%> GETDNL3> Q@FNPTR7 HGETDNL (> :;;ANY FILE NAME INCLUDED?FGETDN1;;NO, THEN RETURN ERRXIT# AFile name not allowed!A==5X;$%X; UPDATE DENSITY OF DISK IN DRIVE.X;8GETDENR> :B HGTDEN2L QDFUNITV GTDEN2M>;;MAKE UNIT BINARY`$>j &DAUXt2~ &DAUX$>DATA  &DBUF$>DATA  &DBUF RSEC2 GGETDN3 !RDCONFX;  Q@FNPTR7R> D FGETDN3( ERRXIT2 ANot a disk file!A==<X;FX; WAIT FOR SOURCE DISKPX;ZCWFSDQSWPFLGd GWFSDn GETDN3:;;IF NO W5AIT REQUIREDxWFSD PRINT.ISD AInsert SOURCE disk, press A= CHRGET *SWPFLGKGETDN3;;IF IN DUP-DISK $CSRCX;RESET%IOCB9 'UNNO QIAUX9 FNOCHGR> ENOCHGSETDENPDKTYPE8$>SAVMAPQMAPBUF95 PSAXMAP9"0, ISAVMAP6 DOFSIN@$>JRSTMAPQSAXMAP9T PMAPBUF9^0h IRSTMAPrX;| NOCHG:X;"SAXMAP ======= =======X;+X; RECONFIGURE DENSITY OR CONFIGURATIONX; DOFSINX;DOFSIN LDX #95X;DOFLOP LDA WOTDCB,XX; STA DUNIT+1,X X; DEXX; BPL DOFLOP2X;The above was moved to SETDRV (in MDOS1.M65) $>1 &DUNIT $UNNO& '&DUNIT;;TELL SIO DRIVE TO CONFIGURE0 (%DKTYPE9;;GET DENSITY/SECTOR SIZE: (QDRVDEF9;;5GET DRIVE SPECIFICATIOND !CONFIGR;;GO CONFIGURE DRIVEN X;X FX; SET UP PAR AND IOCB10 FOR A DIRECTORY SCAN (MULTI-FILE ACTIVITY)b X;l SETSCNPICMD v Q>PAR $>PAR PIBUF &IBUF SETPTR !$>;;OPEN IOCB10 AS DIRECTORY 5X; %OPDIRQ>;;OPEN IOCB AS DIRECTORY PIAUX9 X; .X; OPEN A FILE INDEPENDENT OF DRIVE DENSITY X; ANYDENQ> PIAUX9! PIAUX9 ! Q>OPEN! SCMD ! ISAVDEN*! !CIOER14!X;>!SAVDEN%DUNITH!QDKTYPE8R! PIAUX9\!:f!X;p!'X; SE5T UP 'PAR' FOR A WILD CARD COPYz!X;!DEFPAR SETPTR! Q@FNPTR7! HDEFPX! PCPYTYP! PPAR8!Q> *! PPAR8! PPAR8!Q>;;termination!!!! PPAR8! DEFPX:!X;!SETPTR%>" SETLP13" Q@FNPTR7" PPAR8$" HSETLP1." SETLP218" QPAR58B"R> :L" FSETLP3V" R> >;;account for sparta type`" HSETLP2j" SETLP33t" 'FNPT~":"X;"%DOSRNM ADA==A:A=`=AOS.SYS,A"CKDTST ADOS.SYSA="X;"'X; REPORT ERROR, THEN RETURN TO MENU"X;" ERRXIT7" PRAMLO"7" PRAMLO"7 PRTENT;;W5RITE ERROR MESSAGE FOLLOWING 'JSR ERRXIT'" !MENUSL;;THEN RETURN TO MENU#X; #+X; Subroutines moved from resident code:#X;#.X; SAVE MEMORY SUBROUTINE: WRITE FILE BODY,(#X; INIT AND RUN VECTORS2#X;<#&WDR LDMEM;;LOAD MEM.SAV IF NEEDEDF#%WDR1$>5;;WRITE TEXT TO DISK FILEP# CIOVZ#IWRERNO;;don't use BMI!d#WRERRO2!SAVERRn#WRERNO$>INITADx# WRVEC#$>RUNAD# WRVEC# *STATE# KGODOS1# !NOWMS#GODOS1!GODOS#X;#*WRVECVTEMP;;WRITE THIS 6-BYTE VECTOR?#DRTS2;;IF NOT, JUS5T RETURN# &VECTOR#QINITAD9#PVECTOR#2$QINITAD9$PVECTOR$Q>INITAD"$PVECTOR,$PVECTOR6$!&VECTOR;;(X,A)=MIDDLE WORD@$WR6BYT DOIOJ$ ==T$ PUTCHR^$ VECTORh$ IRTS2r$ !WRERRO2|$ RTS2:$X;$+ =A5David R. Eichel rel.ver.1/1/90A=#PVECTOR#2$QINITAD9$PVECTOR$Q>INITAD"$PVECTOR,$PVECTOR6$!&VECTOR;;(X,A)=MIDDLE WORD@$WR6BYT DOIOJ$ ==T$ PUTCHR^$ VECTORh$ IRTS2r$ !WRERRO2|$ RTS2:$X;$+ =A4#