ML }  X c0C)HCCH Mhhݩh `eCDiCD`  RyHW   * 1H0芢@) Y0.Ș`i#(PMRR\ \b Pgi 0  % @ / ՠ`d   0DDԝLH}N@  )?HI Y0`HIJH) * J j * hJJJ )HJ h i     } YS S0 i`ϣ߳ϣ߳H J3xj2h} 1 |9 ӭ45(420 *(0241өX.`  R *i)Lvw  ~*P}E 5 LN(G E  r s k rsrL ( E LO(0d( L iE0O +)$IC  H S8 }q p h   j 8no CDLQ CFl M  LO Ri)Llk2'")*F }$F$F$F$F$ 5 )ШF/Șl]kpqС,LQ/A! Ti)Zlk@ ܬ/i)(")")k }$F$F$F 5$/L /lF@jj(LNkle$$%8(k()` R 8 ELO Ri)^>jf | NrC s } ) vw5g   enfo Glvw LQ@iLm>j FL ~Jjjjii p qEh }jlrs`LQ:$ȱ$@+[_#{ 8  Խut! ai 8   E I   ] C } H h    ˰ 8  N   Lm E  ,  [ `LQ ,/ 8 ~/  Ơ? ѩ}/  [ /Lj0?MoLn FjMqLp NklLOLQnLoMlNLO R"(+}ըHH`Q R!!  % !   / .   FȑF! /GF \H"+0+* }! F tLQnm: J~nTF1F  *n+)5! n (, n)1JJJn(n*o} I ,0  ci a oF? @ , 8,0 ʩ0H Eh   i}  D ]DmmFLQvtu`*&!*@h ] 0 ^0` c 0l$$%}()()%*&J%H,@hH hH@,h $% 8i8$(%)0hhH ]h`() c 0H c 0 h}`hhh&JJ ](ll  LQ0  /qnoHH 9 9 H H  I9  9 } Nd EH  Q8 o n  FnoL HII/ Ih8`h`Lnon`no`u F }E VEhLO/luF l0BF/lɜɛ׽hE N  b VFL FREE SECTORS C} H) *Fh ):FȽ F FC IH' 0 d  i:Fȩ/F.l`CD/08HDIC}IHȰ/F`ȱ$>.+.i ȱ$:刄H !A \ Hȱ$*?ȝ 2. ? [_{ ,0}-:) 0$:>WI  IТ,LQH  0hLd ~ t u`C ?( 0(C.` E } R =! .ti S0N EE D XC )0')AY  )ע ? 0E088FG \o}n  (HhLcL3 iJ i Lqp 0=rspnqopqlk`jZj0  j FL`H}FhȑFȽlFi0 h FFLFpvqwgneofLF pq7  G0i 0 FJJh1FqȱFpȱFk`B!}08`hEE D 8. =D}tui( TʩL`b!)    cȌaȌd b`aab}H8 hdaHcd8 cH hHH  \h hc` =Hh I8ih( t  ( t(!` L\}CJfCJfCJfCDfC` a  HII  INdh  `h  `n)8jHniPoijIjFIjFIjh` a } I 38  8H0 I  ' H LQ8j Y  8j NdY  &I &I &IHeH.p!}Iiq  `!.莿 2Jjj }.m Ȉ!m FG` ɩLQ z "} e Hi04 \ Ȍ  8 i h !`I0 `C Y8.`DOS SYS#} I  ` ~ݩ.C/`ba.m۩mѤC9 `C L] H  ,- '0 l $}, BLVDE`D1:AUTORUN.SYS8hhJ ȱHȱIȱBȱDȱEeeHHLV)  %}1*  ,,p-  0 I &  '0   Lw)l, 0  I&LD1:MEM.SAV&}E:D1:DUP.SYSE:D1:DUP.SYSE:D1:DUP.}J)1CD1:DOS.SYS n  * \*`آ R'S )ɀ@  U))% BError lo(}ading MEM.SAV or memory!  0* b*c*d*e* R Hd*JSDd*J-=e* 0c*ʈд =}MYDOS 4)}.50 -- Copyright 1988,˛Disks 1S- 2S- 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. L+}oad MEM.SAVE. Rename File(s) O. Change Config.F. Lock File(s) P. Set DensityG. Unlock File(s) Q. Make DirectoryH. Wr,}ite DOS Files R. Pick DirectoryI. Initialize Disk S. Set RAMdisk #J. Duplicate Disk V. Set Verify Flag  ?莼-}( 0  =Select Item ( for menu):@  =ɛL)1L,*L,:W@ ,,L=No such item!.}L*, -L*, BNeed new file name! BNo drive or director0}ies allowed in new name!Lock Unlock Delete Lock which file?â-#Unlock which file?ɢ-$((H @ AQ/wDel1}ete what file?Ѣ-!((H @ ANJ =Answer 'Y' or 'N'h `B L?;(( ~=( ~= =? =Y ?Lj.H @ AhR ?2}R)L*,LM/L-Lz-File to rename, new name? @ A(9', ȱ:>0{ ПFull directory name?Z"L.Dire3}ctory to be used as 'D:'? @ A(5)L.(I: ȱޝL*, BInvalid directory!L?( 4}(0Li-File source, destination? '( @C۩2ڭ82ܭC B9'0 @(ߍeލd(DЍ( ? 9'5} A rBȱޙ':>Ȍ(C0J* .B :'ȱ/.* #,ɛȝ:' ߰ A L?,(0L*, '6}ut(:'3?&' .'Ƚ:'?&'  .ى'Q?''(#( ~= =-->' ~=7}Q =YR_o (J(  0?B݌''BK)`''utz0( >(L0L*,L?nDisk to FORMAT:8} YA B(UTލ1 =(Press for Enhanced Dns)Type to Format Drive 1: =AIYZNj[R VL9}?L*,D1:DUP.SYSDrive to write DOS files to? YAH1:*K)2J) Z wB hpJ) 2<2U:}TC٩1ة۩کL;Source, Destination (Sectors)? YA)((9'( SA)((((( @(0% =Inser;}t both disks, type = A( A((/( B(( BDrives not compatible!J(j(9'Hi''<}h(ɛy BInvalid options! @-&& @)׍&&(&&&۩ک&&&&8* <4&&&& <4=}8*8(ܭ(ݥ2C, BNot enough memory! ک&&`(Mh  & =L?&i &>}&&&mm   =  &((&թԥԍ(Ս(((( ( ((C2((?}ՠԍ((,(0"( (( =m(m( & &("L*,  ( AL4,(, =Insert DES@}TINATION disk, press =Nͼ J) b( 0K) ?((ԭ(խ( ( (((L4Drive, new density:A} YA9'ɛ BDrive unchanged.(ު90٨Ȍ(SD  ABL)xԌҭHӭ@ @ ʎӆ@B}ӭ@@ :  $ӹ @hөԥX` Aˠ =RAM disk present? =NL#8 =xlC}on or E type RAMdisk? =Aό  L   M A, A6: ' =No extra memory available!L#8L7 & & D}& =Use default config for 0)ȩ ~= =K? =NL7 =Size(K)? ? @FjFjFjFj: =Page seqE}uence? ? @o* =RAM disk drive no? = 09) `8 -8**H***) 9 Ȋ)h9 @@ʊ F}H'h(#''/'(ɛ ? @(@: 3 ʽ' L7 =Duplicated sequence number!L7 =Wrong numbG}er of entries!L7K큅쀄 =Verify WRITEs? ; =NumberH} of File Buffers? ? @  6 Lw),R( ';L*,Drive number or : =ɛLC99L60Ȍ( =Remove I}drive? =Y =Is drive configurable? =YЂ =High capacity drive? =Yy =Is drive double sided? =Y ; =TracksJ}/side? ? @#0M P( ; =Step rate? =4/ ; ';L*, =Drive size (in sectors)? ? @H(K}h *;L*,RAM disk drive no? 8L*,Verify WRITEs? ;L*, =WNPy`(`(  LABSAVE:filename,start,end(,init(L},run)) @TUH @Cp` 2< @؆8օڊ BInvalid START-END range!۩ @  @M} hԄՠAμȌZ wB04*  0$ڍXۍY֍T׍U,0LBLB #CL?ֆ׌`Load MEM.SAV from whaN}t file? 0#L*,L?Load from what file?) @TU&̩Z wB &0&-&а&𨭼INIZ'O}RV0II BNO CARTRIDGE!Ԇխ  )L?Run from what address? ?ɛ @P} BAddress must be 1-4 hex digits! BHILV n=`hh =HH` =0{a Hɛ n= n=h` nQ}=L*, = = pHH =hh`K: p `(((( i ɀ((L?(`(B'(0!HH''^R}>I^>(`^>DH(`(HI`(o5 ~= =( B( >@A (J wB0x((HHIIDDES}E B ?(CɈK(٢A ~= =( BL>(B^>((ڤ ܝHݝI VL_>L?(" B !B J) T} B(L& R XY( ?&:0H&((& ( .( & ( .(ʩ(U}`ލD&ߍEBIʎH( V0`ԩ ؠ@ȱ@ȱ)@ BError -- 000&`$8f 3AԄձG/ V}$<68i/(Ԧ`H&եԦ&&eԅheԅԊe(iL*@&&&&ԅL*@B ? 3A?*(ɛ:W}./2SX(0ȱ/.ɛ(ލ9'ި0#:Ȱ :ފ :ȱ: : CAD CAޥX}`(eޅީe߅`(` @L\A @TUȪ: BFile name not allowed!: )  i( =0+L Y}TUD BNot a disk file!(0` =Insert SOURCE disk, press =,(pӮ(A(O  1B AB1BZ} ` % 1(L/ b(de BJKO L?O` B((*(([}(`ȱޙ((:>Ȍ(`D:`OS.SYS,DOS.SYShh =L*,  VLJ C C,pLiLF#Խ٩Յ׆ \} LB`((:>Ȍ(`D:`OS.SYS,DOS.SYShh =L*,  VLJ C C,pLiLF#Խ٩Յ׆  "X;save#d:MDOS.M65 MYDOS moduleLISTFLGX;(LISTFLG2EI<FALARGE DISK FMSAPX;Z>D:MDOS1.M65^}d>D:MDOS2.M65n>D:MDOS3.M65xX; BOOTNDI+;;START DUP HERELISTFLGEIFMSAPX;Z>D:MDOS1.M65c', #X;save#d:MDOS1.M65 MYDOS module9X; Copyright 1984, Charles Marslett, Wordmark SystemsX;(IX; Permission is gra `}nted by the author for any use whatsoever of this2HX; code, so long as this notice remains in the source code, and so<LX a}; long as the source to this routine, however modified or unmodified,F.X; is made available for a nominal cost.PX;Z b}X; DISK I/O EQUATESdX;n4DKADDR1;;SIO ADDRESS OF FIRST DISK DRIVE (D1:)x8TODK;;STATUS BYTE FOR A DATA TRANSFER TO c}THE DISKRDSTAT S;;SIO COMMAND EQUATE FOR READING THE DRIVE STATUSFWRITEV W; e};SIO COMMAND EQUATE FOR WRITING A DISK WITH VERIFICATION/FMTCMD !;;SIO COMMAND TO FORMAT A DISKETTEX;.LK128};;LOC f}ATION OF 128 BYTE SECTOR LINK.LK256;;LOCATION OF 256 BYTE SECTOR LINKX;X; ZERO PAGE EQUATESX; WARMST g}DOSVEC  DOSINI "X;, 6 ICHIDZ@ ICDNOZJ ICCOMZT ICSTAZ^ ICBALZh ICBAHZr ICPTLZ h}| ICBLLZ ICBLHZ ICAX1Z ICAX2Z CURFCB DATBYTX; CHKSUM1 BUFR2X;C i} FMSZPGDIRDSPFMSZPGDIRSECFMSZPG CURFNO FMSBPT& TMP10 TMP2:X;D.X; DEFINITIONS FO j}R THE ATARI ROM EXECUTIVENX;XDSKTIMFbRUNADRlINIADRvMEMTOPDVSTATX;$X; SIO COMMAND B k}UFFER DEFINITIONX; DDEVIC DUNIT DCOMND DSTATS DBUFLO DBUFHI DTIMLO DBY l}TLO DBYTHI  DAUX1 DAUX2 X;*X; I/O SYSTEM DEFINITIONS4X;>1HATABS;;BASE OF THE DYNAMIC HANDLER m} TABLEHX;R8X; CIO COMMAND TABLE BASE DEFINITIONS (FOR IOCB $00)\X;f@p ICHIDz ICDNO ICCOM ICSTA n} ICBAL ICBAH ICPTL ICPTH ICBLL ICBLH ICAX1 ICAX2 ICSPRX;&X; CAR o}TRIDGE SUBSYSTEM DEFINITIONSX;(CARINIT;;LOCATION OF INIT VECTOR"CARTEST;;LOCATION OF FLAGS$&CARRUN;;LO p}CATION OF RUN VECTOR.X;8X; 800XL MAP CONTROLBX;LMAPREGVX;`!X; OTHER I/O PORT DEFINITIONSjX;t NMIEN~ q}X;X; ROM VECTORSX;(DSKINVS;;OLD DISK I/O ENTRY POINT$SIOVY;;SERIAL I/O ENTRY POINTX;X; DOS BOOTING r} CODEX;X;X; DISK BOOT SECTORS (3)X;;;DOS.BOOT LOADS AT 0700#BOOTFL AMA;;indicate new MYDOS+BOOTL  s};;NUMBER OF SECTORS IN THE BOOT /BOOTAD BOOTFL;;ADDRESS OF BOOT CODE IN RAMBOOTIN INIT*!INBOOT;;JUMP TO THE BOOT C t}ONTINUATION(6FILES ;;NUMBER OF FILES THAT MAY BE OPEN AT ONCE23X;DRIVES = * ;USED TO BE BIT PATTERN FOR DRIVES<RAMDK u}U  ;;RAM DISK UNIT #F-X;BUFALC = * ;USED TO BE BUF. ALLOC. DIR.P#DEFAULT ;;DEFAULT UNIT NUMBERZ:DOSEND BOOTND;;ADDR v}ESS OF THE FIRST BYTE OF FREE MEM.d2SECDAT ;;1=128 BYTE SECTOR/2=256 BYTE SECTORn(DOSLOC ;;SECTOR ADDRESS OF DOS.SYSx w}1DLINK LK128;;OFFSET TO THE SECTOR LINK FIELD-DOSAD BASE;;ADDRESS TO LOAD DOS.SYS INTOX;8INBOOT%DOSAD;;SET UP S x}TART OF DOS AS BUFFER ADDRESS QDOSAD$ BTSET;;LOW ADDR IN Y, HIGH IN AX;QDOSLOC,%DOSLOC;;PUT DOS DISK AD y}DRESS INTO (A,Y)X;X; DOS.SYS INPUT LOOPX;"INITLP,;;CLEAR CY, 'DO A READ'%$SECDAT;;GET CODE FOR SECTOR SIZE$F z}NODOS;;IF ZERO, NO DOS ON DISK!" DKIO;;INVOKE DISK I/O ROUTINE,GNODOS;;IF AN ERROR, RETURN NO-DOS ERROR"%DLINK;;POI {}NT TO LINK,,Q@FMSZPG7;;CHECK FOR NEXT LINK (10-BITS)6ANDCDM>;;BEING ZERO,@ 5;;SAVE UPPER BYTE OF ADDRESSJ3T)L@FMS |}ZPG7;;IF SO, LOADING IS COMPLETE^ FBOOTXTh4Q@FMSZPG7;;ELSE, IT'S THE ADDRESS OF NEXT SECTORr5;;SAVE LOWER BYTE ON STACK }}|2 MVBUFR;;THEN ADJUST THE BUFFER POINTER IN DCB7!?;;RESTORE LOWER BYTE TO Y-REG(7;;RECOVER UPPER BYTE OF DISK ADDRE ~}SS!DINITLP;;AND CONTINUE LOADINGX;)NODOSQ>;;NO BOOT PROGRAM ERROR CODE ;;SKIP SINGLE BYTE (LDY #)X; BOO }TXT73DOSXITT?;;SET CARRY, CONVER CODE TO FINAL VALUE?;;PUT CODE INTO Y-REG:;;AND EXITX;4X; MOVE BUFFER POINTERS } TO NEXT AREA TO BE LOADEDX;MVBUFRQDLINK&,04OFMSZPG;;ADD DLINK TO THE CURRENT BUFFER ADDRESS:?;;LOW BYTE TO Y-R }EGDQFMSZPGNO>XBTSET'FMSZPGbPFMSZPGl+BUFSET'DBUFLO;;STORE LOW BYTE INTO DCBvPDBUFHI;;THEN UPPER BYTE }:X;-X; PERFORM DISK READ(CY=0) OR WRITE (CY=1)X;3DKIOPDAUX2;;STORE UPPER BYTE OF SECTOR ADDRESS'DAUX1;;THE }N LOWER BYTE DKIO2%> Q>READ#DSETRTY;;IF CY=0, READ INTO RAM QWRCMDBX;%SETRTY'TMP1;;SET NUMBER OF TRIES }DKFMEPDCOMND, (Q>WRITE;;CLC AND CONSTANT FOR POKERSWRCMDB   'DTIMLO*&Q>;;ASSUME A 128-BYTE SECTOR SIZE4 }0> FSTBUFLH$DAUX2;;SECTOR > 256?R HSET256\ $DAUX1f(>;;SECTOR > 3pDSTBUFL;;IF NOTz)SET256T?;;MAKE A 256 BYT }E SECTOR SIZESTBUFLPDBYTLOU? PDBYTHI+%>DKADDR;;PUT DISK DEVICE CODE INTO DCB 'DDEVICIORTRY"TMP1 GDIO }XIT $DCOMND2A"$>FROMDK;;ASSUME DATA ==> DISKM>&HISREAD;;IF NOT X0,X7,X8 OR XF, OK $>TODK;;ELSE, DATA = }=> DISK )ISREAD&DSTATS;;RESTORE STATUS TO DCB SIOV;;DO THE I/O OPERATIONS$ 1. GIORTRY;;IF NOT OK, RETRY8 X;B 4DIO }XIT$CURFCB;;ELSE, LOAD FCB OFFSET AND STATUSL 3V C` :j X;t ,X; FIXED RAM DEFINITIONS IN BOOT SECTORS:~ X; ,DIUNIT; };UNIT NO. OF CURRECT DIRECTORY .CDIREC;;SECTOR NO. OF CURRECT DIRECTORY HOLFN 5STATE p;;DUP loaded, MEM.SAV ina }ctive, 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; "STKPSV;;SAVED STACK POINTER X; ;;MUST MATCH DUP LOCATION X; 2TRACKS #=(=P=M };;TRACKS IN EACH DISK FORMAT X; 5SECSIZ =======;;BUFFER SIZE TABLE( X;2 %DRVDEF R=R;;DRIVE CONFIG TAB }LE:<  =;;BIT 7=1 => NO DRIVEF % =;;BIT 6=1 => ATARI 810 DRIVEP / =;;BITS 5-4 IS TRACKS (SEE ABOVE TABLE)Z X; BI }T 3=1 => DOUBLE DENSITYd "X; BITS 2-1 ARE DRIVE STRP RATEn X; BIT 0=1 => DOUBLE SIDEDx X; X; DOS.SYS PROGRAM FOLLOWS X; } DKEPT DKOPEN  DKCLOS  DKREAD  DKWRIT  DKSTAT DKXIO X;  X; X; DOS INITIALIZ }ATION CODE X; X; 2INITQ>i;;INITIALIZE THE CURRENT DIRECTORY 6PCDIREC;; TO THE ROOT DIRECTORY OF THE BOOT DRIVE" } Q>i, PCDIREC6 X;@ X; IDENTIFY DRIVE TYPESJ X;T $>^ IDRVLP&DUNITh , ZERDVS;;ASSUME THE DRIVE IS NOT PR }ESENTr QDRVDEF9| 6GNXTDRV;;IF IT IS NOT DECLARED, WAIT FOR AN ACCESS ! JSTRD;;ELSE READ IT'S STATUS *FNXTDRV;;IF AB }SENT, GO TO THE NEXT ONE %> WOTCPYQWOTDCB8 PDDEVIC8 1 IWOTCPY QDRVDEF9 R>@ *ENXTDRV;;IF NOT CON }FIGURABLE, CONTINUE %SECSIZ9 1 SETDRV;;ELSE, TELL IT ABOUT MY CONFIGURATION X; &NXTDRV0;;STEP TO NEXT DRIVE NUMBE }R "HIDRVLP;;IF MORE, LOOK AT THEM X;& X; ZERO INITIALIZED MEMORY0 X;: INITPT2%>MAPBUFCHGMAPD A;;NOTE X=0 HERE }N ZERLP1PCHGMAP8X 1b HZERLP1l #MAP2MODv 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 DON }E? DALCBUF "BUFFLG9 GDKBFSQ ALCBUFC PSBTABU9 3 DKBFSQ0;;BUMP BUFFER COUNTER* $IDKBFLP;;IF NOT CONTINUE L }OOPING4 )'MEMTOP;;DEFINE TOP OF MEMORY USED> X;H X; SET UP HANDLER VECTORR X;\ FNDHND2f 2p 2z *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>DK }EPT "PHATABS9;;BUILD HANDLER VECTOR B!;;DUPINV (dup code modifies this) ;DONE, INITIALIZE DUP CODE X; X;'X; DO }S NON-ZERO PAGE RAM ALLOCATIONSX; CHGMAP$ CURMAP. MAP28MAP2MODB LSTSECLLSTIOCBVX;`=X; } MYDOS FCB STRUCTURE (ALMOST THE SAME AS ATARI DOS 2.0)jX;t FCBFNO~FCBOTC;;OPEN TYPE CODE FCBFLG MAXLEN } CURLEN BUFNO CURSEC LNKSEC SECCNT*DIRBAS;;BASE ADDRESS OF CUR. SECTOR SAVSEC }FCBLENFCBLENX;&BUFFLG;;IF 0, BUFFER NOT IN USE 6SBTABU;;UPPER BYTE OF THE SECTOR BUFFER ADDRESS( }MAPBUF;;SPACE ALLOCATED FOR VTOC7DIRBUFMAPBUF;;SPACE ALLOCATED TO READ DIRECTORIES( FNAME 2 CURMP<X;FX; }P BASE Z/HDTAB ===;;8 LOGICAL HARD DRIVES OFd) ===;;UP TO 65535 SECTORS EACHnX;xBX;this table is ref }erenced by DUP.SYS, and should not be moved!X;X;X; DOS CONFIGURATION CODEX;X;=X; CONTROL BLOCK TO BE WRITTE }N TO A DRIVE TO CONFIGURE ITX;WOTDCB N=@ DIRBUF=  =X;PX; THE CONFIGURATION CODE, FORCES A DRIVE IN }TO THE APPROPRIATE CONFIGURATIONX;"SETDRVM>?;;EXTRACT CONF. BITS PTMP1 'TMP2"% SIOV;;READ CURRENT CONFIGURATIO }N, GJSTRD6 QTMP1@ %TMP2JV?T5;;SAVE REMAINING BITS^M>;;EXTRACT STEP RATE CODEhPDIRBUFrQ>|PDIRBUF }U?'PDIRBUF;;STORE DOUBLE SIDED FLAGC;;GET DENSITYV?/PDIRBUF;;STORE UPPER BYTE OF SECTOR SIZEW?PDI }RBUF;;THEN LOWER BYTEU?T?T?PDIRBUF7V?V?!V?;;POSITION TRACK COUNT FIELD?&"QTRACKS8;;GET NUM }BER OF TRACKS0 PDIRBUF:M>;;SEE IF 77 TRACK 8 IN.D5NV?X/LDIRBUF;;MERGE D/DENSITY WITH 8 IN. FLAGbPDIRBUFl }7vT?;;CONVERT TO 0 OR 8 O>;;SECTOR COUNT = 18 OR 26PDIRBUF %DUNITQHDTAB8 FTOSIOV!PDIRBUF };;SIZE = SECTORS/TKQHDTAB8 PDIRBUF;;LOW BYTE OF SIZEQ>PDIRBUF;;ONE TRACK/DRIVE+TOSIOV#DCOMND;;CHANG }E COMMAND TO WRITEQ>"PDSTATS;;SET DIRECTION -> DISK& SIOV;;WRITE OPTION TABLE TO DRIVE X;FX; AND THIS ROUTINE } MAKES SURE IT REALLY DID HAPPEN AS WE THOUGHT! X;*JSTRDQ>RDSTAT4 PDCOMND> DSKINVH $DUNITRC\ GZERDVSf QDVS }TATpT?;;SECTOR SIZE=256?zT?T?Q>O>SETSIZPSECSIZ9:X;ZERDVSQ>FSETSIZ;;branch alwaysX };X; DOS RAMDISK CODEX;X;+X; RAM DISK I/O HANDLER (POS. IND. CODE)X; MAPAGE ===$ ===. }===8 ===BX;L ===V ===` ===j ===tX;~ === === } ===Ϝ ===X; === === === ===X; VALSEC5CL> }V?  PBUFR=;;DISABLE INT-SQ>(PNMIEN;;DISABLE NMI-S2W?< PBUFRF7P?Z QMAPREGdL>n PCHKSUMxL>| } MMAPAGE8%PMAPREG;;SELECT RAMDISK DATA PAGEX;*QDBUFLO;;USER BUFFER ADDRESS GOES HERE PBUFRQDBUFLO P }BUFR%>8DRREADL;;CY=0 IF READRWRITLQ@BUFR7 P@BUFR73 IRWRITL GRIOXX;")RDKIO'DAUX1;;** }* FOR FORMAT CODE ***,)>6U?@R>J/RDKLMT ;;NUMBER OF 16K PAGES IN RAMDISKT!DVALSEC;;CALCULATE MEM. ADDR.^8h }Q>r GRERROR|X;RREADLQ@BUFR7P@BUFR73 IRREADLX;%RIOXQCHKSUM;;FORCE REAL RAM PAGEPMAPREG;;B }EFORE EXITINGQ>PNMIEN;;RE-ENABLE NMI.;;ENABLE INTERRUPTSQ>;;RETURN '1' IN Y-REG&RERRORPDSTATS;;AND IN ST }ATUS BYTE$CURFCB;;RESTORE FCB ADDR?:;;THEN EXIT INTERRUPTSQ>;;RETURN '1' IN Y-REG&RERRORPDSTATS;;AND IN ST 9O? $X;save#d:MDOS2.M65 MYDOS module9X; Copyright 1984, Charles Marslett, Wordmark SystemsX;(IX; Permission is gr}anted by the author for any use whatsoever of this2HX; code, so long as this notice remains in the source code, and so<L}X; long as the source to this routine, however modified or unmodified,F.X; is made available for a nominal cost.PX;Z}X; DISK OPEN ROUTINEdX;n'DKOPEN WBITMP;;fix that nasty bug!x( SETUP;;SET UP BUFFER POINTERS, ETC.2 GETFNM;;GET D}RIVE ID OR FILE NAME FROM BUFFER'QICAX1Z;;GET TYPE OF OPEN FROM IOCB PFCBOTC9!M>;;TEST DIRECTORY READ FLAG FDKOP}N13!LSTDIR;;IF SET, GO HANDLE DIRECTORY FORMATTINGX;DKOPN1PSAVSEC9PSAVSEC9;;ZERO SAVSEC SFDIR6;;SAVE} STATUS RETURNED EOPNEW*Q>;;MAKE SURE THIS IS NOT A DIRECTORY GETFLAG4HDIROPN;;IF A DIRECTORY, GO HANDLE IT SEP}ERATELYOPNEW%ICAX1Z")>,FOPNOP;;IF OPEN FOR OUTPUT6)>@FOPNIN;;IF OPEN FOR INPUTJ)> T+FOPNUP;;IF OPEN F}OR READ/WRITE (UPDATE)^)> hFOPNAP;;IF OPEN AND APPENDr.DIROPN!ERRCMD;;OTHERWISE, IT IS AN ERROR!|X;OPNAP8;;OPE}N APPEND EOPNCR0 TSTLOK- INITYP;;READ ALL THE SECTORS IN THE FILEQDIRBUF8 PSECCNT9QDIRBUF8PSEC}CNT9APPRD RDNXTS$DAPPRD;;IF NOT EOF, READ ANOTHER QMAXLEN9# LENSET;;SET LENGTHS FOR OUTPUT QSECCNT9 HS}GLDEC"SECCNT9/SGLDEC"SECCNT9;;ALLOW FOR SECTOR REWRITTEN& !OPOUTX0X;: OPNUP8;;OPEN UPDATE (OUTPUT)D EOPNER}1N TSTLOKXOPNOWR INSTRTb !DONElX;vOPNIN8;;OPEN INPUT DOPNOWROPNER1Q>;;FILE NOT FOUND GEROXITX;} OPNOP8;;OPEN (NORMAL) OUTPUT EOPNCR REMOVE !GET1STX;OPNCR0"FCBOTC9OPNCRQHOLFN PCURFNO GOPDIRF}GET1ST ALLOC X;$QICAX2Z;;IF OUTPUT, TYPE OF FILE "M>$;;SAVE LOCKED & FORMAT BITS*1N>C;;MERGE IN DEFAULT CODE (DO}S II, UNLOCKED)4%MAPBUF;;WHICH TYPE DISK?>)>;;IF >2 THEN MYDOSH DLLINKSRL>\X;f LLINKS5p. RDCFNO;;SELECT PR}OPER SECTOR IN DIRECTORYz; ENTNAME;;ENTER NAME INTO ITQLNKSEC9PDIRBUF8 QLNKSEC9PDIRBUF87 }SAVFLAG INITYP TONXTOPOUTXQ> PFCBFLG9! TSTDOS;;FILE NAME = DOS.SYS? HJDONE %CURSEC9QCURSEC9}' SETDOS;;IF SO, UPDATE BOOT SECTORS$X;. QDOSAD8 PFMSZPGB QDOSADLPFMSZPGV0HOWTDOS;;NOTE: DOS CANNOT STA}RT ON ZERO-PAGE`X;jOPDIRFQ>tEROXIT!AEXIT~X;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 WRIT}E FROM&3;; THE DOS CODE WAS ATTEMPTED AND1)DLINK;; WE ARE GOING TO REMAIN COMPATIBLE). DCDOSBFC PCURLEN9 }MVBUFR )DOSENDSDOSEND DLWTDOS JDONE!DONEX;X; READ DATA FROM A FILE(X;2/DKREAD SETUP;;SET UP BUFFE}R POINTERS, ETC.< QFCBOTC9F&M>;;TEST THE DIRECTORY INPUT FLAGP!FRDFILE;;SO WE CAN HANDLE THEZ.!DIRRD;; SPECIAL CASE} OF A DIRECTORY READdX;nRDFILEQCURLEN9x RMAXLEN9;DRDSGBT;;IF NOT AT SECTOR BOUND., READ A BYTE AT A TIME6ERDASN}T;;ELSE, CHECK FOR READ MODE AND BUFFER SIZEX;RDASLPQICCOMZM>4FRDSGBT;;IF NOT BINARY I/O READ A BYTE AT A TIM}E %DLINK1?RDSCLPQ@FMSBPT7;;SIMULATED BURST I/O (USING UNROLLED LOOP) P@ICBALZ71 Q@FMSBPT7 P@ICBALZ71} Q@FMSBPT7 P@ICBALZ7"1, Q@FMSBPT76 P@ICBALZ7@1J HRDSCLPT0Q@FMSBPT7;;DATA AREA IS MULTIPLE OF 4 PLUS 1^ P@}ICBALZ7h0 BUFADJ;;ADJUST BUFFER POINTER BY 125 OR 253r(RDASNT RDNXTS;;READ THE NEXT SECTOR|*ERETEOF;;REPORT EOF/ERROR }IF NECESSARYQICBLLZ;;AND REPORT LAST BYTE IF IT IS SO! ,X;&)RETEOFQ>;;RETURN END OF FILE STATUS0 !AEXIT:X;D}X; WRITE DATA TO A FILENX;X,DKWRITPDATBYT;;SAVE DATA BYTE (PERHAPS)b %ICDNO9l5'ICDNOZ;;INSURE ICDNOZ IS SET UP (BASI}C DOES NOT)v. SETUPW;;SET UP REST OF FLAGS AND POINTERS QFCBOTC9M>8FCANTWR;;ERROR OUT IF WRITE IS ILLEGAL (BASIC} AGAIN) QCURLEN9? RMAXLEN98DSKBURST;;SKIP AROUND IF NOT WRITING END OF A SECTORX;*WRASLP WRNXTS;;WRITE A S}ECTOR OF DATA,ERETEOF;;ERROR OUT IF NO MORE DISK SPACE %STKPSVQ8R>;;IF FROM BASICDBASWRT;;PASS SINGLE BY}TES !QFCBOTC9;;fix open for updateM>;;bug in burst I/O  HBASWRT* QICCOMZ4M>;;AND IF RECORD I/O>FBASWRT;;PAS}S SINGLE BYTESH0%ICBLLZ;;AND IF THE BUFFER IS < 256 BYTESRFBASWRT;;PASS SINGLE BYTES\ %MAXLEN9f1p1WRSCLPQ@ICBA}LZ7;;ELSE DO SIMULATED BURST I/Oz$P@FMSBPT7;;BY UNROLLING THE LOOP1 Q@ICBALZ7 P@FMSBPT71 HWRSCLP-Q@ICBALZ}7;;BUT ONLY 2 ENTRIES FOR WRITING P@FMSBPT7 BUFADJ Q@ICBALZ7 PDATBYT !WRASLPX;BASWRT%> SKBURSTQD}ATBYT #CURLEN9 P@FMSBPT7$ Q>@. :LFCBFLG9;;FOR UPDATE, SAY THE SECTOR HAS BEEN MODIFIED8 PFCBFLG9B HTODONE;;BRANC}H ALWAYS!L X;V CANTWR!ERRCMD` X;j BUFADJ,t QMAXLEN9~ PCURLEN9 OICBALZ PICBALZ DRBAOK #ICBALZ RBA}OK; QICBLLZ SMAXLEN9 PICBLLZ ERBLOK "ICBLLZ RBLOK: X; X; RETURN FILE STATUS X; .DKSTAT SETUP;;S}ET UP RETURN ADDRESS, ETC. ( LFFILE;;FIND IF FILE IS THERE, ETC.(  TSTLOK;;IS IT LOCKED?2 "TODONE!DONE;;RETURN TO CALLE}R< X;F -X; CLOSE FILE (WRITING ANY PENDING SECTOR)P X;Z DKCLOS SETUPd QFCBOTC9n M>;;OUTPUT ALLOWED?x FCLROTC;;IF }NOT, JUST EXIT UFCBFLG9 DCKFLSC $ REWRIT;;REWRITE THE LAST SECTOR RRDIR QSECCNT9 %DIRDSP PDIRBUF8 Q}SECCNT9 PDIRBUF8 QDIRBUF8 %M>;;NOT OPEN FOR OUTPUT ANY MORE SAVFLAG QSAVSEC9 LSAVSEC9 FCLROTC} (LSTIOCB" FFAPPD, ' INITYP;;READ ALL THE SECTORS AGAIN6 APPLP RDNXTS@ DAPPLP;;NOT EOF YETJ ETIELNKT FAPPDQLS}TSEC^ PCURSEC9h QLSTSECr PCURSEC9| TIELNK, RWDISK QDLINK PCURLEN9 QSAVSEC9 %SAVSEC9 SAVL}NK CLROTEICLROTC "Q>;;FAILURE IS A SYSTEM ERROR !AEXIT CLROTCQ> PICHID9 Q> PFCBOTC9 !FREDON X;} CKFLSCUFCBFLG9& DCLROTC0 WRDISK: !CLROTED X;N INITYPQ>X GETFLAGb V?l W?v W? W? LFCBOTC9 PFCBOTC}9 QDIRBUF8 PLNKSEC9 QDIRBUF8 PLNKSEC9 QCURFNO PFCBFNO9 Q> PFCBFLG9 PCURLEN9 PSECCNT9} PSECCNT9 : X; X; DOS XIO ROUTINES* X;4 X;> LX; Sorry about the lack of comments in this file and some of the o}thers,H HX; I just never had to figure this code out after I wrote it (:-)!R X;\ $NODIRFQ>;;FILE NOT A DIRECTORYf !A}EXITp X;z 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$ TONXDR.FNODIRF;;IF NOT A} DIRECTORY8QDIRBAS9B?L QDIRBAS9V-SAVDEF'CDIREC;;UPDATE ADDRESS OF DIR.` PCDIRECj QICDNOZt PDEFAULT;;UPD}ATE UNIT NUMBER~ ITOFDNX;SETRDIRQ>i %>i ISAVDEFX;1RENAME LFFILE;;GET OLD NAME, DRIVE, VALIDAT}E%> STEMPLQFNAME8PMAPBUF81 HSTEMPL+RNLOOP TSTLOK;;CANNOT RENAME IF LOCKED TDDOS;;TEST FOR D}OS GONE!  %TMP2 GETNAM;;GET NEW NAME,($ ENTNAME;;OVERWRITE NAME IN DIR.2& WDIRBK;;REWRITE DIRECTORY TO DISK<X;}F TSTDOS;;NEW NAME DOS.SYS?PHREPLDS;;NO, LOOK AT NEXTZ %DIRDSPdQDIRBUF8n5xQDIRBUF8?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 DEL}ETED?"Q>,% SAVFLAG;;REWRITE DIRECTORY BLOCK6 CSFDIR@DDELLP;;IF ANOTHER FOUND,J)TOFDN!FREDON;;ELSE, WRAP UP AND} EXITTX;^0REMOVE TSTLOK;;ONCE HAD 'OPVTOC' CALL FIRSTh INITYPr 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 WRITABLE&#LKULKLQ>;;STRIP OFF OLD BIT 50 GETFLAG:!LDATB}YT;;AND REPLACE WITH NEWD SAVFLAGN CSFDIRX DLKULKLb ETOFDNlX;vDELDIR%> Q> ?DELSETPFNAME 83} HDELSET SFDIR DINVDELX;Q> PDATBYT TONXTDELDRL FREE INCCSEC "DATBYT HDELDRL  !GETFNM}X; POINT%FCBFLG9* GERRCMD4X;>QICSPR9HRCURSEC9R HPNTREAD\ QICSPR9f RCURSEC9p FPNTSMEz PNTREAD}C!FPNTCLN;;IF SECTOR UNMODIFIED WRDISKQ> PFCBFLG9PNTCLNQICSPR9PLNKSEC9 QICSPR9 PLNKSEC9}" CHASE;;READ SECTOR POINTED TO EBADPNTX;PNTSMEQICSPR9 RMAXLEN9 EPNTEQLPNTLSTPCURLEN9 !DONE$X;}.,PNTEQLFPNTLST;;IF POINTING AT LAST BYTE8&BADPNTQ>;;INVALID POINT LOCATIONB LX;V&ERRCMDQ>;;INVALID IOCB PAR}AMETER` !AEXITjX;tNOTEQCURSEC9~ PICSPR9QCURSEC9PICSPR9 QCURLEN9PICSPR9 !DONEX;DKX}IO SETUPQICCOMZ;;GET COMMAND BYTER> FFORMATR>+EERRCMD;;IF INVALID COMMAND S>   DERRCMD? QV}ECTBH8(52 QVECTBL8<5F:;;VECTOR TO PROPER ROUTINEPX;Z,VECTBH RENAME =DELETE d" MKDIR =}LOCK n$ UNLOCK =POINT x# 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%> %WOTCOPY2QWOTDCB8;;set up DCB for"PDDEVIC8;;densi }ty stuff,16 IWOTCOPY2@ $ICDNOZJ (RAMDKUT%FWOTRAM;;don't do it for RAMdisks^%SECSIZ9hQDRVDEF9r SETDRV };;set density|!WOTRAM$CURFCB;;restore X reg%>(C;;THEN INITIALIZE NEW BIT MAP (VTOC)CLRMAPPMAPBUF8PMAPBUF }83)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 %ICDNOZ )RAMDKU(FRAMFMT;;IF RAMDISK, SKIP EVERYTHING&}QFMSBPT0(%FMSBPT;;call density junk for patch:/ BUFSET;;SET UP BUFFER POINTER FOR SIO CALLD$>N&TMP1;;ALLOW ONE} TRY ONLYX(Q>";;PRESUME 1050 D/D FORMAT REQUESTb%ICAX2Z;;THEN GET AUX2 BYTEl(GFMTOK;;MINUS --> NO FORMAT REQUIREDv H}NMLFMT%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 SECTOR > 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) ORDK}LMT V?* WCURSEC94,HNOTDEF;;FAIL IF NOT 256 SECTORS OR MORE>X;H8X; SUCCESSFUL FORMAT, CREATE VTOC AND EMPTY DIRECTORY}RX;\%FMTOK%>;;check for a bad formatf Q@FMSBPT7p#M@FMSBPT7;;first two bytes $FF?zR>FFMTOK2;;yep, continue}Q>;;otherwise format error HFMEXIT.FMTOK2 INVUNIT;;MAKE SURE WE CAN DO THIS!- DELDOS;;DELETE ANY CURRENT DOS BOO}T FILE QICAX1Z PCURSEC9 QICAX2Z#M>;;DISK MUST HAVE 256 SECTORS&HNOTDEF;;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?$!IFIGSIZ;;NO, FIGURE SIZE THEN.'Q>;;YES, FORCE TO 1040 SECTORS8 PCURSEC9B Q>L HNOTD}EFVX;`FIGSIZQDRVDEF8j"M>1;;EXTRACT TRACK COUNT FLAGStV?~6V?V??0QNOSECS8;;AND USE DRIVE DEFAULT SEC}TOR COUNT PCURSEC9QNOSECS88,DNOTDEF;;IF NOT DOUBLE SIDED, THIS IS IT TCURSEC9U?;;ELSE, DOUBLE ITX;}NOTDEFPCURSEC9R>;;NEED 16 BIT LINKS?  DSHORTS;;NO, SHORT FORMAT OK*#MAPBUF;;YES, FORCE LONG FORMAT (DOS3),}SHORTS FNDBIT;;FIND LAST BIT MAP SECTOR( QTMP22"HGT246;;IF PAST 256TH MAP BYTE<*DLINK;;SINGLE DENSITY?F GFDBDENP)}>Z IFDBDENdGT246PMAP2n,xO> PMAPBUFFDBDENQ> PMAPBUF Q> 2PMAPBUF;;START WITH} 9 FREE SECTORS UN-FREE!FLOOP FMTFRE DECCSECR>;;BOOT SECTORS YET?)HFLOOP;;IF NOT, CONTINUE DEALLOCATINGQ }CURSEC9 HFLOOPX;Q>;;success)PFMSBPT;;bad sector code deleted hereX;Q>">PMAPBUF7;;ALLOCATE THE RO!}OT DIRECTORY AND BASE VTOC SEC.,*Q>;; NOTE: ALWAYS THE SAME 9 SECTORS6PMAPBUF8@"%>,;;START ALLOC. OF VTOC HEREJ Q"}MAPBUFT;^S>;;GET NUMBER OF SECTORSh*DLINK;;(SINGLE DENSITY?)rGMPNSD;;IF NOT, M-3|T?;;IF SO, M*2-5 MPNSD>#}0;;MOVE COUNT TO XX;ALCMPLQ> ALCMAP0 GSMBSIZ5 DECCNT7T? HALCMAPPMAPBUF 81IALCMPL;$};BRANCH ALWAYS!X;SMBSIZPMAPBUF 8&$QMAPBUF;;MARK EMPTY SIZE, TOO0PMAPBUF:QMAPBUFDPMAPBUFN %}FMTMAP;;WRITE MAP TO DISKXX;b X; CREATE AN EMPTY DIRECTORYlX;v Q>i %>i3CLRDIR SETDIR;;RESET THE DIREC&}TORY BASE SECTORC$CLRDLPPDIRBUF8;;ZERO THE BUFFER3 HCLRDLPX;Q> PDIRSEC1CLRDL2 WDIRBK;;THEN WRITE '}8 SECTORS OF ZEROS "DIRSEC ICLRDL2 %BUFNO9Q>  PBUFNO92PBUFFLG8;;DONE, SO FREE UP INTERNAL BUFFERS  QF(}MSBPT* !AEXIT4X;>"NOSECS #=(=P=MHX;RSETDIRPDIRBAS9\CfPDIRBAS9p%>z:X;X; DOS BI)}NARY LOAD CODEX;X;.X; LOAD AND EXECUTE A BINARY FILE (PROGRAM)X;DKLOADQICAX1Z-PICPTLZ;;SAVE PROGRAM NAME B*}UFFER POINTERR>#ETOERRC;;IF WRITE, REPORT ERRORX;Q>TORTS PRUNADR-Q>TORTS;;ASSUME RUN ADDRESS IS A+}BSENTPRUNADRQ>$ PICAX1Z.QICHID9;;IOCB OPEN?8 ICCFILEB DKOPEN;;IF NOT, OPEN ITL GDKLERVV WDREAD;;RE,}AD A HEADER WORD` FCCFILEj+%>;;NO $FFFF, REPORT HEADER ERROR CODEt GDKLERV~X;TOERRC%>;;INVALID IOCB:X;-}GETTXTQ>TORTS PINIADR:Q>TORTS;;FOR EACH SEGMENT, RE-FORCE NULL INIT CODEPINIADRTXTLP DKREADDK.}LERVGDKLERR%> P@ICBALZ7 #ICBALZ HDECLEN  #ICBAHZDECLENQICBLLZ HDECLOW( "ICBLHZ2DECLOW"ICBLLZ</} HTXTLPF QICBLHZP HTXTLPZ QICBAHZdR>INIADRn HCCFILExX;QICPTLZ;;IF NO INITS,V?ECCFILE;;SKIP TO NE0}XT PAGEA;;ELSE SAVE IOCB5 %> CPSICBQICHIDZ 8$PICHID9;;SAVE 12 BYTE IOCB ENTRY23 HCPSICB1}7>5# DOINIT;;AND CALL INIT FUNCTION7">,56 %> @1CPRICBQICHID9;;THEN RESTORE THE 12 BYTE IOCBJPICH2}IDZ 8T2^3h HCPRICBr7|>X;&CCFILE WDREAD;;READ START ADDRESS FCCFILE PICBALZ 'ICBAHZ WDREAD3};;READ END ADDRESS;O> DCCSUBT3 CCSUBT;!SICBALZ;;CALCULATE THE LENGTH PICBLLZ C SICBAHZ PICBLHZ4}& 0EGETTXT;;BRANCH IF A VALID LENGTH (GET DATA)0 %%>;;ELSE, MEMORY WRAP ERROR CODE: GDKLERRD X;N WDXIT7X 7b DKLERR5}Cl 5v  DKCLOS;;CLOSE PROGRAM FILE 7 (?;;AND RETURN HIS ERROR CODE (IF ANY) : X; BX; READ A WORD FROM THE PROGRAM 6}FILE AND COMPARE IT WITH $FFFF X; WDREADQ> PICBLLZ PICBLHZ;;SET LENGTH TO ZERO  DKREAD;;READ A BYTE GWDEOF7} 5  DKREAD;;READ THE SECOND! GWDEOF1 !?!7 !)>;;UPPER BYTE $FF?*!,HTORTS;;IF NOT, TOTAL VALUE IS NOT $FFFF4!%R>8};;UPPER OK, IS LOWER BYTE $FF?>!.TORTS:;;RETURN ZERO FLAG IF WORD WAS $FFFFH!X;R! WDEOF17\!#WDEOF)>;;IS THIS END OF FI9}LE?f!%HWDXIT;;IF NOT, RETURN ERROR CODEp!7z!"7;;ELSE, GET RID OF RETURN ADDR! QICPTLZ!V?!V?!6!# DKCLOS;;CLOSE FIL:}E AND SET Y=1!8!$ETORTS;;EXIT IF NO-RUN SPECIFIED!+!@RUNADR:;;OTHERWISE, GO TO RUN ADDRESS!X;!FX; INVOKE INIT FOR E;}VERY BLOCK OF INPUT CODE (USUALLY JUST AN RTS)!X;!#DOINIT!@INIADR:;;CALL INDIRECTUN ADDRESS!X;!FX; INVOKE INIT FOR EVI #X;save#d:MDOS3.M65 MYDOS moduleX;X; DOS MAKE DIRECTORY CODE(X;29X; Copyright 1984, Charles Marslett, Wordma=}rk Systems<X;FIX; Permission is granted by the author for any use whatsoever of thisPHX; code, so long as this notice>} remains in the source code, and soZLX; long as the source to this routine, however modified or unmodified,d.X; is ma?}de available for a nominal cost.nX;x-X; XIO FUNCTION TO CREATE A NEW DIRECTORYX;X; PARSE DIRECTORY NAMEX;MK@}DIR GETFNM" SFDIR;;FIND FILE IN DIRECTORY EMKDMRDQ>;;FILE ALREADY EXISTS ;;SKIP 2 BYTESDISFULQ>;;DIRECA}TORY FULL !AEXITX;X; READ IN BIT MAPX;MKDMRDQHOLFN GDISFUL RBITMP" %MAPBUF,161@ 'DATBYTJX;B}T'X; FIND EIGHT SECTORS FOR DIRECTORY^X;h3Q>q;;FIRST AVAILABLE SECTOR AFTER ROOT DIR.r PCURSEC9| Q>qPCC}URSEC9Q> PTMP1FDIRLP#TMP1" FNDLBIT;;IS THIS SECTOR FREE? EFDIR2 MMAPBUF8 DFDIR1FDIR2MMAPBUFD}8FDIR1HFDIR3 PTMP1FDIR3 INCCSEC QTMP1R> HFDIRLPX;& X; ALLOCATE THE SECTORS USED0X;:ALCDLE}P DECCSECD FNDLBITNN>X EALCPG2b MMAPBUF8l PMAPBUF8v DALCPG1ALCPG2MMAPBUF8PMAPBUF8 VMAP2MOF}DALCPG1 DECCNT "TMP1 HALCDLPX;(X; WRITE ALLOCATION MAP BACK TO DISKX; FMTMAPX;5X; ENTER NAME ANG}D TYPE INFO INTO PARENT DIRECTORYX; QHOLFN  SDIRBK;  ENTNAME*QCURSEC94PDIRBUF8> QCURSEC9HPDIRH}BUF8RQ>\PDIRBUF8fQ>pPDIRBUF8zT? SAVFLAGX;X; THEN CLEAR NEW DIRECTORYX;Q> PFMSBI}PT QCURSEC9%CURSEC9 !CLRDIRX;$X; SIMULATE OLD STYLE BIT FINDERX;FNDLBIT FNDBIT5;;SAVE MASKQJ}TMP2;;FIRST PAGE? FFNDPG0$'TMP2;;SAVE OFFSET IN PAGE. RDATBYT8 EDFEJMPB RDNXTM;;READ IN PROPER PAGEL$%TMP2;;THK}EN RESTORE A AND Y REGSV7`!;;;SET CY (PAGE 1 BUFFER USED)j:tX;~FNDPG07;;RESTORE SAVED MASK,;;AND CLR CY (SAY PAGL}E 0):X;DFEJMP!DFERRX;DECCSECQCURSEC9 HALCPG0"CURSEC9ALCPG0"CURSEC9:X;INCCSEC#CURM}SEC9 HDELDIN #CURSEC9 DELDIN:X;(X; DOS DIRECTORY ROUTINES2X;<X;F/X; OPEN A DIRECTORY (FOR DIRECT USER AN}CCESS)PX;ZLSTDIR%> dSAVFNBQFNAME 8n P@FMSBPT7x3 ISAVFNB) SFDIR;;FIND A MATCH IN THE DIRECTORY-EO}ENDDIR;;IF NO MORE, GO REPORT FREE SPACE1NXTDIR FMTDIR;;ELSE, FORMAT INTO TEXT STRING QCURFNO-PFCBFNO9;;SAVE FILE P}NUMBER OF ENTRY FOUNDGODONE!DONE;;AND RETURNX;1GOTEOD"DATBYT;;CONVERT EOL TO $9B (REAL EOL)PCURLEN9;;AND FINIQ}SH UP HGODONEX;X;DIRRD%> | FGOTEODS}R>;;IS THIS END OF LINE?'HGODONE;;IF NOT, CONTINUE TEXT DUMP QFCBFNO9 RCURFNO HDMSTRD (DIUNIT FDRDNRQT}DMSTRD RRDIRDRDNRQ CSFDIR DNXTDIRX;0X; NO MORE ENTRIES, REPORT FREE SECTORS LASTX;&ENDDIR RBITMP;;READU} THE VTOC DATA%>%'CURMAP;;FORCE A REREAD NEXT TIME&QMAPBUF0:$MAPBUF;;AND STUFF BUFFER WITH NUMBER OF FREE V}SECS.: CVTDECD$>N9FSECLQFSECM9;;FOLLOWED BY "FREE SECTORS" TEXTX P@FMSBPT7b3l2v HFSECL#FGODONE;;W}THEN LAST LINE IS DONEX;:DIREOF!RETEOF;;NO MORE LINES, RETURN E-O-F INDICATIONX;FSECM A FREE SECTORSA=X;X}/X; FORMAT A DIRECTORY ENTRY FOR BASIC, ETC.X;FMTDIR%> ;;space $DIRDSP QDIRBUF95M>  FNOTLCK %> *;Y};IF SO, MARK AS LOCKED NOTLCKC %>* P@FMSBPT747>%> ;;spaceHM>R FNOTDIR\%> :f NOTDIRCp%>z P@FMSBPZ}T7 CPYNAML3QDIRBUF9 P@FMSBPT72)>  DCPYNAMLX;Q> ;;space P@FMSBPT7 %DIRDSPQDIRBUF8[}$DIRBUF8!%>;;SECTOR COUNT STARTS HERE X; 8X; CONVERT A 16-BIT INTEGER TO A 4 OR 5 DIGIT NUMBER X;$ CVTDEC&T\}MP2. PTMP18 $>'B Q>'L MKDGT2V R> 0` HSKIP5j 1t SKIP5$>~ Q> MKDGT2 Q>d;;FOR SHORT]} STUFF MAKDGT Q> MAKDGT A O> 0 P@FMSBPT7 3 Q>;;TERMINATE LINE PDATBYT P@FMSBPT7 Q> $^}CURFCB PCURLEN9 :( X;2 ;;IF SUBTRAHEND < 2_}56, ZERO UPPER BYTEP MKDGT2&DIRDSPZ PDIRSECd 'DATBYTn %> 0x ; DGTLP2QTMP1 SDIRSEC > QTMP2 SDIRDSP D`}DGTXIT PTMP2 &TMP1 3 EDGTLP2 X; DGTXITC %DATBYT P@FMSBPT7 3 :" X;, @X; PARSE A FILE NAME WITH WIa}LD CARD CHARACTERS ('*' AND '?')6 X;@ GETNAM23;;look for ">" inJ Q@ICBALZ7;;the start ofT R> >;;the filename^ FGETNAMb}h 1r HGETNAM;;branch always| X; GETFNM$CURFCB %>i Q>i SETDIR 3 Q@ICBALZ7 3 R> :;;DEFAULT c}DIRECTORY? HGETNAM2 1 'TMP1 %DEFAULT 'ICDNOZ C PICDNO9 SETUPD& QCDIREC0 %CDIREC: SETDIRD %d}TMP1N X;X GETNAM$> b 3l AFTSTRQ@ICBALZ7v R> * HTSTPER Q> ? 3 QLOOPPFNAME 9 2 ITOXITC;;END OF e}EXTENSION? "PERFND(>;;END OF FILE NAME? HQLOOP;;NO MORE -?-S FAFTSTR X; TSTPERR> .;;A PERIOD? 4HTSTCHR;;IF f}NOT, CHECK FOR INDIVIDUAL CHARACTERS Q> ;;IF SO, FILL WITH SPACES 3 HPERFND X; TSTCHRR> ?* &DENDCHR;;IF < '?', g}CHECK FOR DIGIT4 1R> Z;;ELSE, UPPER CASE LETTER, '?', OR '@'?> DGOTCHRH R> _R *DENDCHR;;IF CARET, BACKSL. OR BRACKETS\q}"B#DOS SYSB6'DUP SYSB]MDOS M65B[_MDOS1 M65BMDOS2 M65B<MDOS3 M65BMDUP M65B'MDUP1 M65BMDUP2 M65 -R> z;;LOWER CASE, ACCENT OR UNDERSCORE?f DGOTCHRp %ENDCHR(> ;;IF FIRST CHAR, ERRORz "FERRCHR;;NO BYTES IN FILE NAMr}E R> 0;;ELSE, A DIGIT? (DFILLNM;;IF NOT, THIS IS END OF NAME R> : EFILLNM X; GOTCHRPFNAME 9 3 2 Gs}AFTSTR X; TOXITCQ@ICBALZ7 TSTDIRR> :;;look for MYDOS FMYDIR;;or SpartaDOSR> >;;directory separator HXITCHRt}MYDIR'TMP2$ SFDIR;;ELSE, FIND FILE.EFNER1;;NO SUCH FILE8 TONXDRB FFNER1L %TMP2V HGETNAM`'FNER1Q>;;IF Nu}OT, RETURN ERROR 174j ,;;BIT ABS (SKIP 2 BYTES)tX;~ERRCHRQ> !AEXITX; FILLNM5Q> ;;spaceFILLLPPFNAMv}E 92 GFILLLP7 !TSTDIRX;7X; RETURN WITH NON-ZERO FLAG IF FILE IS A DIRECTORYX;(TONXDRQ>;;FILE w}FOUND, A DIRECTORY?  GETFLAG"FTONXIT;;IF NOT, SET ZERO FLAG4QDIRBUF8;;YES, MOVE POINTERS TO THE NEW LEVEL( PDIRx}BAS92QDIRBUF8<PDIRBAS9FQ>;;AND CLEAR ZERO FLAGP TONXIT:ZX;d8X; ENTER A NAME INTO THE DIRECTORY AT DIRBUy}F[DIRDSP]nX;x ENTNAME6$>  %DIRDSP2NAMELPQFNAME 9;;LOAD THE MASK CHARACTERR> ?'HSTORIT;;IF NOT '?'z}, SAVE IT AS IS!863DNOSTOR;;IF CY CLEAR, LEAVE CHARACTER UNCHANGED,Q> ;;ELSE, IF CY SET, CONVERT '?' TO ' 'ST{}ORITPDIRBUF8 NOSTOR32 GNAMELP8 %DIRDSPXITCHR$CURFCB":,X;6)SFDIR WBITMP;;INSURE BIT MAP IS SAFE|}@$>J &HOLFNT &CURFNO^2h &DAUX2r2| &DAUX1 $>READ &DCOMND8 SYSSET;;SET UP POINTERS, ETC. FOR A NEW DIS}}K ACCESS QICDNOZ RRAMDKU.FCSFDIR;;IF RAMDISK, FORGET DENSITY CHECK! $CURFCB;;don't read boot sec"QDIRBAS9;;if ~}in subdirectories$R>i;;but allow if first read HCSFDIR- DSKINV;;ELSE, READ THE FIRST BOOT SECTOR GERRX( IN}VUNIT;;UPDATE DRIVE CONFIGURATIONX;0CSFDIR#CURFNO;;READ NEXT 16-BYTE DIR. BLOCK QCURFNO&/ BSECDS;;CONVERT TO SECT}OR AND DISPLACEMENT0XITCHR1EXITCHR:%HNOREAD;;IF DISP>0, PROCESS BLOCKD# RDIRBK;;IF DISP=0, READ SECTORNX;XNOREAD}%DIRDSPb QDIRBUF8l7FFNDOLD;;ZERO IS END OF DIRECTORY (NO MORE ENTRIES)v;GFNDOLD;;NEGATIVE IS EMPTY SLOT (MAY HAVE MORE} ENTRIES)M>;;preserve lock flag R>;;is this DOS 2.5 + file?HNOD25;;nopeQ>A;;otherwise, kludge theNDIRBUF}8;;flag to make $42PDIRBUF8;;and save lock. NOD25M>8HCSFDIR;;IF OPEN/CREATE FILE, IT IS NOT REALLY HERE!$> }CPNXCHQFNAME 9R> ?#FWCMTCH;;EVERYTHING MATCHES '?'RDIRBUF84HCSFDIR;;IT DOES NOT MATCH, LOOK AT THE }NEXT ONE  WCMTCH32  GCPNXCH*,4*DXITCHR;;ENTRY FOUND, RETURN WITH CY=0>X;HFNDOLD$HOLFNR9IKPOLD;;IF AN EMPTY} SLOT IS ALREADY FOUND, DO NOTHING\ $CURFNOf5&HOLFN;;ELSE, SAVE THE SLOT NUMBER (FIRST EMPTY!)p KPOLD>z2GCSFDIR;;IF N}OT END OF DIRECTORY, KEEP LOOKING ERRX;5EXITCHR1;;ELSE, ENTRY NOT FOUND, RETURN WITH CY=1X;X; DOS I/O ROUTINES}X;X;X; DISK SECTOR I/O ROUTINESX;!WRDISK;;;FMS DISK WRITE ENTRY0RWDISK%FMSBPT;;DATA SECTOR READ/WRITE ENTRY}QFMSBPT BUFSETQCURSEC9 %CURSEC9 FMDKIO6 $DUNIT$ (RAMDKU. FRDKIO188B5LQSECSIZ9V>`7}j !DKIOtRDKIO1!RDKIO;;was moved...~X;EXTEND ALLOC QFCBOTC9V? DREWRIT "FCBOTC9 WTRICK !WRTTST}X;REWRIT%LNKSEC9 QLNKSEC9 SAVLNKWRTTSTGRTBADF #SECCNT9  HTONXT#SECCNT9X;($TONXTQLNKSE}C9;;MAKE NEXT SECTOR2PCURSEC9;;NEW CURRENT SEC.<QLNKSEC9FPCURSEC9PQ>ZPLNKSEC9;;ZERO LINKdPLNKSEC9}n(LENSETPCURLEN9;;ZERO CURRENT OFFSETxQDLINK;;GET THE LINK LOC.PMAXLEN9;;MAKE IT MAX. LEN.,;;CLEAR CY FOR LATER }READ:X;RDNXTSQFCBFLG9 FCHASEX;WRNXTSQFCBFLG9 GEXTENDT? IRDNXTST? PFCBFLG9 WRDISK I}RDNXTSX;"8RTBADF!HWERR;;RETURN HARDWARE ERROR CODE IF PRESENT,X;6 SAVLNK5@CJ %DLINKT P@FMSBPT7^7h3r P@}FMSBPT7|3 QCURLEN9NOBITP@FMSBPT7 %FCBOTC9GLEN16;;16-BIT LENGTH? QFCBFNO9T?T? %DLINK L@FMSBPT7} P@FMSBPT7LEN16!WRDISKX;WTRICKQLNKSEC9 PSAVSEC9QLNKSEC9PSAVSEC9& &LSTIOCB0 QCURSEC9: P}LSTSECDQCURSEC9NPLSTSECX !WRDISKbX;lINSTRT INITYPvX;CHASEQLNKSEC9LLNKSEC9 FNOLINK TO}NXT;;SET CY=0, FUNC=READ RWDISK4GRTBADF;;CANNOT READ SO BAD FILE NUMBER(ERR=164) %DLINKQFCBOTC9;;16-BIT LINK?}L> GLNGLNK Q@FMSBPT7V?V? RFCBFNO9  HXLINKEDQ> LNGLNKM@FMSBPT7*PLNKSEC943> Q@FMSBPT7H }PLNKSEC9R3\ Q@FMSBPT7f PMAXLEN9p DRDXIT,z:X;XLINKEDQICCOM9R>FMTCMD;;IS THIS A FORMAT? HFNOERR NO}LINK;:X;%X; READ OR WRITE A DIRECTORY BLOCKX;RRDIRQFCBFNO9X;SDIRBKPCURFNORDCFNOQCURFNO BSECD}SX;1RDIRBK WBITMP;;TAKE CONTROL OF SYSTEM BUFFER$,. ;;LDA # (SKIPS 1 BYTE)8 WDIRBK;B RWDBK6L$CURFCB;;PUT }FCB NO. IN XV&&DIUNIT;;SAVE THE DIR. BUFFER IOCB` SYSSETj,t QDIRSEC~ ODIRBAS9?QDIRBAS9!O>;;MULTIPLE }DIRS. REQ. THIS8SYSRW FMDKIO IDRDXIT3Q>;;BIT MAP R/W ERROR, RETURN SYSTEM ERR. CODE ;;SKIP 2 BYTESX;}FNOERRQ> PDSTATS !HWERR;;FILE NUMBER MISMATCHX; +X; READ OR WRITE THE DISK VTOC (BIT MAP)X;RBITMPQCURMA}P( RICDNOZ2.FMAPXIT;;IF WE READ WHAT IS ALREADY THERE!<9 WBITMP;;ELSE, REAL I/O, SAVE CURRENT BUFFER CONTENTSFX;PQ>}Z?d'ZMAPPMAPBUF8;;THEN ZERO ENTIRE 512n#PMAPBUF8;;BYTES OF MAP BUF.x1 HZMAP,4 RWBMAP;;THEN READ 128 O}R 256 BYTES OF VTOC DATAX;%>8'DIUNIT;;INDICATE MAP IS LOADED (NOT DIRECTORY DATA)1'MAP2;;INDICATE NO DATA IN SE}COND PAGE OF MAP3&'CHGMAP;;INDICATE MAP IS UNCHANGED3 'MAP2MOD 'CURMPX;8MAPCLRPCURMAP;;AND SAVE DRIVE N}UMBER MAP APPLIES TO MAPXIT:X;"WBITMPQCHGMAP,0FMAPCLR;;IF MAP NOT CHANGED, SKIP WRITING IT6 PDUNIT@FMTMAPQ>}J!PCHGMAP;;ELSE, MARK IT UNUSEDT PCURMAP^QDUNIT;;save drive #h5r ;;;SET CY TO INDICATE A WRITE|3 RWBMAP;;AND CAL}L THE READ/WRITE SECTOR ROUTINE7;;restore drive # PDUNITX;WRNXTMQMAP2MOD)HNOMAPI2;;IF THE PAGE BUFFER IS CLE}ANQ>;;JUST EXIT, ELSE5 QMAP2 #MAP2MOD;)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 ONE05:.,;; BY FALLING INTO MUSTWM WITH CY CLEAREDDX;N MUSTWM5XQ>MAPBUF }b%>MAPBUF l3 BUFSET;;SET UP BUFFER POINTERS FOR SECOND PAGEv7;; OF VTOC BUFFER# MAPIOC;;ISSUE I/O OPER}ATION(S)77PMAP2;;UPDATE ID FOR CONTENTS OF SECOND PAGE BUFFER NOMAPI:X;9RWBMAP SYSSET;;SET UP BUFFER POINTERS} FOR SYSTEM I/OQ> MAPIOC65$QSECSIZ9>7(>;;256 BYTE SECS?  FMAPDDS-T?;;128, CHANGE PAGE }NUMBER TO PAIR NUMBER MAPDDSN>*;4 O>h>?H!(>;;128 OR 256 BYTE SECTORS?R2FDDMAPX;;IF 128, READ 2 SECTORS TO} FILL BUFFER\ Q>hf8p6z& SYSRW;;READ OR WRITE FIRST SECTOR QMAPBUF.R>;;IF DOS 2.0 DISK, ONLY ONE SECTOR EV}EN!DXITMBF;; IN SINGLE DENSITY! STEPBP1DDMAPXQ>h86/ SYSRW;;READ OR WRITE SECOND OR ONLY SECTOR} XITMBF8NOMAPI2QICDNOZ.PDUNIT;;RESTORE USER DRIVE NUMBER TO DUNIT0:;;SINCE THIS MAY HAVE BEEN ON ANOTHER DRIVE!}X;/SYSSETQ>MAPBUF;;SET UP BUFFER POINTERS%>MAPBUF$ !BUFSET.X;8EX; ROUTINE TO STEP TO THE NEXT DIRECTORY} ENTRY (UNTIL WE RUN OUT)BX;LBSECDS%>V 'DIRDSP`V?j WDIRDSPtV?~ WDIRDSPV?9WDIRDSP;;(FILE NUMBER MOD 8) }* 16 IS OFFSET IN SECTOR+PDIRSEC;;FILE NUMBER/8 IS SECTOR OFFSETX;R>;;END OF DIRECTORY?16EBSECXT;;IF SO, RET}URN CARRY SET (VALUES ARE BAD!)3WDIRDSP;;FINAL SHIFT SO NUMBER IS *16 (NOT *32) BSECXT:X;X; DOS ALLOCATION ROUTIN}ESX;X; !X; FREE A SECTOR FOR LATER USEX;1FREE RBITMP;;MAKE SURE WE HAVE THE RIGHT MAP( PCHGMAP29FMTFRE#MAP}BUF;;BUMP LOW BYTE OF FREE SECTOR COUNT<HFREE0;;IF NO CARRYF#MAPBUFPFREE0 FNDBITZ5d QTMP2n FSBMP1x 'T}MP2RCURMP;;BEFORE FIRST HOLE?ESBMP2;;NO, LEAVE UNCHANGEDPCURMP;;YES, NEW FIRST HOLESBMP2 RDNXTM %TMP2"V}MAP2MOD;;MARK MAP PAGE2 DIRTY7LMAPBUF8PMAPBUF8:X; SBMP17 LMAPBUF8 PMAPBUF8:X;"3X; F}IND BIT ASSOCIATED WITH A SECTOR ON THE DISK,X;6FNDBITQCURSEC9@M>;;EXTRACT THE BIT NUMBERJ?T;^Q>h.FREE1W?};;POSITION CARRY TO THE BIT TO FLIPr1| IFREE15;;SAVE THE BIT MASKX; QCURSEC9,$O> ;;ALLOW FOR 10 BYTE HE}ADER?;;SAVE LOW BYTEQCURSEC9O>;;PROPOGATE CARRYW?;;fix 65535 sector bug PTMP2CW? VTMP2 W? V}TMP2 W?& ?0 X;: 7;;RESTORE THE BIT MASKD :N X;X )X; ALLOCATE AN UNUSED SECTOR TO A FILEb X;l ALLOC RBITMPv PCHG}MAP %> Q> PTMP2 !ALL1RMAPBUF8;;ANY BITS LEFT? HSECFN1;;IF SO 3 HALL1 X; ; QMAPBUF SCURMP ;} S>! PTMP1 !ALLCKGALGONE! QCURMP ! PTMP2*! RDNXTM4!Q>>!?H!ALL2RMAPBUF8R!1HSECFN2;;IF FREE SECTOR IN }SECOND PART OF MAP\!3f! HALL2p!%#CURMP;;TO NEXT SECTOR OF BIT MAPz! "TMP1! IALLCK!X;!ALGONE"CURMP!#DFERRQ>;;D}ISK FULL ERROR CODE!%!AEXIT;;IF THIS IS IT, ERROR-EXIT!X;! SECFN1;!$>;;I.E., -8*10 - 1! ALL3W?!2! RMAPBUF8! }DALL4!," HALL3"ALL4NMAPBUF8" PMAPBUF8$" IALL7."X;8" SECFN2;B"$>;;I.E., -8*10 - 1L" ALL5W?V"2`"RMAPBUF}8j" DALL6t",~" HALL5"ALL6VMAP2MOD"NMAPBUF8"PMAPBUF8"X;" ALL7C"T?" UTMP2"T?" UTMP2"T?" U}TMP2" PTMP1#A # OTMP1# $CURFCB# PLNKSEC9(# QTMP22#O><#PLNKSEC9F#DECCNTQMAPBUFP# HNOBORZ#"MAPBUF}d#NOBOR"MAPBUFn#,x#:#X;#X; DOS MISC. SUBROUTINES#X;#X;#%X; SET UP STATE VARIABLES ON ENTRY#X;#SETUP%IC}DNOZ;;GET UNIT NO.#SETUPW&CURFCB#@#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 UN}IT, TEST FOR CURRENT DENSITY6$@UFIXEDPSECDAT;;OTHERWISE, STORE CORRECT DENSITY INFORMATION@$V?J$W?T$W?^$4L>};;AND UPDAT}E LINK POSITION IN THE DISK SECTORh$ PDLINKr$X;|$ $CURFCB$"%BUFNO9;;GET THE BUFFER NUMBER$ HRSETUP$#%FILES;;IF ONE I}S NOT ALLOCATED$3$ SFORB1$6FNOSECB;;ALLOCATE ONE, OR ABORT THE OPERATION NOW!$QBUFFLG8$ HSFORB$Q>$PBUFFL}G8$C$ PBUFNO9$RSETUPQDOSEND;;==SBTABL%3PFMSBPT;;STORE THE BUFFER POINTER FOR THIS FILE%4QSBTABU8;; IN THE }ZERO PAGE POINTER "FMSBPT"%PFMSBPT&%:0%X;:%(INVUNIT JSTRD;;TEST FOR DRIVE STATED%5HUFIXED;;IF IT IS ACCESSABLE, RE}TURN REAL DENSITYN%X;X%0NOUNITQ>;;RETURN ST=160, DRIVE NOT PRESENTb% ;;SKIP TO JMP INSTRUCTIONl%3NOSECBQ>;;RETURN S}T=161, NO MORE FILE BUFFERSv% !AEXIT%X;%+X; REMOVE DOS POINTER FROM BOOT SECTORS%X;%'TDDOS TSTDOS;;MUST WE UPDATE B}OOT?%HTDEXIT;;NO, RETURN%1DELDOS%>;;YES, REMOVE DOS POINTER FROM BOOT% FUPDBT%X;%&X; ADD DOS POINTER TO BOOT SEC}TORS%X;%SETDOS'DOSLOC%PDOSLOC% %SECDAT&UPDBTQDUNIT & RRAMDKU& FTDEXIT & 'SECDAT*& QDEFAULT4&5>&%>H}& QFCBOTC9R&GNOAND;;LONG LENGTH FIELD?\&!%>;;IF NOT, USE ONLY 10 BITSf&NOAND'ANDCDp&Q>BOOTFLz&%>BOOTFL}& BUFSET&%>& 'DAUX2& D12303& 'DAUX1&$>& &DEFAULT&;& DKIO2& STEPBP& )BOOTL& HD1230&7' PDEFAU}LT' %ICDNOZ' 'DUNIT$'QSECSIZ8.' PSECDAT8':B'X;L'STEPBPQDBUFLOV'N>`' PDBUFLOj' GTSTEODt' #DBUFHI~'X;'}TSTEOD%DAUX1':'X;'%X; TEST FOR FILE NAME = 'DOS.SYS''X;'TSTDOS%> ' $DIRDSP'TDLOOPQDIRBUF9'NDOSSY}S 8' HTDEXIT'2'3( HTDLOOP (TDEXIT$CURFCB(?(:((X;2(DOSSYS ADOS SYSA<(X;F(1X; FIND AT LEAST ONE }FILE MATCHING GIVEN NAMEP(X;Z(1LFFILE GETFNM;;EXTRACT FILE NAME FROM BUFFERd('TMP2;;SAVE IT FOR -RENAME-n(+ SFDIR;;FIND} FIRST MATCHING FILE IN DIRx("Q>;;IF NONE, RETURN ERROR 170(EAEXIT;;ELSE, RETURN(:(X;(%X; RETURN ERROR IF FILE IS }LOCKED(X;(TSTLOKQ> ;;CHECK BIT 5( GETFLAG( FTDEXIT( Q>;;FILE LOCKED ERROR = 167( ;;SKIP 2 BYTES(X;(X; }RETURN WITH NO ERROR(X;)DONEQ>;;NORMAL COMPLETION)X;)-X; RETURN ERROR CODE IN ACC TO CIO (IN Y)")X;,)(AEXIT$STK}PSV;;RESTORE STACK POINTER6)B@))$CURFCB;;RESTORE IOCB OFFSET TO X-REGJ)"PICSTA9;;RETURN STATUS IN IOCBT)?;;RETURN STATUS }IN Y-REG^)&QDATBYT;;POSSIBLY RETURN DATA HEREh)")>;;SET CY FLAG APPROPRIATELYr):|)X;)$X; RETURN HARDWARE ERRORS TO CIO})X;)$HWERRQ>;;fix VTOC updating bug) PCURMAP) PCHGMAP)*QDSTATS;;LOAD REAL DISK I/O ERROR CODE)'HAEXIT;;AND RETU}RN IT TO THE CALLER)X;)-X; RELEASE FCB AND RETURN NO-ERROR STATUS)X;)FREDON$CURFCB)7%BUFNO9;;FINISHED WITH THE SE}CTOR BUFFER, RETURN IT)&FDONE;;IF NONE ALLOCATED, SO WHAT!*Q>*4PBUFNO9;;OTHERWISE, IT'S NOT ALLOCATED ANY MORE!*PB}UFFLG8&* FDONE0*X;:*+X; TEST OR CLEAR A BIT IN THE FLAG BYTED*X;N*GETFLAG%DIRDSPX* MDIRBUF8b*:l*X;v*1X; SAVE FL}AG BYTE AND WRITE BACK TO DIRECTORY*X;*SAVFLAG%DIRDSP* PDIRBUF8* !WDIRBK*X;DSPX* MDIRBUF8b*:l*X;v*1X; SAVE FLW "X;save#d:MDUP.M65 MYDOS moduleLISTFLG2LISTFLG2(EI2<#X;save#d6:MDUP.M65 MYDOS moduleFAMYDOS} UTILITIES PROGRAMAPX;ZRDCONF ;;patch into RDdMAPAGE ;;handler in DOSnRDKLMT: x RDAD1 RDAD2 } RDAD3L NMLMAP X;*ORIGIN;;FIRST BYTE AFTER MDOS CODEX;>D:MDUP1.M65"X; resident portion of DUP c}ode>D:MDUP2.M65>D:MDUP3.M65X; DUPEND DUPLENDUPENDDUPBASEMSLENDUPENDMSBASEX;" ME}NUSL>D:MDUP2.M65>D:MDUP3.M65X; DUPEND DUPLENDUPENDDUPBASEMSLENDUPENDMSBASEX;" ME #X;save#d:MDUP1.M65 MYDOS module9X; Copyright 1984, Charles Marslett, Wordmark SystemsX;(IX; Permission is gra}nted by the author for any use whatsoever of this2HX; code, so long as this notice remains in the source code, and so<LX}; long as the source to this routine, however modified or unmodified,F.X; is made available for a nominal cost.PX;Z}X; DEFINED VALUESdX;n CRx EOFX; OPEN GETREC GETCHR PUTCHR CLOSE RENAME }DELETE! LOCK# UNLOCK$ FORMATX;X; ROM AND RAM ADDRESSESX;CARTSTX;" AUDF1,AUDCT}L6 SKRES @ SERIN JSEROUT T IRQEN^ SKCTLh PBCTLrX;|FASCII؆ IFPِEDITRV} DSKIOS CIOVV SIOVYSETVBV\CIOINVnX; WARMST DOSVEC  DOSINI  POKMSK} BRKKEY RAMLOX; DUNITZ!& DCMDZ"0 DBUFZ$: DLENZ(D DAUX1Z*N DAUX2Z+X DAUX3Z,bX;l} LMARGNRv RMARGNSX; FR0Ԕ VECTORԞ HDBUF֨ BUFADڲ BUFLENܼ FNPTR TEMP TEMP2}X; INBUFFX;VSERIN VIMIRQ CDTMV3CDTMF3* SHFLOK* RUNAD4INITAD>ME}MTOPH MEMLOR$DVSTAT;;SYSTEM STATUS BUFFER\X;fDDEVICp DUNITz DCMD DSTAT DBUF}DTIMEO DLEN DAUX HATABSX; IOCB@ ICDNOA ICMDB ISTATC IBUFD I}LENH IAUXJX;X; FMS ENTRY POINTS$X;. FILES 8(RAMDKU ;;LOC OF RAM DISK DRIVE NOBDFUNIT L BSI}ORiV WRCMDy`DKTYPEjDRVDEFtFMINIT~ HDTAB  STATEMDINITWOTDCB% 1CONFIG}R/ ;;CONFIGURE DRIVE SUBROUTINE ENTRYMAPBUF X; X;OTHERS IN THE MDUP.M65 FILEX;X; ! RESEND;;START} OF FREE MEMORYX;^;;patch into dos here !INIT;;DUP INIT ENTRY POINTX;X; PROGRAM AREA(X;2 ORIGIN<X;F} X; INITIALIZE MYDOS INTERFACEPX;ZINITQ>DUPENTdPDOSVECnQ>DUPENTx PDOSVECX;Q> PFNAMEQ> } *STATE/HCKMDOS;;IF WARM START CHECK FOR DUP LOADEDX;X; COLD START CODEX;!PSTATE;;SET MODE TO WARMSTART$}> SOPEN;;RUN AUTORUN.SYS FILE  ' AFN GCLOSX" CLOSX, !@RUNAD:6X;@X; CLOSE IOCBS 10 AND 20JX;T}CLOSX CLOS20^CLOS10$>;;CLOSE IOCB 10h ,;;SKIP 2 BYTESrCLOS20$> ;;CLOSE IOCB 20|!CLOS2Q>CLOSE;;CLOSE ANY IO}CBSCMDPICMD9 !CIOVX;DBUF10$>DEFBUFPIBUF9C PIBUF9 CKMDOS:X;AFN AD1:AUTORUN.SYSA=}CX; Moved AUTORUN FN so SUPERARC will not think this is >=4.3 DOSX;X; OPEN FILEX;X; CALLING SEQUENCE:X; JSR} SOPEN&X; DB AUX0X; DB CMD:X; DW BUFFER ADDRESSDX;N SOPEN;X ;;LDA #IMM OPCODEbX;l&X; DO A READ/W}RITE TYPE I/O REQUESTvX;X; CALLING SEQUENCE:X; JSR DOIOX; DB IOCBNOX; DW BUFFER LENGTHX; DB C}MDX; DW BUFFER ADDRESSX; DOIO,7 PRAMLO7 PRAMLO%> Q@RAMLO7  DDOIO1 PIAUX9  EXTRCB*} DOIO1>43> Q@RAMLO7H PILEN9R3\ Q@RAMLO7f PILEN9p XTRCB3z Q@RAMLO7 PICMD93 Q@RAMLO7 PIBUF93} Q@RAMLO7 PIBUF9C, ORAMLO?Q> ORAMLO 5 C 5$ !CIOV;;DO I/O REQUEST. X;8 (X; IF NO DUP.}SYS, INCREMENT DRIVE NO.B X;L RETRYOS#DUPSYSV QDUPSYS` M>j R> t DRTYOSV~ HGOTO1 RRAMDKU FRTYOSV }GOTO1Q> 1 PDUPSYS RTYOSV> QDKTYPE 19 FRETRYOS HNOWMS X; X; LOAD PROGRAM FUNCTION X; LDFILE LDME}M $> % TOVECT;;LOAD PROGRAM OR GO TO IT  ,;;skip the LDY #1 X;( *X;*************************************2 X;< (X;} STANDARD EXIT POINT FOR PROGRAMSF X;P *X;*************************************Z X;d !X; RESTORE DOS/DUP INIT VECTORn X;}x DUPENT%> SAVERR'CBSAV *STATE KGODOS INOWMS CLOS10 SOPEN  ;;WRITE MEM.SAV FILE OPEN NMS}AV GNOWMS DOIO   MSLEN PUTCHR MSBASE NOWMS CLOS10" # SOPEN;;GET DUP.SYS INTO MEMORY,  6  '@ } DUPSYSJ GRETRYOST QDOSINI^ PINISAVh QDOSINIr PINISAV| GODOS CLOSX !DOSOS;;THEN START IT UP X; X;} X; RUN AT ADDRESS X; )TOVECT!@VECTOR:;;TO 'RUN AT' ADDRESS X; X; LOAD MEM.SAV IF NEED BE X; LDMEM*STATE;;LO}AD MEM.SAV? INOLDMS X; $>  SOPEN   OPEN& NMSAV0 GNOLDMS: X;D DOION   X MSLENb GETCHRl }MSBASEv X; NOLDMS!CLOS20 X; NMSAV 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 +DRIVERS;;ALLOW 2K FOR RESIDENT CODE MSBASE  X; FOR 40 CHAR DEF DIRiQ #X;SAVE#D:MDUP2.M65 MYDOS module9X; Copyright 1984, Charles Marslett, Wordmark SystemsX;(IX; Permission is gra"}nted by the author for any use whatsoever of this2HX; code, so long as this notice remains in the source code, and so<LX" }; long as the source to this routine, however modified or unmodified,F.X; is made available for a nominal cost.PX;Z" }KX;======================================================================dX;n-X; START OF NONRESIDENT PORTION OF DUP.SYSx" }X;.DATAP;;ALLOCATE BUFFER FOR BIT MAP, ETC. DELIM!PAR2P;;another bug fixed RP PAR3PX; DATA" } UNNO PTR PTRSAV IPTR IPSAV CBYTE SECTOR CSRC CDES CPYTYP" SWPFLG" }, RCNT6 SECSIZ@ FNPTJ FNPT2T!PARP;;REAL PARAMETER (LAST)^ DUPBASE hDOSSYS AD1:DOS.SYSA=r"}X;|2X; CLOSE (BRUTALLY) ALL IOCBS AND REOPEN SCREENX;INITIO CIOINV$>" SOPEN;;OPEN SCREEN AS IOCB #0  "} OPEN EC&CDTMV3;;CLEAR TIMER #3&CDTMV3%>Q>$PCDTMF3;;SET TIMER NOT DONE FLAG SETVBVWAITI"}MQCDTMF3;;DONE?!HWAITIM;;NO, CONTINUE LOOPING:&X;0 X; DISK UTILITY PROGRAM ENTRY:X;D DOSOS,N-X$>b&BRKK"}EY;;ENABLE BREAK KEYlX;vQ>MDINITPDOSINIQ>MDINIT PDOSINIX;Q>PLMARGN;;SET MARGINSQ>'"} PRMARGN QDUPFLAG LSTATEM>R> HNOSWF PWARMST  NOSWFQ>@ LSTATE !PSTATE;;ELSE, SAY IT WAS DONE*"}Q>4 LPOKMSK>#PPOKMSK;;ALLOW BREAK INTERRUPTSH PIRQENR INITIO;;CLOSE ALL FILES\X;f QSTATEpM>z FSHMEN+ "}ERRXIT;;MEM.SAV ERROR CAN NOW BE SHOWN- AError loading MEM.SAV or memory!A==X;SHMENQDFUNITL> 0 PDEFAULT"}$>%>DKSLPQ> ;;spacePD1STAT9 PD1STAT9PD1STAT9PD1STAT9 )RAMDKUHCKHCD;;IF NOT RAM "}DISKQ> R$ HSETUNI.X;8CKHCDQHDTAB8BFGENDCD;;IF NOT HARD DISKLQ> HVSETUNIPD1STAT9` HDKUNINjX;t"}GENDCDQDKTYPE8~ FNXTDKSV?;;DOUBLE DENSITY?Q> SEDKSNGD;;NO, SINGLEQ> D;;YES, DOUBLEDKSNGDPD1STAT"}9QDRVDEF8V?Q> - DDKSSDQ> =DKSSDPD1STAT9 DKUNINCL> 0  PD1STAT9 NXTDKS00(020<1F"} HDKSLPP PRINTZ };;CLEAR SCREENd, AMYDOS 4.50 -- Copyright 1988,An =ADisks Ax0D1STAT A1S 2S 3S 4S"} 5S 6S 7S 8S A= AD: = DADEFAULT 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=. A"}C. Copy File(s) M. Run at AddressA=, AD. Delete File(s) N. Load MEM.SAVA=. AE. Rename File(s) O. Change Confi"}g.A=+ AF. Lock File(s) P. Set DensityA=. AG. Unlock File(s) Q. Make DirectoryA=". AH. Write DOS Files R. Pi"}ck DirectoryA=,- AI. Initialize Disk S. Set RAMdisk #A=6/ AJ. Duplicate Disk V. Set Verify FlagA=@ A A==J "}%CBSAVT IMENUSL^% CIOER1;;IF LOAD ERROR, REPORT IThX;rX; SELECT MENU FUNCTION|X;MENUSL$>B2&OPT;;OP" }T=00 IF NO OPTIONS &SWPFLG)&CBSAV;;FOR DIR SCANS, 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.S""}YS IN MEMORY CHRGET&R>0 HCKITEM: !SHMENDX;NCKFDIRR> 1X DCKFDDb !FASTDIRl CKFDDR> *v HBADITM !FAST"#}DDX;CKITEMR> 9 DCKFDIRR> ANFUNC EBADITM S> A EITEMVBADITMQ>NFUNC ITEMVT?? QDUPJT8"$} PRAMLOQDUPJT8  PRAMLO+!PRTMEN;;GO TO MENU EXIT (WITH MESSAGE) X;* TCOMND 4 UCOMND >NSI ANo such"%} item!A==H !MENUSLRX;\DUPJT DIRLST=STCARf CPYFIL=DELFILp RENFIL=LKFILz ULKFIL=W"&}BOOT FMTDSK=DUPDSK SAVFIL=LDFIL BRUN=MEMSAV CONFGR=CHDISK MKDIR=SETDIR"'} RAMDRV=TCOMND UCOMND=VERIFYNFUNC DUPJT  NSIX;%X; * AND 1-8. FAST DIRECTORY "(}LISTX;FASTDDPPAR Q> : PPAR HDOFDD$ X;. FASTDIRPPAR8 Q> :B PPARL DOFDDQ> *V PPAR` P")}PARj Q> Dt 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> PCPYTYP GETFN DEFPAR DODIRLQ>PAR %>PAR"+} DBUF10 $>( &CSRC;;IOCB10 IS SOURCE2 $ OPDIR;;OPEN IOCB10 AS DIRECTORY< X;F Q>DATA& P PBUFADZ",} Q>DATA& d PBUFADn X;x Q>& PBUFLEN Q> PBUFLEN X; $>;;CDES=IOCB00 QDELIM GCPY1FSP "-}QDELIM GSGFCPY GETFN2 'IBUF PIBUF SGFCPY$>  Q>GETCHR HDOCALL X;" CPY1FSPQ>GETREC, DOC".}ALL&CDES6 COPYF@ %!MENUSL;;THEN RETURN TO CMD. LINEJ X;T BADRN ERRXIT^ ANeed new file name!A==h CANTDV ERR"/}XITr 9 ANo drive or directories allowed in new name!A==| X; LKMSG ALock A= ULMSG AUnlock A= DELMSG ADel"0}ete A= X; X; F. LOCK FILES X; #LKFIL ALock which file?A== %>LKMSG $>LKMSG Q>LOCK 'HDOCMD2;;"1}GET FILE NAME THEN LOCK IT X; X; G. UNLOCK FILES X; &ULKFIL AUnlock which file?A== %>ULMSG& $>ULMSG"2}0 Q>UNLOCK: X;D 'DOCMD2'SECSIZ;;do mass lock/unlockN &&SECSIZ;;unless /Q is specifiedX 5b GETFNl CKDSKv $OP"3}T (> Q;;Query? FDOPRM HAFTCHK;;branch either way X; X; D. DELETE FILE(S) X; %DELFIL ADelete what file?A=="4} %>DELMSG $>DELMSG Q>DELETE X; DOCMD'SECSIZ &SECSIZ 5 GETFN CKDSK $OPT* ((> N;;IF "5}'/N' THEN DO IT THE EASY WAY4 FAFTCHK> DOPRM PRINTH  AAnswer 'Y' or 'N'A==R 7\ SETSCNf X;p RDFN SCNDIRz E"6}DELX;;IF END OF DIRECTORY QSECSIZ $SECSIZ PRTMSG Q>PAR $>PAR PRTMSG PRINT A?A= C"7}HRGET R> Y HNODELT $> CIOCL;;DELETE THE FILE THENNODELT!RDFNX; SMPLCMD5$ GETFN;;GET FILE NAME. "8}CKDSK;;VERIFY A DISK FILE8 AFTCHK7BISSCMDPICMDL$>V CIOCL` QICMDjR>)t FSETFNJ~DELX!MENUSLSET"9}FNJ!SETFNMJCANTDV!CANTDVJBADRN!BADRNX;X; E. RENAME FILE(S)X;-RENFIL AFile to rename, new name?A==":} GETFN CKDSK%PTR QDELIMR> , FCKNAM2 R> ;;space HJBADRN CKNAM23( Q@FNPTR72R> :< FJCANTDVF";}R> >;;check for sparta typeP FJCANTDVZR> 0d DDORENn R> zx DCKNAM2DORENQ>RENAME HISSCMDX;X; Q. MA"<}KE A DIRECTORYX;'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">} DCPYDNE@Q>)J !ISSCMDTX;^SETFNM$>hQPTRrN>| FZAPNAM%>Q> : R@FNPTR7 HALLNEW;;IF NOT SUBDIRE"?}CTORY FNDEND2%FNAME9HFNDEND;;END OF OLD DIR?PFNAME9X; ALLNEW3 FCPYDNE R@FNPTR7 HALLNEW"@}0;;POINT BACK AT ':')FCPY1ST;;IF START, NO ':' TO PRESERVEX;& CPYNAM20 CPY1ST3: Q@FNPTR7DZAPNAMPFNAME9N HCP"A}YNAMX !MENUSLbX;lCPYDNE ERRXITv AInvalid directory!A==X;X; SINGLE FILE (DEVICE) COPYX;TOERR1!CIO"B}ER1SGCOPY$>&CSRC;;SOURCE IS IOCB10 SOPEN ;;INPUT OPEN;;OPEN FUNCTION PAR;;INPUT DEVICE NAM GTOE"C}RR1 !SGFCPYX;X; C. COPY FILES X; DUPFIL -CPYFIL AFile source, destination?A==*Q> ;;space4*PPAR3"D};;DEFINE CHAR 3 OF DEVICE NAME>Q>H PCPYTYPR GETFN;;GET SOURCE FILE NAME\X;fQ>DUPENDp PBUFADzQ>DUP"E}END PBUFADX; QMEMTOP;S>DUPEND PBUFLENQMEMTOPS>DUPENDPBUFLENX; DEFPAR "F}QDELIM GSFNAME GETFN2Q>SFNAMEPSWPFLG$ TWARMST. QFNPTR8PIBUF B QFNPTRL PIBUF VQPAR;;"G}DISK DEVICE?`R> Dj HSGCOPYt Q>PAR~ %>PAR DBUF10X;Q> ?%> QQQPPAR281HQQQX; C"H}WFSD$>$ OPDIR;;OPEN IOCB10 AS DIRECTORYX;%>  CPSCL13 Q@FNPTR7 PPAR38( HCPSCL12 CPSCL21< Q@FNPTR"I}7FR> :P FCPSCL3Z R> >;;account for sparta typed HCPSCL2n CPSCL33x 'FNPT2 Q@FNPTR7 FOPINPX;)$>;;SCAN -"J}PAR- STARTING AT 1-ST BYTEMVMSKQ@FNPTR7GWCOPYB;;1 FILESPEC COPY??R> * FMVNMLR> . DWCOPYB HDOSTORQ>"K} ;;space1DOSTORPPAR293 MVNML2"(>, DMVMSK6 SKPPRD3@MVEXTQ@FNPTR7J FWCOPYBTR> .^&FSKPPRD;;IF A"L} PERIOD, SKIP OVER IThR> *r FOPINP|R> ;;space FWCOPYBR> , FWCOPYBR> FWCOPYB3SAVBLKPPAR292"M}(>  DMVEXT EOPINPX;WCOPY CWFSDOPINP SCNDIR *CBYTE GOPINP& DWCNEXT0 !MENUSL:X;DWCOPYBQ> "N};;spaceN HSAVBLKXWCNEXTQ>PAR3bPIBUF0l Q>PAR3v PIBUF0X;$> %FNPT2WCNBLDQPAR29 FTE"O}RMXR> ? HSTWCC QDATA9STWCCPPAR38R> ;;space FOVWRTC3 OVWRTC2(>  DWCNBLDQ> .  PPAR38*"P}34WCEBLDQPAR29> FTERMXHR> ?R HSTWCEC\ QDATA9fSTWCECPPAR38pR> ;;spacez FOVWRTE3 OVWRTE2(> "Q} DWCEBLD TERMXQ> . RPAR38 HNOTOVP1NOTOVPQ>$OPT(> Q HNOQUERYQ> ?NOQUERYPPAR38Q>"R} PPAR38$X;. QCPYTYP8 HDOONEB Q>PARL $>PARV PRTMSG` PRINTj A-->A=t Q>PAR3~$>PAR3"S} PRTMSGQOPTR> Q HDOONE CHRGETR> Y HSKPCOPDOONEQIAUXPIAUX $>  &CSRCQ>"T} PIAUX9  Q>PAR %>PAR DEFBUF( Q>OPEN2 SCMD< GCPYERRFX;P$>ZCKFDOSQCKDTST9d RPAR39n "U}HNOXDOSx0 HCKFDOS QPAR3PDOSRNMPDOSSYSQ>` PPAR3NOXDOSQ>PAR3PIBUF0 Q>P"V}AR3 PIBUF0X;$> &IAUX0$>0 &CDES Q>GETCHR" COPYF;;COPY FILE,X;6SKPCOPQCPYTYP@ HTOEXIT"W}J !WCOPYTTOEXIT!MENUSL^CPYERR!CIOER1hX;rX; I. FORMAT A DISK|X;FMT1050Q> HDOFMTX; FMTDSK ADis"X}k to FORMAT:A=$ GETDN;;GET DRIVE NUMBER OR NAME DEFPARX; Q>PARPIBUF Q>PAR PIBUFX;"Y}%> Q@FNPTR7 PFMTDVNX;&"X; MAKE SURE ABOUT DRIVE NUMBER0X;: PRINTD& A(Press for Enhanced Dns)A=N "Z} AType to Format Drive AXFMTDVN A0:A=bX;l CHRGETvR> 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!*ALFMTD!MENUSL4X;>X; H. WRITE DOS/DUP TO DISKHX;RDUPFNM A"]}D1:DUP.SYSA=\,WBOOT ADrive to write DOS files to?A=f GETDNpQDUPSYSz5Q> 1PDUPSYS PNMSAV%"^}> Q@FNPTR7R> : HCANWB QDEFAULTCANWBPDOSSYSPDUPFNMX;%1;;SET UP INITIAL VALUES OF PARMS.'"_}OPTQ> PSTATEX;$Q>DOSSYS.%>DOSSYS8 DBUF10B"Q>;;OPEN OUTPUT=WRITE DOS.SYSL PIAUXV1 ANYDEN;"`};OPEN AND WRITE DOS.SYS (ANY DENSITY)` CLOS10j7t PNMSAV~PDUPSYSX;"X; **** WRITE DUP.SYS HERE ****X;"a}%>pQ>DUPBASE$>DUPBASE D2B8AQ>DUPFNMPIBUFQ>DUPFNMPIBUF;;Bugs fixed RPQ"b}>DUPEND  PHDBUF Q>DUPEND  PHDBUFQ>DUPLEN( PHDBUF2Q>DUPLEN< PHDBUFFQ>"c}PPTEMP;;CLEAR 'RUN' FLAGZ!WRDUP;;WRITE DUP.SYSdX;nX; J. DUPLICATE A DISKxX;2DUPDSK ASource, Destination (S"d}ectors)?A== GETDN%> Q@FNPTR7M>;;GET DRIVE NUMBER PCSRC PCDES QDELIM;;IF SINGLE DRIVE DUP.R> "e}(FSETSSZ;;GO SET SECTOR SIZE( GETDN2;;ELSE, GET SECOND DRIVE NAME%> Q@FNPTR7M> PCDESRCSRC;;SAME DR"f}IVE?"#HSETSSZ;;YES, SINGLE DRIVE DUP.,$>6 &SWPFLG@ SETSSZ>J %CSRCT QSWPFLG^L>@;;SET DUP-DISK FLAGh PSWPFLG"g}r GDODKDP| PRINT( AInsert both disks, type A= CHRGETX;DODKDP CWFSD QCSRC;;POINT TO SOURCE DRIV"h}E0 GETDEN;;IDENTIFY DENSITY OF SOURCE DISKETTE%CDES;;ELSE, TWO DRIVE DUP. $CSRCQDKTYPE9RDKTYPE8 FS"i}AME 'UNNO SETDEN %CDES $CSRC QDKTYPE9& RDKTYPE80 FSAME: ERRXITD # ADrives not compatible!A=="j}N SAMETWARMSTX V?b PSECSIZl W?v )PSECSIZ;;SET SECTOR SIZE (128 OR 256) &DUNIT;;READ SOURCE VTOC X; QDELIM"k} 5 Q> > INIBMPPDATA9 PDATA9 0 HINIBMP 7;;BOOT COPY? R> ( 'FBLDVTOC;;YES, BUILD IMAGINARY VTO"l}C!R> !FRDVTOC;;NO, DOS COPY!OOPS ERRXIT;;ELSE, ERROR ! AInvalid options!A==*!BLDVTOC GETNUM4!)> ->! HOOP"m}SH! PDATAR! &DATA\! GETNUMf!)> )p! HOOPSz! PDATA! &DATA!%>!'PTR! 'DATA! 'DATA!Q>DAT"n}A ! PBUFAD!Q>DATA ! PBUFAD!Q>!D26BB$DATA! (DATA! HD26CB" $DATA" (DATA" E"o}D26D2$" D26CB;."U?8" NXTSCTB" HD26BBL"X;V"D26D2$DATA`" (DATAj" DD26EAt" HD26E4~" $DATA" (DATA" D"p}D26EA" D26E4T?" NXTSCT" HD26D2"X;" D26EA;"U?" ED26EA" P@BUFAD7"X;" RDVTOC;# QMEMTOP # SSECSIZ# PBU"q}FLEN#QMEMTOP(#SSECSIZ2#PBUFLEN<#X;F# QBUFLENP#R>DUPENDZ#QBUFLENd#S>DUPENDn# EENUFx# ERRX"r}IT# ANot enough memory!A==#X;#NXTSCTED272E# P@BUFAD7#Q># #BUFAD# HD272E# #BUFAD#D272E#DATA"s}# HD2736# #DATA# D2736:#X;$ ENUFQPTR$&FSKRDVT;;IF POS, SKIP READING VTOC$ Q>h"$ $>h,$ PDAUX6$ &"t}DAUX@$ Q>DATAJ$$>DATAT$ PDBUF^$ &DBUFh$ RSEC1r$ INOERFD|$ !CIOER1$ NOERFD,$ QDATA$-O> ;;ADD IN"u} THE BOOT, MAP AND DIR SECTORS$ PDATA$5DCK2BIT;;THEN TAKE CARE OF SECOND BIT MAP IF NEC.$##DATA;;ELSE, BUMP UPPER"v} BYTE$CK2BITQDATA$R>$2DSKRDVT;;IF SINGLE SECTOR, SKIP READING SECOND$ #DATA$,$ QDBUF$ ODLEN% PDBUF% Q"w}DBUF% ODLEN&% PDBUF0% "DAUX:% RSEC1D%X;N%SKRDVTQ>X% PDAUXb%Q>l% PDAUXv% QDATA % PCBYTE%Q>"x}% PIPTR%Q>DATA %PVECTOR%Q>DATA % PVECTOR%X;%DORDQVECTOR% PPTRSAV%QVECTOR%PP"y}TR% QIPTR& PIPSAV & QCBYTE& PCBSAV & QDAUX*& PSECTOR4& QDAUX>&PSECTORH&Q>R&$PCPYTYP;;SET OPERATION TO '"z}READ'\&LRSQ>DUPENDf& PDBUFp&Q>DUPENDz& PDBUF&LRS1TCBYTE& "IPTR& HCBIT& #VECTOR& HPAGE1&#VECTO"{}R& PAGE1%>& Q@VECTOR7& PCBYTE&$>& &IPTR&CBIT*CBYTE& GASPT' QCPYTYP'T?;;CY=0, READ; CY=1, WRITE' Q"|}CSRC$'DRSECIN;;ACC=DRIVE #.' QCDES8'!RSECIN SECTIO;;READ OR WRITEB'IOD,L' QDBUFV' OSECSIZ`' PDBUFj' QDBUFt'O"}}SECSIZ~' 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, END OF THE BUF"}FER?( RDBUF(QBUFLEN(( SDBUF2(ELRS1;;NO, GET NEXT SECTOR<(X;F( QCPYTYPP("ISTDD2;;IF WRITE, DO NEXT READZ( C"}WFSDd( !DORDn(X;x(STDD2*SWPFLG( ICKFORM( PRINT(3IDD AInsert DESTINATION disk, press A=( CHRGET(CKF"}ORMQ> N(ROPT( FNOFORM(POPT($> ;;IF FORMAT REQ., DO IT(Q>DOSSYS(%>DOSSYS( DEFBUF( Q>FORMAT) PIC"}MD ) QCDES)#L> 0;;CONVERT DRIVE NO. TO ASCII")PDOSSYS,) CIOCL6)&NOFORM"CPYTYP;;THEN, MAKE A WRITE@) QPTRSAVJ) "}PVECTORT)QPTR^)PVECTORh) QSECTORr) 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>;;DRIVE NUM"}BER ONLY?*"HCHDSK2;;IF SO, CHANGE DEFAULT*BADPCMD ERRXIT* ADrive unchanged.A==&*CHDSK2%PTR0* Q@FNPTR7:*>D*"}%>N* Q@FNPTR7X*R> 9b* EBADPCMDl* S> 1v* DBADPCMD*?*3* 'UNNO*Q>*(> S* FTOSGL*(> D* HBADPCMD*T?*"}TOSGLPDKTYPE8* DOFSIN*"!SHMEN;;THEN SHOW CHANGED MENU*X;+(X; O. CONFIGURE SYSTEM OR DISK DRIVE +X;+ CHKBANKS"}= +%>;;This is BOB code...*+';;uncommented as4+';;per usual...H+QR+5\+$>f+ ?L1'p+Q@z+ PMAPBUF8+&"}@+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;;was a DEY, ?L9', QMAPBUF8,P@,1,)>-H?L9 -7-P-Q>(-P2-Q<-PF-.P-:Z-X;d-?FOCn-P"}MAPAGE9x-2-(>A-D?L8-%>-H?L9-X;-X;-GETRDK PRINT- ARAM disk present?A=- CHRGET-%>-R> N-"} HRAMDSU- !NOFAST.RAMDSU PRINT.' Axlon or E type RAMdisk?A=. CHRGET". %>,. $>6.R> A@. HSAV"}ADRJ. %>T. $>^.SAVADR'RDAD1h. 'RDAD2r. 'RDAD3|. &RDAD1. &RDAD2. &RDAD3.R> A. FOKP0. CH"}KBANKS. QRDKLMT. HOKP1. PRINT.' ANo extra memory available!A==.%>. !NOFAST.OKP0!RAMDSU2.X;/ OKP1$>"}/ &NMLMAP/ &FR0&/T?0/T?:/ UFR0D/T?N/ UFR0X/T?b/PFR0l/ UFR0v/ IFP/ FASCII/ PRINT/! AUse d"}efault config for A=/%>/OKP2Q@INBUFF7/ GOKP3/3/ HOKP2/ OKP3M>/ P@INBUFF7/3/Q>/ P@INBUFF70 QIN"}BUFF 0$INBUFF0 PRTMSG 0 PRINT*0 AK?A=40 CHRGET>0R> NH0 FRAMDSU2R0 !DVNOQ\0X;f0RAMDSU2 PRINTp0 ASize("}K)?A=z0 GETLIN0 GETNUM0VVECTOR0W?0VVECTOR0W?0VVECTOR0W?0VVECTOR0W?0 HSAVRDS0Q>0"}SAVRDSPRDKLMT0X;1X;1GETSEQN PRINT1 APage sequence?A=$1 GETLIN.1 GETNO281)>CRB1 HFSNUML1 FRSEQV1DVNO"}Q PRINT`1 ARAM disk drive no?A=j1GETRDRV CHRGETt1%> ;;ASSUME 9~1R> 01*DNOFAST;;IF DIGIT, CHANGE RAMDISK CODE1R"}> 91 ENOFAST1M>1?1(NOFAST'RAMDKU;;SET RAMDISK UNIT NO.1:1X;1 RSEQ?1 $PGMAP81 &NMLMAP1)>2 ECPAXSQ 2"} QSQMAP82$>2 CPY0U?(2U?225<2U?F2U?P2U?Z2M> d2?n2CPY1QSQTAB8x2 PMAPAGE922232A2M>2 HCPY1272("}>2 HCPY02CPSEQQSQTAB92 PMAPAGE9222(>@2 HCPSEQ3 FDVNOQ3X;3CPAXSQ$>@"3 AXSQL0,3A63 PMAPAGE9@3 HAXS"}QLJ3 FDVNOQT3X;^3 FSNUM$>h35r3A|3FSNCLPDATA9323 HFSNCL373FSLP1&UNNO3)>CR3 FTONML3PDATA@"}93>3QDATA93 HBADSEQ3"DATA93%PTR3 Q@FNPTR74R>CR4 HFSLP44 GETLIN&4FSLP4 GETNO204 $UNNO:42D4"}(>@N4 HFSLP1X4TONML(RDKLMTb4 HWRONGl4 PNMLMAPv4 UPDLP104QDATA@94 PMAPAGE94A4 HUPDLP14 !DVNOQ4BAD"}SEQ PRINT4( ADuplicated sequence number!A==4 !GETSEQN4X;4WRONG PRINT4% AWrong number of entries!A==4 !"}GETSEQN4X;5PGMAP ===== 5SQMAP ==K===5X; 5SQTAB ===*5 ===45 ===>5"} ===H5X;R5 ===\5 ===f5 ===p5 ===z5X;5 ===5 ===Θ5 ==="}5 ===5X;5 ===5 ===5 ===5 ===5X;5CONSYS PRINT5 AVerify WRITEs?A"}=5 DOVRFY6 PRINT6! ANumber of File Buffers?A=6 GETLIN$6 GETNUM.6>86 FSKPFCTB6R>L6 ESKPFCTV6&PFILES;;S"}ET NUMBER OF FILES (0-16)`6SKPFCT GETRDKj6 MDINIT;;REINITIALIZE DOS3t6 !DOSOS~6X;6ZAPDRVQ>Ғ6 ,;;SKIP 2 BYTES6 "}SET52Q>R6 %UNNO6PDRVDEF86 CLRHDS6CONXIT!MENUSL6X;6(CONFGR ADrive number or :A=6 CHRGET;;GET "}DRIVE NUMBER6.R>;;IF RETURN, GO TO SYSTEM CONFIGURATION6 HCONDRIV7 !CONSYS 7CONDRIVR> 97 DSAVDVN7TOBADP!BADPCM"}D(7SAVDVNS> 127 DTOBADP<7?F73P7 'UNNOZ7%Q>;;THEN ZERO CONFIGURATION BYTEd7PDRVDEF8n7X;x7 PRINT7 ARemove"} drive?A=7 CHRGET7R> Y7 FZAPDRV7 PRINT7 AIs drive configurable?A=7 CHRGET7#R> Y;;IF NO, SET TO $52 AND E"}XIT7 HSET527 PRINT7 AHigh capacity drive?A=7 CHRGET7R> Y8 FGETHCD8 PRINT8 AIs drive double sided?A=""}8 CHRGET,8R> Y68 HSETSS@8Q>J8 ORDRVT8SETSS PRINT^8 ATracks/side?A=h8 GETLINr8 GETNUM|8R>#8 FSET358?"}8Q>08)>M8 FSETTKS8Q> 8)>P8 FSETTKS8Q>8)>(8 HSETSS8SETTKS ORDRV8SET35 PRINT9 AStep rate?A="}9 CHRGET9R> 4&9 ESET3509 S> 0:9 DSET35D9T?N9 ORDRVX9 CLRHDSb9 !MENUSLl9X;v9GETHCD PRINT9" ADrive size"} (in sectors)?A=9 GETLIN9 GETNUM9(>9FGETHCD;;INVALID SIZE959 %UNNO9Q>9PDRVDEF89Q>9PDKTYPE"}8979 SETHDS: !MENUSL :X;:#X; S. Set RAMdisk Drive Number :X;*:#RAMDRV ARAM disk drive no?A=4: GETRDRV>: "}!MENUSLH:X;R:$X; V. Set Verify Flag ON or OFF\:X;f:VERIFY AVerify WRITEs?A=p: DOVRFYz: !MENUSL:X;:DOVRFY C"}HRGET:$>W;;ASSUME YES!:R> N: HDOVFY:$>P:/DOVFY&WRCMD;;SAVE THE WRITE COMMAND IN DOS:::X;:ORDRV%UNNO:L"}DRVDEF8:PDRVDEF8::;X;;CLRHDS$>;A$;SETHDS%UNNO.;PHDTAB88;AB;PHDTAB8L; !DOFSIN%UNNO:L r