@L}6CD l0C)HCC WhL/h `CmCDiD`  R@P1  Y0@R !L` D  C D     )16CS S)  C)D1 p p 0 C9DI pCDL~CiCDiD`X;SAVE #D2:DUP.M65AADISK UTILITY PROGRAMS (DUP) VER 3.0 for DOS 2.5 01/10/85AX;X;'X;CHANGED FOR SYSTEM R}ESET -- DUPFLG,X;ADDED INTERRUPT ROUTINES FROM SIO -- KB$.X;ADDED SAVE/RESTORE OF DOSINI VECTOR -- KB./X;Modified this me}ss for DOS 2.5 -- 1/85 MER8X;BTX;*******************************************************************************L7X; } THIS IS FINAL VERSION OF DUP ---- 2.5 ----VSX;***************************************************************************I}*X;SAVE #D2:DUPEQU.M65AEQUATESAX; **** EQUATES ****X;X;X;$ CIOV. DKHNDS3,SECSIZ;; As }sume 128 byte sectors only8SETVBV\BSYSVBV_LXITVBVbVCIOINVn`7POKMSK;; Pokey interrupt mask (shado }w for IRQEN)j-IRQEN;; IRQ interrupt enable on pokeytMEMTOP~ BRKKEY DOSVEC DOSINI ;;DOS INIT VECT }OR WARMST LMARGNR RMARGNSCARTST3INTRVEC ;;INTERRUPT VECTOR LOC FOR SIO PATCH MEMLOSH }FLOKINITAD RUNAD ICHIDZ  ICDNOZ!  ICBALZ$ ICBAHZ% ICIDNO.( MAXDEV!2HATABS }<USRDOSF FMSPFMINITFMSZ7DRVBYT ;; Drive byte - tells which drives exist.dDOSFMS@n!WRMST}Rt;;WARM START VECTORx?BSIORr;;ENTRY POINT TO FMS DISK HANDLER USED BY DUP DISKX; CR SPACE  CUP} CDN CLF CRT DLL CLSCR}(EOF;;ENDFILE RETURN CODE FROM CIOX;X; OPEN CLOSE } PUTCHR  GETCHR" GETREC, PUTREC 6 RENAME @ DELETE!J FORMATO9FORCEFMT;; Forces sgl or dbl }format (aux1 is flag)T LOCK#^ UNLOCK$h0STAREQS;;STATUS COMMAND TO DISK CONTROLLERrX;| IOCB1X;3DVSTAT};;ADDRESS OF STATUS INFO STORED BY OSX;X; DCBDUNITDCBDCOMNDDCBDSTATSDCBDBUFLO}DCBDBUFHIDCBDSLODCB DSHIDCB X; IOCB@ICHIDIOCBICDNOIOCB&ICCOMIOC}B0ICSTAIOCB:ICBALIOCBDICBAHIOCBNICBLLIOCBXICBLHIOCB bICAX1IOCB lICAX2IO}CB vX; SYSED OWRIT ORDWRT X;X;(X; **** ZERO PAGE VARIABLES ****X;X; JMPTBL} X;SAVE #D2:DUPINIT.M65ADUP INITIALIZATIONA$X; **** INIT CODE FOR DUP ****X;X;>X; INITIALIZATIO}N CODE FOR DUP - CALLS FMS INIT CODE.$0X; CALLED ON WARM START AND COLD START..X;8$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;};BX;L$;; Message for wrong DUP diskV1:WRONGDUP }=ANeed DOS2.5,type Y A=CR`-@ORG ;; Make sure there's }enough roomjX;t$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;~X;,;; ??? SPACE FOR ADDITIONAL INIT CODE%NEWINITTDRVBYT;; Di}sable RAMDISK VDRVBYTQ> 1 PDFDRVX;X; Try to load "RAMDISK.COM"X; Q>4:RAMFN $>5:RAMFN TRYLOAD;; an}d try to loadX;#Q>4AF;; Try to load AUTORUN.SYS  $>5AF !TRYLOADX;(:RAMFN AD:RAMDISK.COMA=CR2X;<$X;;;;;;};;;;;;;;;;;;;;;;;;;;;;;;;;FX;P0X; Code for PRINTMSG which checks for dup 2.5ZX;dCHK2.5Q>LnRDOSOS;; Check for DUP2}.5x H:NOT2.5 !CIO1X;':NOT2.5Q>;; Set DUP not in memory PDUPFLGQ>4:WRONGDUP$>5:WRONGDUP3 WAITY;; Pr}int message and wait to load 2.0 DUP !:NOT2.5X;$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;*X; Rev A SIO patch (a la Pau}l Laughton)X; ISRBUGQ; H:BUG1!" :BUG1C,56!@X;J$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;TX;^@ORG D }X;SAVE #D2:DUPLOAD.M65ALOADER ROUTINEA!X; **** LOADER ROUTINE ****X;X;5X; LOADS FROM THE FILE !}(MUST BE LOAD FORMAT)$!X; INTO MEMORY. RETURNS:.X; X=0 LOAD OK8(X; X=1 OPEN ERRORS Y=CIO CODEB(X; "} X=2 READ ERRORS Y=CIO CODELX; X=3 BAD LOAD FILEV0X; ON ENTRY, IOCB 1 POINTS TO FILENAME.`X;j@A #}LIGN t.DUPFLG ;;FLAG -IF DUP IN MEMORY NOT ZERO~/OPT ;;HOLDS VALUE OF OPTION GIVEN BY USER>LOADFG ;;FLAG = $8 $}0 IF MEMORY FILE DOESN'T HAVE TO BE LO HDBUFSFLOADQ>STLOADPLOADFGLOADQ>4RTS PRUNAD Q>5RTS-PRUN %}AD;;MAKE RUN AT EOF DEFAULT TO RTS$> Q>OPEN PICCOM9Q>;;OPEN TYPE=INPUT PICAX19  CIOOPN;;TRY TO OPEN &}FILEIRDLF;;CONT IF OKQ>;;OPEN ERRORS(HCLFX;;CLOSE AND EXIT2 RDLF$>< Q>4DBUFF PICBAL9P Q>5DBUFZ PICBAH '}9dQ>n PICBLL9xQ> PICBLH9&PMEMLDD;;CLEAR MEM.SAV LOADED FLAG Q>GETCHR PICCOM9 CIOGERST;;IF ERRS (}Q>$RDBUF;;CHECK FOR VALID LOAD FILE HLNLF RDBUF$HLNLF;;BRANCH IF NOT A LOAD FILE RDDRC$> Q>4HDBUF )} PICBAL9 Q>5HDBUF PICBAH9"Q>,RDDRC1PICBLL96Q>@ PICBLH9J) CIO;;NO ERROR CHECK SO CAN CATCH EOFTISTO *}K;;IF NO ERROR^)>;;SEE IF EOFhHERST;;IF SOME ERROR STATUSrX;|X;EOF SO DONE, EXITX; CLOSX;;CLOSE IOCB'S 1 AN +}D 2*OPT"GDRUN;;BRANCH IF NO RUN OPTION$ JMPRUN;;JUMP THROUGH RUN VECTORDRUNQ>;;OK STATUS *LOADFG;;WAS MEMO ,}RY SWAPPED? PLOADFG*GCLFX;;BRANCH IF MEMORY WASN'T SWAPPED) MEMSVQ;;DOES MEMORY SAVE FILE EXIST?GDRUN1;;BRANCH I -}F NOT77&!GOOD;;WRITE MEMORY AND RELOAD DUPX;MX; SEE IF DUP WRITTEN OVER. IF IS RELOAD & TELL USER NEED ME .}M.SAV TO&X; LOAD THIS FILE.0X;:'DRUN1QDUPFLG;;SEE IF DUP CLOBBEREDDHDRUN2;;NO, THEN RETURNN(Q>4NMSF;;ELSE T /}ELL USER NEED MEM.SAVX $>5NMSFb PRNTMSG;;PRINT MSGl!RRDUP;;RELOAD & RUN DUPvX;%X; RETURN TO CALLING ROUTINE 0}X;$DRUN2Q>;;NO DUP ERR MSG ON EOF CLFX>RTS:X;X; ERROR RETURNSX;LNLF CLOSXQ>;;BAD LOAD 1} FILE HCLFX ERSTC5 CLOSX 7?  HCLFX*X;4>X; CONTINUE WITH LOAD - CHECK LOAD ADDRESS FOR HEADER>2X 2}; HEADER IF HAVE CONCATENATED LOAD FILESHX;R STOK$>\QHDBUF;;MOVE PARAMS TO IOCBf PICBAL9p5z QHDBUF 3}PICBAH9?73;;WAS ADDRESS FF?HADOK;;BRANCH IF NOT?3;;OTHER BYTE FF?HADOK;;BRANCH IF NOTX;OX; 4} HAVE A HEADER & START ADDRESS - GET END ADDRESS FOR TEXT & DO AGAINX; QHDBUF PHDBUF QHDBUF PHDBUF;;M 5}OVE LOAD ADDRESS Q>4HDBUF$ PICBAL9. Q>5HDBUF 8  6}L !RDDRC1V X;` 8X; GET LENGTH OF TEXT. THEN DETERMINE IF IN DUPj X;t /X; *** The NOP's in the next section of code 7}~ *X; are there only to make changed code 0X; occupy the same space as the old DUP 2.0s 0X; code. Since the new version 8} was shorter, 0X; filler was required (The new version also X; works!). X; ADOKQHDBUF ; SHDBUF PICBLL9 9} QHDBUF SHDBUF PICBLH9 QHDBUF *R>5NMDUP ;; IS BEGINNING PAST DUP? 4 EANWD;; BRANCH IF SO( QH :}DBUF2 R>5NDOS;; IS END BELOW DUP?< 4F EAWD;;BRANCH IF NOTP X;Z 8X; SINCE TEXT IN DUP, LOAD MEM.SAV IF NECCESAR ;}Yd X;n ANWDQMEMLDDx *GAWD;;BRANCH IF MEM.SAV ALREADY LOADED Q> LLOADFG 7PLOADFG;;SET MEM.SAV DOESN'T HAVE TO BE <} LOADED FLAG AWD#ICBLL9 H:AWD1 #ICBLH9 0:AWD1*LOADFG;;DOES MEMORY HAVE TO BE LOADED GDLM;;BRANCH IF NOT (QM =}EMLDD;;WAS MEM.SAV ALREADY LOADED? GDLM;;BRANCH IF SO "MEMLDD - LDMEM;;LOAD MEM.SAVE FILE (IF IT EXISTS) )Q>;;SHOW >} USER AREA NOT DUP IN MEMORY PDUPFLG 1 RELDIN;;RESTORE DOS IN VECTOR FROM SAVED LOC X;" EX; SET NO INIT ADDR DEF ?}AULT THEN READ IN TEXT & ATTEMPT INIT, X;6 DLM$>@ Q>4RTSJ PINITADT Q>5RTS^ 'PINITAD;;INIT DEFAULTS TO AN RTSh @}& CIO;;READ DATA DIRECTLY TO MEMORYr IDLM1| !ERST;;IF ERRORS DLM1*OPT "GDINIT;;BRANCH IF NO GO OPTION  JMPINT;; A}DO INIT /DINIT!RDDRC;;GET NEXT SECTION OF LOAD FILE X; 2X; *** A subroutine existed here in DOS 2.0s to 3X; supposedl B}y check for a load file overwriting 0X; DUP.SYS. It didn't work properly, so the 1X; code was rewritten without the subr C}outine. /X; The final result used less code than the X; original! X; BX; But we must fill up the old space... so here }X;SAVE #D2:DUPSUB.M65ARESIDENT SUBROUTINESA2X; **** SUBROUTINES FOR RESIDENT DUP ****X;X;6X; [} X;SAVE #D2:DUPMEMSV.M65ACREATE MEM.SAV FILEA(X; **** CREATE MEM.SAV FILE ****X;X;+X;ROUTINE WRITTEF}N BY M.E., APRIL 21,1980$OWRIT;; PICAX19;; OREST;;OPEN FOR WRITE%GERRWR;;IF ERROR THEN JMP AND RETX;J}X;X;WRITE MEMORY BLOCKX; Q>PUTCHR  PICCOM9)Q>4NDOS;;STORE START OF BLOCK FOR CIO PICBAL9(Q>5NDOS;;START K}ADDR (HIGH)2 PICBAH9<!Q>4MLEN ;;LENGTH OF BLOCKF PICBLL9PQ>5MLEN;;LENGTH(HIGH)Z PICBLH9d CIO;;WRITE DATA BLL}OCKn#GERRWR;;IF WRITE ERROR THEN JMPx CLOSX GERRWR%>RET:X;ORESTQ>4OPEN PICCOM97Q>4NAME;;ROUTINM}E TO COMPLETE OPEN OF 'D1:MEMORY.SAV3PICBAL9;;CALLING SUB SUPPLIES 'READ' OR 'WRITE'Q>5NAME;;IN ICAX1 PICBAH9 !CN}IOOPNX;%ERRWR:;; Return with error statusX;=CIOOPNQDFDRV;; Set default drive for MEM.SAV and DUP.SYS PMEMSVDRO}V PDUPDRV!CIOX;@J0X; **** ENTRY POINT ON 'DOS' CALL ****TX;^X;c @ORG h%INISAV ;;DOSINI VECP}TOR SAVE LOCr MEMFLG | MNDUP$> &MEMFLG &LOADFG0 &WARMST INITIOX;/ MEMSVQ;;FIND OUT IF FILE D1:MQ}EM.SAV EXISTS'IGOOD;;BRANCH IF MEM.SAV FILE EXITSQ>"PWARMST;;CLEAR WARM START FLAG FFINALX;X;,GOOD MWR}RITE;;WRITE USER AREA TO MEM.SAV GERROR "MEMFLG;;SHOW MEMORY WRITTEN& GFINAL0X;:,ERRORQ>4ERRMES;;PRINT ERROR OCCS}URED MSGD $>5ERRMESN PRNTMSG;;GOTO MSG PRINTERXX;b"Q>4ERR;;PRINT QUERY TO RUN DOSl $>5ERRq,WAITY ;; Print messaT}ge and wait for 'Y'v PRNTMSG;;GOTO MSG PRINTERX;!X; WAIT FOR Y TO RUN DOSX; Q>GETREC PICCOM Q>4STAKU} PICBAL Q>5STAK PICBAHQ> PICBLLQ> PICBLH CIO QSTAK;;SEE IF Y TYPEDR> Y HRTCART;;BRANCH V}IF NOT*Q>4 PWARMST>X;H FINAL$> R Q>CLOSE\!PICCOM9;;SET UP CLOSE COMMANDf CIO;;PERFORM CLOSE COMMANDpX;z'W}RRDUPQDOSINI;;SAVE DOS INIT VECTOR PINISAVQDOSINIPINISAVX;#Q>4DOS;;SET UP DUP INIT ADDR ASPDOSINX}I;;DOS INIT VECTOR Q>5DOSPDOSINIX;RRDUP1Q>4DUPSYS$> PICBAL9 Q>5DUPSYS PICBAH9 %> ''OPT;Y};ASSURE NO /N OPTION IN EFFECT$ 1;;SHOW THAT DUP IS IN MEMORY. 'DUPFLG8 $ SFLOAD;;LOAD DUP.SYS AND RUN ITB RTCART:L EZ}C AE:A=CR DUPSYS AD1:DUP.SYSA=CR DUPDRVDUPSYS X; 2ERRMES AERROR-SAVING USER MEMORY ON DISKA=CR &ERR A+} ROUTINE TESTS IF MEM.SAV IS PRESENT ON THE$(X; RETURNS - MINUS IF NOT THERE./X; PLUS IF MEM.SAV IS\} THERE8X;= @ORG sB"MEMSVQ CLOS20;;CLOSE IOCB # 2L Q>OPENV PICCOM9` Q>4NAMEj PICBAL9t Q>5NAME~ PICBAH9]} Q>ORDWRT2PICAX19;;TRY TO OPEN D1:MEM.SAV FOR READ/WRITE CIOOPN6;;SAVE STATUS CLOS20;;CLOSE MEM.SAV8;;RESTO^}RE STATUS:X;X;GX; SAVE FILE SUBROUTINE - WRITE FILE BODY, INIT, & RUN VECTORSX;+WDR1Q>;;THIS IMMEDIA_}TE VALUE MODIFIED2FWDR2;;BR IF MEM FILE DOESNT HAVE TO BE LOADED  LDMEM WDR2$>& CIO;;DO SAVE - WRITE BODY TO DI`}SK(3INITQQ>;;THIS IMMED VALUE CHANGED DURING SAVE22FRUNQ;;SET TO FF WHEN AN INIT VECTOR IS PRESNT< #INITQF QINITa}ADP+PVECTR;;IF INIT VECTOR FOR FILE SAVE ITZQINITADd PVECTRn Q>4INITADx> PLDST Q>5INITAD WRVEC+b}RUNQQ>;;THIS IMMEDIATE VALUE MODIFIED3FNORNAD;;SET TO FF WHEN A RUN VECTOR IS PRESENT #RUNQ QRUNAD*PVECTR;;Ic}F RUN VECTOR FOR FILE SAVE IT QRUNAD PVECTR Q>4RUNAD> PLDST Q>5RUNAD WRVEC#NORNAD CLOSX;;CLOSd}E IOCBS 1 &2" QMEMFLG, MWDR16 FDRRDUP@/#WDR1;;RESET MEM.NEEDS TO BE LOADED FLAGJ!RRDUP1;;RELOAD & RUN DUPT)e}DRRDUP!DOSOS;;RUN THE SWAPPED IN DUP^X;hX;rX;|WRVECPLDST2 &LDND PLDND$> Q>4LDST PICBAL9f} Q>5LDST PICBAH9Q> PICBLL9Q> PICBLH9#!CIO;;WRITE INIT OR RUN ADDRESSX;X;X; JUMP TO CAg}RTRIDGE&X;0CLMJMP LDMEM:%Q>;;SHOW DUP NO LONGER IN MEMORYD PDUPFLGN* RELDIN;;RESTORE DOS INIT VECTOR SAVEDX !@h}CARTST:;;JUMP TO CARTRIDGEbX;lX;v=X; LOAD MEM.SAV (IF IT EXISTS) BEFORE RUN AT ADDRESSX;+LMTR LDMEM;;LOAD Mi}EM.SAVE IF IT EXISTS*Q>;;SHOW THAT DUP NO LONGER IN MEMORY PDUPFLG* RELDIN;;RESTORE DOS INIT VECTOR SAVED!@RAMLj}O:;;RUN AT ADDRESSX;5X; RESTORE DOSINI VECTOR FROM SAVED LOCATIONX;RELDINQINISAV PDOSINIQINISAVk}PDOSINI: X;X; X; SUBROUTINE - LDMEM*%X; LOAD MEM.SAV IF IT EXISTS4X;>LDMEMQMEMFLGH'HLDMEl}M1;;BRANCH IF MEMORY WAS SAVEDR:\LDMEM1 MEMSVQf.ILDMEM2;;BRANCH IF MEM.SAV FILE DOES EXISTp%Q>;;TELL CART PGM AREAm} CLOBBEREDz PWARMST"FCLOS2;;GO CLOSE AND GOTO CARTX;LDMEM2Q>OPEN PICCOM9 CIOOPN;;REOPEN MEM.SAV Q>GETCn}HR PICCOM9Q>4MLEN  PICBLL9 Q>5MLEN PICBLH9 Q>4NDOS PICBAL9 Q>5NDOS PICBAH9  CIO$ CLOS2Q>o}CLOSE. PICCOM98 !CIO;;CLOSE MEM.SAVB X;L ;X; CLOSE ALL IOCBS & RE-OPEN ZERO AS SCREEN EDITORV X;` 2INITIO CIOIp}NV;;THIS ROUTINE CLOSES ALL IOCB'Sj #;THEN REOPENS THE SCREEN EDITORt $>~ Q>OPEN PICCOM9 Q>4EC PICBAL9 Q>5Eq}C PICBAH9 Q>ORDWRT PICAX19 !CIO X; X; CLOSX - CLOSE IOCBS 10,20 X; CLOSXQ>CLOSE $> PICCOM9  r}CIO X;( (X; ENTRY TO CLOSE IOCB # 2 ONLY2 X;< CLOS20$> F Q>CLOSEP PICCOM9Z :GOCIO!CIOd X;n X; SUBRs}OUTINE - PRNTMSGx KX; PUTS A CHARACTER STRING TERMINATED BY A CARRIAGE RETURN CHAR TO X; SCREEN EDITOR. X; 0t}X; ENTRY - REG A : LOW BYTE MSG ADDRESS /X; REG X : HI BYTE MSG ADDRESS X; =X; PUT PARAMS IN IOu}CB - USE IOCB 0 FOR SCREEN EDITOR X; 2PRNTMSGPICBAL;;SET MSG ADDR IN IOCB BUFF ADDR &ICBAH X; X; SET UP RESv}T OF IOCB X; $>;;SET IN BUFFER LENGTH !&ICBLH;;ASSUME 256+ BYTES MAX 0" Q>PUTREC;;PUT MSG, PICCOM1 42 46 X;@w} IX; TEST IF DUP IS RESIDENT - IF IS THEN USE INDIRECT CIO ROUTINEJ 'X; TO TEST FOR BREAK KEY ABORTT X;^ 1QDUPFx}LG;;=ZERO IF NON-RESIDENT DUP NOT IN MEMh 1F:GOCIO;;IN MEMORY THEN USE INDIRECT CIO CALLm @ALIGN r ?OLDPRMSG!CHK2.5;y}; Go to insure that dup.sys is version 2.5| X; X; SAVH = LDST LDND VECTR X; ,X; Allow for 3 VT}}}Need DOS2.5,type Y Λ# N 1? l LlD:RAMDISK.COMLu L1 L ;LHL+  TV/}X;SAVE #D2:DUPDUP.M65ADUPLICATE DISKA+X; **** DUPLICATE DISK ROUTINE ****X;X;)X; FMS equates neede<|}d for VTOC access:$X;.*DVDWRQ;; Write required flag offset8)DVDSMP ;; Offset of start of bitmapVX;`X;j,DDMG =H}OC buffers of 144 bytes. )X; (128 bytes plus 3 VTOCs w/ 16 bytes (X; extra data in comparison to 2.0s) @ORG |}X;SAVE #D2:DUPSIO.M65AREV A SIO PATCHA4X; **** SIO INTERRUPT SERVICE ROUTINES ****X;X;9X; E}QUATES FOR INTERRUPT ROUTINES MOVED FROM SIO$X;.X; ZERO PAGE8X;B1BUFRLO2;;POINTER TO BYTE TO SEND OR RECEIVEL} BUFRHI3V2BFENLO4;;POINTER TO BYTE AFTER END OF BUFFER` BFENHI5j/CHKSUM1;;LOC TO STORE DATA FRAME CHECKSUMt+}CHKSNT;;;CHECKSUM SENT FLAG- =FF SENT~8NOCKSM<;;FLAG NO CHECK SUM TO BE RECEIVED-NOT ZERO/STATUS0;;HOLD FOR STATU}S TO BE PUT IN DCB0BUFRFL8;;FLAG-IF FF RECEIVE BUFFER IS FULL7RECVDN9;;FLAG RECEIVE NOT DONE. USED BY WAIT LOOP4}POKMSK;;POKEY INTERRUPT MASK SHADOW FOR IRQENX;=X; HARDWARE REGISTERS USED IN SIO INTERRUPT ROUTINESX;0SK}RES ;;SERIAL PORT STATUS RESET ON POKEY&SEROUT ;;SERIAL OUTPUT REGISTER1SERINSEROUT;;SERIAL PORT INPUT REG ON P}OKEY,IRQEN;;IRQ INTERRUPT ENABLE ON POKEY/SKSTAT;;SERIAL PORT STATUS REG ON POKEYX; 'X; ERROR CODES R}ETURNED BY SIOX;%FRMERR;;FRAMING ERROR ON INPUT(3OVRRUN;;DATA FRAME OVER RUN-BIT D5 IN SKSTAT2(CHKERR;;DAT}A FRAME CHECKSUM ERROR<FHX; **** INTERRUPT SERVICE ROUTINE TO OUTPUT DATA NEEDED ****PX;ZX;dX;n@X; }IT UPDATES THE BYTE TO PUT ON SERIAL I/O BUS POINTERxGX; UNTIL END OF BUFFER. AFTER EACH UPDATE OF THE PTR ADDS THE}IX; VALUE OF THE BYTE TO THE CHECKSUM. OUTPUTS THE CHECKSUM WHENKX; PTR EQUALS THE END OF BUFFER PTR (POINTS T}O BYTE AFTER BUFFER).JX; RETURNS TO THIS ROUTINE AFTER CHECKSUM PASSED AND RESETS POKEYIX; INTERRUPT REG TO H}AVE THE TRANSMIT DONE ROUTINE CALLED TO END(X; WAIT LOOP (SEE SIO LISTING).X;X; K.B. 6/10/80X; ISRO}DNC;;SAVE Y REG ON STACK5X; #BUFRLO'HNOWRP0;;INCREMENT PTR TO NEXT BYTE#BUFRHI;;TO SENDX;,X; PATCH} TO ROUTINE - CHANGED CHECK"X;,1NOWRP0QBUFRLO;;CHECK IF PTR IS WITHIN BUFFER6+RBFENLO;;DO A DOUBLE PRECISION SUBTRACT@} QBUFRHIJ SBFENHIT3DNOTEND;;BRANCH IF (BUFR) < (BFEN)-MORE TO SEND^X;h*QCHKSNT;;TEST IF CHECKSUM ALREADY SENTr#HR}ELONE;;BRANCH IF ALREADY SENT|X;&X; SEND CHECKSUM AND SET FLAGX; QCHKSUM+PSEROUT;;PUT CHECKSUM IN SERIAL O}UT REG"CHKSNT;;SET FLAG TO FF HEXHCHKDON;;RETURNX;JX; AFTER CHECKSUM SENT AND CAUSE NEXT INTERRUPT THEN CH}ANGE POKEYKX; MASK TO ENABLE TRANSMIT DONE INTERRUPT AND TERMINATE WAIT LOOP.X;"RELONEQPOKMSK;;GET POKEY MASK}L>;;OR IN ENABLE PPOKMSK!PIRQEN;;ENABLE THE INTERRUPTSX;#X; RESTORE REGS AND RETURN&X;0 CHKDON7:?;};RESTORE Y REGD57;;RESTORE A REG SAVED IN OS IRQ INTERRUPT HANDLERN9XX;b=X; MORE TO SEND. SEND NEXT BYTE POINTED} AT BY BUFR.lX;vNOTEND%>Q@BUFRLO7;;GET NEXT BYTE"PSEROUT;;PUT IN SERIAL OUT REGX;,!OCHKSUM;;ADD BYTE T}O CHECKSUMO> PCHKSUMX;-!CHKDON;;GO RETURN AND WAIT FOR NEXT BYTEX;9X; ******** END OF OUT SERVICE R}OUTINE ********DX; **** SERIAL INPUT READY INTERRUPT SERVICE ROUTINE ****X; X;X; FX; AFTER SERIA}L RECEIVE IS ENABLED ROUTINE IS USED TO COLLECT*CX; BYTES FROM THE SERIAL INPUT REG AND PUT THEM IN BUFFER.4EX; } WILL STOP WHEN BUFFER IS FULL. IF A CHECKSUM IS EXPECTED>EX; ROUTINE WILL MARK BUFFER FULL AND CONTINUE. WHEN CHECKS}UMHBX; RECEIVED IT WILL CHECK IF = TO CHECKSUM IT WAS MAKING.R7X; WILL STORE ERRORS FOUND IN STATUS LOCATION.\}X;fLX; THE IRQ INTERRUPT HANDLER IN THE OS PUSHES THE USER'S A REGISTERp7X; ONTO THE STACK BEFORE CALLING THIS} ROUTINE.zX;X; K.B. 6/11/80X; ISRSIRC;;SAVE Y REG ON STACK5X;0X; GET STATUS FROM POKEY THEN }RESET IT.X; QSKSTAT'PSKRES;;IGNORES VALUE- JUST STROBEDX;X; CHECK FOR ERRORSX;*GNTFRAM;;BIT 8 SET }IF NO FRAMING ERROR %>FRMERR #'STATUS;;SET FRAME ERROR STATUS X;$ 2NTFRAMM> ;;IF BIT 5 CLEAR THEN FRAME OVER RUN. "H}NTOVRN;;BRANCH IF NO OVER RUN8 %>OVRRUNB *'STATUS;;ELSE SET OVERRUN ERROR STATUSL X;V HX; CHECK IF BUFFER FULL AND} THIS IS A CHECKSUM. IF IT IS, THEN` )X; CHECK IF DATA SENT WAS VALID.j X;t 3NTOVRNQBUFRFL;;TEST FOR BUFFER FULL (N}OT ZERO)~ 0FNOTYET;;IF ZERO THEN NOT YET, THIS IS DATA. !QSERIN;;ELSE THIS IS CHECKSUM RCHKSUM;;ARE THEY EQUAL? FSRE}TRN;;YES,THEN RETURN -%>CHKERR;;ELSE SET CHECK SUM ERROR STATUS 'STATUS X; -X; SET RECEIVE DONE TO END WAIT LOO}P X; SRETRNQ>;;DONE VALUE PRECVDN X; #X; RESTORE REGS AND RETURN X; SUSUAL7 ?;;RESTORE Y REG 7;;R}ESTORE A REG( 92 X;< LX; IF BYTE IS DATA, THEN GET HERE. PUT BYTE IN BUFFER AND CHECK IFF X; AT END OF BUFFER}.P X;Z NOTYETQSERIN;;GET DATA BYTEd %>n %P@BUFRLO7;;STORE IT IN THE BUFFERx X; , &OCHKSUM;;ADD DATA BYTE TO CHEC}KSUM O> PCHKSUM X; *#BUFRLO;;INCREMENT POINTER TO LOCATION HNTWRP1;;FOR NEXT BYTE INPUT #BUFRHI X; 9X; } THE PATCH CHANGED THE TEST FOR END OF BUFFER X; 0NTWRP1QBUFRLO;;DO DOUBLE PRECISION SUBTRACT RBFENLO QBUFRHI} "SBFENHI;;CARRY CLEAR IF BORROW :DSUSUAL;;BRANCH IF (BUFR) < (BFEN)-WITHIN BUFFER LIMIT" X;, 7X; DONE WITH DATA. }SEE IF CHECKSUM TO BE SENT6 X;@ &QNOCKSM;;IF = ZERO THEN A CHECKSUMJ FGOON;;WILL FOLLOW THE DATAT X;^ #Q>;;ELSE NO CHE}CKSUM TO FOLLOWh #PNOCKSM;;CLEAR NO CHECKSUM FLAGr /FSRETRN;;RETURN AFTER SET RECEIVE DONE FLAG| X; 4X; SET BUFFER }FULL AND THEN GO GET CHECKSUM X; ,GOON"BUFRFL;;SET BUFFER FULL FLAG TO FF HSUSUAL;;GO RETURN X; KX; ********} END OF RECEIVE SERIAL INPUT INTERRUPT ROUTINE ******** MDEND   / MDEND;;SET END ADDR IN FMS PAST RES DUP SO >X;} ;BUFFERS DON'T CLOBBER IT. STAKNTERRUPT SERVICE ROUTINES ****X;X;9X; EEX;SAVE #D2:DUPBUF.M65.ABUFFERS - BEGINNING OF NON-RESIDENT DUPAHX; ******** BEGINNING OF NON-RESIDENT PORTI}ON OF DUP ********X;X;3NDOS|;;END OF THE SYSTEM BUFFERS AND MINIDUPB NDOSLPAR(;;PARAMETER AREAj LINE}P;;TYPE IN LINE BUFFERtLBUFLINE"DBUF;;DATA BUFFER FOR COPYDB1DBUFDB3DBUF DBL;; DATA BU}FFER LENGTH.EDBL;;DATA BUFFER LENGTH USED IN USEPGM( MENUSZ2 PER< UNNOF RCNTP SSTATZ SWDP}d CSRCn CDESx SAVX PTR IPTR CTR T16BUFLENT1;;SAVE AREA FOR BUFR LEN, USED IN USEP}GM!STVEC;;A TEMP OF SOME KIND9MLT125STVEC;;TEMP STORE FOR MULTIPLE OF 125, USEPGM2;; Junk!!! Just takes up sp}ace for alignment0EOFFLG;;ENDFILE FLAG FOR SOURCE IN DUPFIL0FTRF;;FIRST TIME READ FLAG USED IN DUPFIL@TWODRV}FTRF;;FLAG TO SHOW IF 1 OR 2 DRIVES. USED IN DUPDISK DTH EDN AE:A=CR; ******** BEGINNING OF NON-RESIDENT PORTIN X;SAVE #D2:DUPCMD1.M65AMAIN MENU ROUTINESAX; **** DOS MENU ****X;X;DMENU CLSCR$( ADISK OPERAT }ING SYSTEM II VERSION A. =A 2.5 A8) ACOPYRIGHT 1984 ATARI CORP.A=CR=CRB, AA. DISK DIRECTORY I. FORMAT DISKA=CRL }/ AB. RUN CARTRIDGE J. DUPLICATE DISKA=CRV, AC. COPY FILE K. BINARY SAVEA=CR`, AD. DELETE FILE(S) L. BINARY }LOADA=CRj/ AE. RENAME FILE M. RUN AT ADDRESSA=CRt/ AF. LOCK FILE N. CREATE MEM.SAVA=CR~/ AG. UNLOCK FILE } O. DUPLICATE FILEA=CR. AH. WRITE DOS FILES P. FORMAT SINGLEA=CR CDN=CDN=CDN=CDN=CDN DMEND DULENDMEN }DDMENUX;@ALIGN u DOSOS!:DOSOSX;>DUJPT DIRLST=STCAR=CPYFIL=DELFIL=RENFIL=LKFIL=ULFIL7 WBOOT=F }MTDSK=DUPDSK=SAVFIL=LDFIL=BRUN=MEMSAV DUPFIL=SGLFMT!DUNUM;;NUMBER OF FUNCTIONS 0X; **** DISK OPERATIN }G SYS MONITOR ****X;X;(:DOSOS$>2 -;;MAKE SURE DECIMAL MODE OFF< &BRKKEYF2P &LOADFGZQ>d PLMARGNnQ }>'xPRMARGN;;SET MARGINS%QPOKMSK;;ENABLE BREAK INTERRRUPTSL> PPOKMSK PIRQEN INITIO;;CLOSE FILESX;#X }; Check for mini-dup of DOS 2.5X; QOLDPRMSG!R>L;; If not a JMP, then 2.0s FDSKUTLX;(:NEED2.0Q>;; Set DUP }not in memory PDUPFLGQ>4:WRONGMINI$>5:WRONGMINI" WAITY' !:NEED2.0,X;67:WRONGMINI }=AInsert DOS 2.0s, ty }pe Y A=CR@X;J X; DISK UTILITY MONITORTX;^ DSKUTLhDU1Q>DUNUMrPMENUSZ;;SET MENU SIZE| Q>4DUJPT P }JMPTBL Q>5DUJPT)PJMPTBL;;SET UP JUMP TABLE ADDRESSX; FALL THRU TO MENU SELECTX;X;X;CX; MENU SELECT MO }NITOR -- VECTORS TO ROUTINE SELECTED FROM MENU.X;$SHMENQ>4DMENU;;GET MENU ADDRESS PICBAL Q>5DMENU PICBAHQ> }4DULEN;;GET MENU LENGTH PICBLL Q>5DULEN& PICBLH0 DSPMSG;;SHOW MENU:X;D!X; SELECT ITEM FROM MENUNX9X; } **** FUNCTIONS COME HERE WHEN THEY ARE DONE ****bX;l)MENUSL$>;;RESET STACK AT THIS POINTvB2!&WCFLAG;;CLEAR }WILD-CARD FLAGQ>4SIT;;SELECT ITEM MESSAGE $>5SIT PRNTMSGQ>@;;MAKE SURE UPPER CASE PSHFLOK" CHRGET;;GO GE }T KEYBOARD CHAR.X;R>CR;;IF CR RE-DISPLAY MENU FSHMENX;;0S> A;;CONVRT ASCII CHAR. TO BINARY # & SUB. 1 0GR }ANGE;;IF ASCII CHAR NOT A #, GO READ AGAIN*RMENUSZ;;IS THE # ENTERED > MENU SIZE? "IRANGE;;IF YES, GO READ AGAIN.*T?4 }#?;;SET INDEX TO (MENU # - 1) * 2> Q@JMPTBL7H3RPRAMLO;;GET STRING POINTER\ Q@JMPTBL7f PRAMLOp+%>;;LOAD STRIN }G POINTER INTO REGISTERSzQ@RAMLO7;;FOR DSPLIN>1 Q@RAMLO7) DSPLIN;;PRINT MODULES INITIAL STRING SCROL;;SCRO }LL INPUT WINDOW1QRAMLO;;INC BY 2 TO POINT PAST STRING POINTER,O> PRAMLOD:DOSELECTION #RAMLO<:DOSEL"}2 X;SAVE #D2:DUPDEL.M65ADELETE FILESA(X; **** DELETE FILE ROUTINE ****X;X;DELFIL DEMG$ GETIC1.(} PERX;;EXIT IF PARAM ERRORS8X;B/ CHKVER;;BE SURE THAT IT IS VER. 2 DISKETTELX;V@X; CONTINUE WITH DELETE - ALL(}OW ONLY FOR DISK DEVICE ID`X;jQPAR;;GET DEVICEt!R> D;;ONLY ALLOW DELETE FOR D:~FDF1 Q>4NDF $>5NDF DSPLIN(} !MENUSLNDF ANOT A DISK FILEA=CRX; DF1$>QOPTR> N;;IF OPTION=N, NO QUERYHDWQ;;NO, DELETE WITH QUERY (} Q>DELETE PICCOM9 CIOCL( !MENUSL2DWQQ>4TYQ< $>5TYQF$ DSPLIN;;SAY TYPE Y TO DELETE...PQ>Z0PIPTR;;HOW (}MANY FILES TO SKIP, NONE AT FIRSTd$> ;;SET UP DELETE IOCBn Q>DELETEx PICCOM9 Q>4DB3 PICBAL9 Q>5DB3 PICBAH9(}Q> D PDBUFQ> : PDBUF-QPAR;;DEVICE NUMBER OR : FROM OP INPUTR> : H:HASDN#Q> 1;; NO DRIVE NUMBE(}R - USE D1:):HASDNPDBUF;;KLUDGE KLUDGE KLUDGE IDRD$> Q>OPEN PICCOM9"Q>,PICAX19;;DIR READ OPEN6 Q>4(}PAR@ PICBAL9J Q>5PART PICBAH9^ CIOCLh Q>4DBUFr PICBAL9| Q>5DBUF PICBAH9 Q>GETREC PICCOM9Q>(PP(}TR;;HOW MANY FILES WE HAVE SKIPPEDX;.X; READ FILENAME FROM DIR, QUERY AND DELETEX; RDFN$>Q> PICBLL9Q>(} X;SAVE #D2:DUPDIR.M65ALIST DIRECTORYA.X; **** DIRECTORY LISTING ROUTINE ****X;X;DIRLST DLMG$ $}GETIC1.! USEBUF;;INIT BUFADR & BUFLEN8$PTRB&QPAR9;;LAST CHAR OF SEARCH SPECLR> :;;IF COLON, ADD *.*VHGLF`Q>$} *j PPAR9t PPAR9~Q> . PPAR9222&PTR'GLFQ>CR;; Put RETURN at end of buf PPAR9 &SAVX$}$>  PIOCB GETFIL PERX)Q>;;READ DIR INFO - use new mode!!!! $> PICAX19Q>OPEN;;OPEN( PICCOM92%&$}CSRC;;COPY SOURCE=DIRECTORY INFO< CIOCLFQPTRP;Z SSAVXd0R>;;IF ONLY 3 CHARS, IS 'D:'CR, USE DEFAULTn FDLST1x$}DLST0!PDES;;GO INTO COPYDLST1$SAVX QPAR9R> D HDLST0&!PDES1;;GO INTO COPY WITH DES='E:'X;1DLMG ADIREC$}TORY--SEARCH SPEC,LIST FILE?A=CRLIST DIRECTORYA.X; **** DIRECTORY LISTING ROUTINE ****X;X;DIRLST DLMG$ $! PICBLH9& CIOCL;;READ A LINE FROM DIRECTORY)QDBUF;;IF FILE LINE, THIS IS BLANKR> ;; Is it a space?&#HDELX(};;THIS IS FREE BLOCKS LINE0#PTR;;COUNT THIS FILE:"QPTR;;HAVE WE SKIPPED ENUF YETD RIPTRNGRDFN;;BR IF NOX$>;;PUT(} PTRb%>;;GET PTRlX;vX; MESSAGE DELETE FILE NAMESX;MDN1QDBUF8R> ;;END OF FILENAME FMDN2 PDBUF92(}3(> GMDN1X;!X; FILENAME IS MOVED, PUT .EXTX; MDN2Q> . PDBUF9 2%> ;;WHERE EXT IS MDN3QDBUF8*(} PDBUF943>2H)> R GMDN3\&SAVX;;PUT CR HERE LATERfQ> ?;;FOR QUERYp PDBUF9z2Q>CR PDBUF9 Q>4DB3 $>(}5DB3# DSPLIN;;GO ASK ABOUT THIS FILE CHRGETR> YHRDFN;;GO DO NEXT FILENAME/QPTR;;NUMBER FILES WE HAVE GONE T(}HRU SO FAR!PIPTR;;IS NEW NUMBER TO SKIP. $SAVXQ>CR PDBUF9 $> ;;DELETE IOCB CIOCL CLOS1$ )!IDRD;;CLOS(}E AND REOPEN DIR READ FILE. $DELX CLOS1;;CLOSE DIR READ FILE8 !MENUSLB CLOS1$>L Q>CLOSEV PICCOM9` !CIOCL;;DO CL(}OSE AND RETURNj 0TYQ ATYPE A="=AYA="=A TO DELETE...A=CR X; DEMG ADELETE FILE SPECA=CR X;LISTDEMG$ GETIC1.(lX;SAVE #D2:DUPCOPY.M65ACOPY FILESA$X; **** COPY FILE ROUTINE ****X;X;CPMG ACOPY--FROM, TO?A=CR$,} OE AOPTION NOT ALLOWEDA=CRLX;VX;`X;jX;tX;~ WCFLAG WCSKP1 WCSKP2 WCBUFLWCBUFWCBUFL,}WCOPYM A COPYING---AWCBUF2 ADN:AWCBUFL"CPYFIL CPMG;;COPY FILE PROMPT$ GETIC1;;GET SOURCE DEVICE, ETC,}.QPTR PSAVX!QPAR;;GET 1ST CHAR. OF DEVICER> D;;TEST IF IT IS THE DISK 3HJMPNWC;;BR IF NOT THE DISK (THEN USE O,}LD CODE)"$>;;LOOK AT SOURCE FILE SPEC.- LOOKWC;;LOOK FOR WILDCARDS IN FILE SPEC.(3FCPYFL1;;BRANCH IF WILDCARDS USED ,}IN DISK SPEC.2JMPNWC!NOTWC;;USE OLD CODE<CPYFL1Q>FX;PX;Z9WCINITPWCFLAG;;'WLDCARD' MODE (COPY-FILE OR DUP-FIL,}dQ>n PWCSKP1xX;WCOPYLQ> PWCSKP2$>;;OPEN DIRECTORYQ> PICAX19 Q>OPEN PICCOM9 Q>4PAR P,}ICBAL9 Q>5PAR PICBAH9 CIOCLX;X;#WCOPYRQ>GETREC;;READ DIRECTORY PICCOM9" Q>WCBUFL, PICBLL96Q>@,} PICBLH9J Q>4WCBUFT PICBAL9^ Q>5WCBUFh PICBAH9r CIOCL|X;3QWCBUF;;IF 1ST CHAR. OF DIR READ IS A #-IT IS TR,}> 0 DWCGOTR> : EWCGOTX;3Q>CLOSE;;ALL DONE -- NORM EXIT OF WILDCARD COPY PICCOM9 CIOCL !MENUSLX;,}X;9WCGOTQWCSKP1;;IF ALREADY COPIED OR SKIPPED THIS FILE RWCSKP2 FSKIP1X;& #WCSKP20 HWCOPYR:X;DSKIP1#W,}CSKP1NX;X&Q>CLOSE;;CLOSE DIRECTORY READ FILEb PICCOM9l CIOCLvX;X; %>;;DON'T COPY .SYS FILESSYSLOPQWC,}BUF 8 RDOTSYS8 HNOSYS1 ISYSLOP GWCOPYLX;DOTSYS ASYSAX;'NOSYS%> 1;;CALC SOURCE DRIVE NUMBER Q,}PARR> :  FWCGOT1? WCGOT1'WCBUF2*X;4X;>+$>;;COMPRESS SPACES, ADD ':', ADD 'CR'H%>RX;\COMPR1,}QWCBUF9f R>SPACEp FCOMPR2z PWCBUF283X; COMPR22(>  HCOMPR1X; QWCBUF9 R>SPACE FCOMPR5Q> .,} PWCBUF283COMPR3QWCBUF9 R>SPACE FCOMPR4 PWCBUF28$ 3. COMPR428 (> B HCOMPR3L X;V COMPR5Q>CR` P,}WCBUF28j X;t X;~ 5Q>4WCOPYM;;PRINT 'COPYING---DEV:FILENAME.EXT' MSG $>5WCOPYM DSPLIN X; *WCFLAG 2JWCOPY;;BR,} TO MIDDLE OF DUP FILE ROUTINE IF DU X; /$>;;SET UP BUFR ADDR TO PNT TO WLDCARD FIL Q>4WCBUF2 PICBAL9 Q>5WCBUF2,} PICBAH9 !WCDUPS X; #WCOPY USEPGM;;SET BUFFER SIZES $>;;OPEN COPY SOURCE FILE Q>OPEN( PICCOM92 Q>< P,}ICAX19F Q>4WCBUF2P PICBAL9Z Q>5WCBUF2d PICBAH9n &CSRCx CIOCL X; $> % PIOCB;;GET COPY DESTINATION FILE 0,}QPTR;;SAVE PTR,IPTR- MIGHT REPET GETTING 2ND MES 5 QIPTR 5 % GETFIL;;GET 2ND FILE NAME TO PAR 7;;RECOVER IPTR,},PTR PIPTR 7 PPTR $SAVX QPAR9 R> D" FWCOPY0, 3!PDES;;JMP TO OLD CPY-FILE CODE IF NOT DSK DEST6 X;@ -WCOP,}Y0%> 1;;CALCULATE DESTINATION DRIVE #J QPAR9T R> :^ FWCOPY1h X;r ?| WCOPY1)WCBUF2 HWCOPY2 3 CLOSX;;CANT ,}COPY TO SAME DRVE NMBR - ERR & EXI X; !ODMS X; X; WCOPY2$> .'WCBUF2;;CHANGE FILESPEC TO DESTINATION Q>4,}WCBUF2 PICBAL9 Q>5WCBUF2 PICBAH9 -!OPDES1;;CONTINUE INTO OLD COPY-FILE CODE X; X; NOTWC & $> ;;IOCB 30 ,} PIOCB: GETFIL;;GET SECOND FILENAMED X;N 0X; MAKE SURE DESTINATION IS NOT DOS.SYSX X;b ($SAVX;;ENTRY-INDEX TO DE,}ST FILE SPECl ' TSTDOS;;WON'T RETURN IF IS DOS.SYSv X; $SAVX LOOKWC 2HNWCIND;;BRANCH IF NO WILDCARDS IN DESTINATIO-}N Q>4NWA $>5NWA DSPLIN !MENUSL 4NWA AWILD CARDS NOT ALLOWED IN DESTINATIONA=CR X; NWCIND   PERX;;IF-} PARAM ERRS, EXIT 4 USEPGM;;ASK USR IF CAN USE PGM AREA OR DATA BFR PSRC QPAR;;GET 1ST LETR OF PARAM* R> K4 4FODM-}S;;K:GETS 'OPTION DOESNT MAKE SENSE' FOR NOW> R> CH 6FODMS;;C: GETS 'OPTION DOESNOT MAKE SENSE' FOR NOWR R> E;;E: AS SOURC-}E IS SPECIAL\ 'HOPSRC;;IF NO THEN OPEN SOURCE FILEf $>p &CSRCz !PDES OPSRCR> S -FODMS;;S: AS SOURCE GETS O.D.M.S-}. FOR NOW X; X; OPEN SOURCE FILE X; $> Q>OPEN PICCOM9 Q>;;OPEN IN PICAX19 &CSRC! CIOCL;;OP-}EN SOURCE FILE HEREX;)X; READY FOR OPEN OF DESTINATION$X;.PDES$SAVX8 QPAR9BX;LR> K;;IS DEST KEYBOARD?V-} FODMS;;YES, THEN CAN'T DO IT`X;jR> E;;CHECK FOR SPECIAL CASEtHOPDES;;IF NOT~:PDES1Q>;;SPECIAL CASE - DONT OPEN,-} USE EXISTING IOCB PCDES !DOCPYODMSQ>4OE!$>5OE;;SAY OPTION NOT ALLOWED DSPLIN CLOSX;;CLOSE IOCB 1 & 2-} !MENUSLX; OPDESR> C6FODMS;;C: GETS 'OPTION DOESNOT MAKE SENSE' FOR NOW$OPT;;GET 2ND FILE OPTIONX;(> A;;A- }PPEND TO DISK FILE  HOPDES1R> D HODMS(Q> 2 HOPDES3<OPDES1Q>FOPDES3$> PPICAX19;;OPEN TYPE OUTZ Q>OP- }ENdPICCOM9;OPENn &CDESx CIOCLQ> PICAX29X;X;COPY FROM CSRC TO CDESX;DOCPYQ>GETCHR GC1$CSRC- } %CDES PICCOM9 Q>PUTCHR PICCOM8'QBUFADR;;ADDRESS OF BUFFER - EITHER3PICBAL9;;PGM AREA (MEMLO) OR DATA BUFFER - }(DBUF) PICBAL8'QBUFADR;;BUFADR IN LSB,MSB ORDER PICBAH9" PICBAH8,CLOOP$CSRC6'QBUFLEN;;LENGTH OF BUFFER AD- }DRESSED@PICBLL9;;BY BUFADRJ1QBUFLEN;;BOTH BUFADR & BUFLEN ARE ASSIGNEDT!PICBLH9;;IN SUBROUTINE USEPGM^ CIO;;READ-} FROM INPUTh 'SSTATr $CDES| %CSRC QICBLL8 PICBLL9 QICBLH8 PICBLH9&LICBLL8;;IF SOURCE FILE LENGTH = 0F-}CKRS;;DON'T DO WRITE! CIOCL;;WRITE, ABORT IF ERROR/CKRSQSSTAT;;GET READ OPERATION STATUS BACK$ICLOOP;;IF OK, GO RE-}AD SOME MORER>;;EOF STATUS FCLOC!CIOER;;IF NOT, ABORTCLOC$CSRCFDU4;;IF E:, DONT CLOSEX;X;CLOSE SOU-}RCE FILE&X;0 Q>CLOSE: PICCOM9D CION DU4$CDESXFDU3;;IF DES=E:b Q>CLOSEl PICCOM9v CIO DU3$CDESHDU-}6Q>4DDSK$>5DDSK 5 PRNTMSG;;PRNT A CR BEFOR SELECT OR WLDCARD PRMPT DU6 X; *WCFLAGIDU5*!WCO-}PYL;;BRANCH BACK TO WILD CARD LOOPDU5!MENUSLX; **** COPY FILE ROUTINE ****X;X;CPMG ACOPY--FROM, TO?A=CR$,1X;SAVE #D2:DUPCMDS.M65ARENAME, ETC.A(X; **** RENAME FILE ROUTINE ****X;X;IX;RENAME SETS UP IOCB #11} WITH THE OLD FILE NAME AND THE BUFFER ADDRESS$IX;POINTS TO THE NEW FILE NAME. THE NEW FILE SPECIFICATION CANNOT HAVE.JX;A1} DEVICE ID. THE DEVICE ID IS THE SAME AS SPECIFIED FOR THE OLD FILE8CX;D2:ABC.S2,QQQ.R3 THIS RENAMES ABC.S2 ON DRIVE #21} TO QQQ.R3BX;LRENFIL RNMGV1 GETIC1;;GET OLD FILE SPEC & PUT ADDR IN IOCB` GETNAME;;GET NEW FILE NAMEj# PERX;;EXI1}T IF PARAMETER ERRORStX;~% CHKVER;;MAKE SURE VER 2 DISKETTEX; X; CONTINUE WITH RENAMEX; Q>RENAME$>1} PICCOM9 CIOCL !MENUSL+RNMG ARENAME - GIVE OLD NAME, NEWA=CRX;;X;******************* SUBROUTINE ******1}*************X;5X; MAKE SURE THIS IS A VERSION 2 FORMAT DISK X;+CHKVER%>;;ASSUME DRIVE 1- GET DRIVE #3QP1}AR;;TEST CHAR 2 OF FILE SPEC FOR SEMICOLON('R> :;;IF IS, USING DEFAULT DRIVE (1)2!FDRV1;;IT IS, SO SAVE DRIVE #<,M>;1};ELSE CHAR 2 IS ASCII REP OF DRIVE #F!?;;CONVERT TO BINARY & SAVE ITPDRV1'UNNO;;SAVE DRIVE #ZX;d5!TSTVER2;;TST FOR V1}ERS. 2 DISK- WONT RTURN IF NOTnX;x(X; **** FORMAT DISK ROUTINE ****X;X;(SGLFMT WHD;; Single density for1}mat!Q>FORCEFMTH:FMTOPTIONSX;FMTDSK WHD Q>FORMAT:FMTOPTIONSPFMTTYPE GETLIN GETDN,O> 0 1}PDDSK PCDSK" PERX,(Q>4VFM;;QUERY TO VERIFY DRIVE NUMBER6 $>5VFM@ DSPLINJ CHRGETTR> Y;;SEE IF OK^HFMXh 1 }QFMTTYPEr%> !| DOFMTFMX!MENUSL;;EXIT.X;FMTTYPEX; DOFMT$> PICCOM9 Q>4FDP PICBAL9 Q>5F1!}DP PICBAH9C PICAX19!!CIOCL;;CALL CIO TO DO FORMAT%WHD AWHICH DRIVE TO FORMAT?A=CR/VFM ATYPE A="=AYA="1"}=A TO FORMAT DISK A DDSK& CR0 FDP ADA: CDSKD A:A=CRNX,X; **** START CARTRIDGE ROUTINE ****bX1#};lX;vSYVBLSYSVBVXTVBLXITVBV%STCAR SCMG;;NO MSG, PRINT A ROMTST!%ROMTST;;TEST IF RAM OR OTHER1$}Q>;;PATTERN #1 PROMTST RROMTSTHNOTRAM;;BRANCH IF NOT RAMQ>U;;PATTERN #2 PROMTST RROMTSTHNOTRAM;;B1%}RANCH IF NOT RAMX;-'ROMTST;;THERE IS VALID RAM - SAY NO CART NOCARTQ>4NCA$>5NCA;;SAY NO CART  DSPLIN* !MEN1&}USL4X;>/X; CHECK IF ROM OR EMPTY ADDRESS SPACEHX;R#NOTRAMQ;;KNOWN ROM ZERO BYTE\*HNOCART;;BRANCH IF EMPTY A1'}DDRESS SPACEfX;p+>;;SINCE EMPTY ADDR SPACE GIVES A RANDOMz8CKCARTQROMTST;;VALUE, TEST THE SAME LOC MANY TIMES.#FNOCA1(}RT;;BRANCH IF NO CARTRIDGE RROMTST#HNOCART;;BRANCH IF NO CARTRIDGE2HCKCART;;LOOP BACKX;X;=X; RESET1)} VERTICAL BLANK VECTORS BEFORE ENTERING CARTX; INITIOQ>;;SET VVBLKI$>5SYVBL;;HI BYTE %>4SYVBL SETVBV 1*}Q>;;SET VVBLKD $>5XTVBL$ %>4XTVBL. SETVBV8 !CLMJMPB L NCA ANO CARTRIDGEAV SCMG CR` X;j X;t +X; *1+}****** RUN AT ADDRESS *******~ X; X; X; BRUN BRMG GETLIN GETNO PERX PRAMLO &RAMLO QCTR R>1,} 2FMOUT1;;RETURN TO MENU IF NO RUN ADDRESS GIVEN . INITIO;;CLOSE ALL IOCB'S, THEN REOPEN S/E )!LMTR;;LOAD MEM.SAV & J1-}UMP TO ADDRESS X; X; &BRMG ARUN FROM WHAT ADDRESS?A=CR( 2 2X; **** CREATE MEM.SAV FILE ON DISK ****< X;F X1.};P 6MEMS ATYPE A="=AYA="=A TO CREATE MEM.SAVA=CRZ MEMSAV MEMSd  CHRGET;;GET CHAR (CR)n R> Yx *HMOUT;;BRANCH IF 1/}USER'S ANSWER NOT A Y MEMSVQ;;TRY TO OPEN MEM.SAV +GMCONT;;IF FILE DOESN'T EXIST THEN JUMP -Q>4MEMSG;;ELSE 'MEMORY.SA10}VE' AREADY EXIST $>5MEMSG;;  DSPLIN;;DISPLAY THIS FACT )MOUT CLOSX;;EXIT AFTER CLOSING IOCB1 MOUT1!MENUSL;; X;2-} X;SAVE #D2:DUPDOS.M65AWRITE DOS FILESA%X; **** WRITE DOS & DUP ****X;X;,WBOOT DOSDRV;;ADDRESS O52}F DRIVE # PROMPT$X;.,X; RETRIEVE DRIVE NUMBER FROM USER.8X;B GETLIN;;GET INPUTL* GETDN;;GET DRIVE AS NUMBER, 53}VERIFY ITV PERX;;EXIT IF ERROR`PUNNO;;SAVE IT FOR TSTVER2jL> 0;;TURN BACK TO ASCII REPt&PDS;;STORE IN DOS.SYS FI54}LE SPEC~PQWMG;;& IN PROMPTX;5 TSTVER2;;TST IF VERS. 2 DISK - IF ISNT WONT RTRNX;>X; ASK USER IF CAN WR55}ITE DOS & DUP TO SPECIFIED DRIVEX;Q>4QWMG;;PRINT PROMPT $>5QWMG DSPLIN CHRGETR> YHWBX;;EXIT UNLESS Y56}X;GX;TELL USER WRITING DOS FILES AND WRITE DOS.SYS FIRST- JUST OPEN IT. X; Q>4WBMG $>5WBMG( DSPLIN2X;< Q>57}OPENF $>;;OPEN DOS.SYS ON IOCB #1P2PICCOM9;;WILL CAUSE FMS TO REWRITE BOOT SECTORZQ>4DS;;& A COPY OF DOS.SYSd PICBA58}L9n Q>5DSx PICBAH9Q> PICAX19' CIOCL;;DO OPEN, IF ERROR GOTO MENUX;$> Q>CLOSE PICCOM9 CIOCL;;59}DONE CLOSE IT.X;*X; WRITE DUP.SYS - SWAP AREA FILEX;$> ;;MOVE 11 CHARSMDUPBLQDUPSYS9.PPAR9;;M5:}OVE FILE NAME TO PARAMETER LIST0 HMDUPBL"QDS;;GET DRIVE NUMBER,(PPAR;;PUT IT IN DUP.SYS FILE SPEC6X;@&P5;}TRJ$>T) PIOCB;;PUT FILE NAME POINTER IN IOCB^ Q>4DTHh PLDSTr Q>5DTH| PLDST Q>4NMDUP PLDND Q>4LEN 5<}PWDRL Q>5LEN PWDRH Q>5NMDUP PLDND 5;;NO /A Q>4DOSOS PRUNAD Q>5DOSOS&PRUNAD;;SET DUP.SY5=}S RUN ADDRESS"RUNQ;;SET RUN FLAG!NRUNAD;;WRITE DUP.SYSWBX!MENUSL&.DOSDRV ADRIVE TO WRITE DOS FILES TO?A=C5>}R0%WBMG AWRITING NEW DOS FILESA=CRXX;bl=QWMG ATYPE A="=AYA="=A TO WRITE DOS TO DRIVE .A=CRX;DS AD1:5?}DOS.SYSA=CRX;,WVD AERROR - NOT VERSION 2 FORMAT.A=CRX; 7X; **** TEST FOR VERSION 2 FORMAT - SUBROUTINE ****5@}X; X;*X;4 X; SUBROUTINE - TSTVER2>X;HIX; READS THE DISK'S VTOC AND CHECKS IF VERSION BYTE IS SET AS 2.5A}RX;\2X; ENTRY - DRIVE # STORED IN UNNOf?X; EXIT - RETURNS ONLY IF IS A VERSION 2 DISKp@X; 5B} ELSE DOES AN ERROR EXIT BACK TO MENUz-X; CALLS - DRVSTAT AND RVTOC6X; CAL5C}LED BY - DELFIL, RENFIL, WBOOT.X;X;IX; GET DRIVE TYPE SO KNOW CORRECT SECTOR SIZE - NEEDED FOR RVTOCX; TS5D}TVER2  X; .X; READ THE VTOC & CHECK IF VERSION 2 X;$ &OKTYP RVTOC;;READ IN VTOC TO DBUF. QDBUF;;1ST BYTE IS V5E}ERSION #8 R>;;IS IT VERSION 2?B &FSMVRS;;YES, SAME VERSION - RETURNL X;V 8X; NOT A VERSION 2 DISK - PRINT MSG & GO5F}TO MENU` X;j "Q>4WVD;;ELSE, NOT SAME VERSIONt "$>5WVD;;PRINT INCOMPATIBLE MSG~ DSPLIN !MENUSL;;GOTO MENU X; )X; 5G} DISK IS VERSION TWO SO RETURN X; SMVRS:;;RETURN**** WRITE DOS & DUP ****X;X;,WBOOT DOSDRV;;ADDRESS O49ADUP DISK-SOURCE,DEST DRIVES?A=CRt5DBUF;; Us=R}X;SAVE #D2:DUPCMD2.M65AVARIOUS COMMANDSA-X; **** LOAD USER FILE FUNCTION ****X;X;LDFIL LFMG$ 9K} GETIC1.Q>8$OPTBPOPTL+(> N;;IS OPTION N FOR DON'T LOAD AND GO?VHNOTN;;BRANCH IF NOT`"OPTjNOTN PERXt 9L}LOAD~#(>;;PROCESS LOAD SUBR RESPONSE FLDFX;;BRANCH IF LOAD WAS OK(>FNLF;;IF BAD LOAD FILE"C;;OTHERWISE WE GO9M}T A CIO ERROR!CIOER;;GO SAY WHAT IT ISNLFQ>4BLF $>5BLF DSPLIN;;BAD LOAD FILE MSG CLOSX;;CLOSE THE FILE9N}LDFX!MENUSL;;EXITBLF ABAD LOAD FILEA=CRX;$LFMG ALOAD FROM WHAT FILE?A=CR(22X; **** LOCK & UNLOCK FIL9O}E COMMANDS ****<X;FX;PLKFIL LKMG;;DO LOCKZ GETIC1d PERXn Q>LOCKx$> PICCOM9 CIOCL !MENUSL"L9P}KMG AWHAT FILE TO LOCK?A=CRX;ULFIL ULMG;;DO UNLOCK GETIC1 PERX Q>UNLOCK$> PICCOM9 CIOCL !9Q}MENUSL$ULMG AWHAT FILE TO UNLOCK?A=CR COMMANDSA-X; **** LOAD USER FILE FUNCTION ****X;X;LDFIL LFMG$ 8*e data buffer as VTOC bufferPVTOCPTR Q>4DBUF PVTOCPTR1QUNNO;; Use source drive number for VTOC read PICDNO=S}Z&Q>;; Turn off write required flag)PDBUFDVDWRQ;; so VTOC will be read. CALLRVTOC 6I:READOK;; If error occurre=T}d, tell user and abort. !CIOER1X;(:READOKQ>DVDSMP2PPTR<QDBUFDVDSMPFPCSRC;;BYTE OF ALLOC MAPPQ>ZPI=U}PTR;;COUNT BITS IN BYTEdQ>nPDSHI;;POINT TO SECTOR ONExQ> PDSLO:X;X;DUPDSK DDMGQ>;;ASSUME SIN=V}GLE DRIVEPTWODRV;;CLEAR FLAG GETLIN GETDNPUNNO;;UNIT NO FOR READ GETDN#PCDES;;CDES IS THE DEST DRIVE #=W} PERXX;2X; CHECK IF TWO DRIVE OR SINGLE DRIVE DUPX;"SAMEQUNNO,!RCDES;;IF BOTH UNITS THE SAME6FSDD;=X};SINGLE DRIVE DUP@ $>5IBDJ Q>4IBDT( DSPLIN;;PROMPT TO INSERT BOTH DISKS^ CHRGETh"TWODRV;;SET TWO DRIVE FLAGrGD=Y}ODKDP;;GO DUP DISK|-IBD AINSERT BOTH DISKS, TYPE RETURNA=CRX;X;X;LX;USED BY BOTH SINGLE & DOUBLE DRIVE DUP. WI=Z}LL NOT ASK TO SWAP IF 2 DRIVEX;FLAG (TWODRV) IS SET.(X;IF THE TWO DRIVE FLAG IS CLEAR WILL6X;FILL FROM SOURCE DISK, SW=[}AP, EMPTY, SWAP, REPEAT.X;*SDDQ>4ISD;;TELL USER TO INSERT SOURCE3$>5ISD;;FOR INITIAL READ - USED ONLY FOR SINGLE=\} DSPLIN;;DRIVE DUPLICATE CHRGET-DODKDPQ>4NMDUP;;SET BUFFER AT END OF DUP PSTVEC Q>5NMDUP PSTVEC&X;04X=]}; BUFFER BOTTOM MOVES FROM NMDUP TO MEMTOP:@X; SET END OF BUFFER TO MEMTOP MINUS 1 SECTOR IN BYTES.DFX; W=^}HEN BUFFER BOTTOM IS LESS THAN OR EQUAL TO BUFFER END, ATN5X; LEAST ONE MORE SECTOR WILL FIT IN MEMORY.XX;b QMEMTO=_}Pl;v"S>4SECSIZ;;T1 IS END OF BUFFERPT1QMEMTOP S>5SECSIZ+PT1;;T1 IS MEMTOP MINUS SECTOR SIZE.X;)X=`};SEE IF ROOM FOR AT LEAST ONE SECTOR!X;!QT1;;DO DOUBLE PRECISION TESTRSTVEC;;TO SEE IF ROOM+QT1;;IF T1 IS = S=a}TVEC THEN ENUF ROOMSSTVEC;;FOR ONE SECTOR"EENUF;;BRANCH IF (T1)>=(STVEC)NORMQ>4NRM $>5NRM  DSPLIN !ME=b}NUSL X;*+ENUF CKMEM;;SEE IF OK TO USE USER AREA4Q>>)POPT;;SET UP FOR READ HERE FIRST PASSH0PFIRSTTIME;; and set =c}the pass number to zeroR RVTOC;;READ VTOC\&QDSLO;;COPY INITIAL WRITE POINTERSf#PSWDP;;TO INITIAL READ POINTERSp QDSH=d}Iz PSWDPQPTR PSWDP QIPTR PSWDP QCSRC PSWDP!!LRS1;;SKIP FIRST READ PROMPTX;7X;READ FR=e}OM SOURCE DISK TIL BUF FULL OR END OF DATA.X;!DORDQ>;;FLAG WE ARE READINGPOPT*TWODRV;;TEST FOR 2 DRIVES GL=f}RS1;;YES, SKIP THE SWAP Q>4ISD;;INSERT SRC DISK $>5ISD$ DSPLIN. CHRGET8 X;B "X;SWAP POINTERS TO WHERE WE AREL X=g};V 1LRS1 DOSWDP;;SWAP SECTOR AND BITMAP POINTERS` X;j 0X;LOOP READING/WRITING SECTORS TO BUFFER AREAt X;~ $LRS AAM;;ADV=q}%b DUP M65bDUPEQU M65bDUPINIT M65b' DUPLOAD M65bEDUPMEMSVM65b#DDUPSUB M65b/~DUPSIO M65bDUPBUF M65bDUPCMD1 M65bDUPDIR M65bDUPDEL M65b/DUPCOPY M65bDUPCMDS M65b1DUPDOS M65bJDUPCMD2 M65b6{DUPDUP M65bLDUPFIL M65b DUPTST M65bDUPSAVE M65b.DUPMISC M65b8DUP REFb5zDUP OBJ DUPRES OBJzTEMP ANCE ALLOCATION MAP 0GASPT;;IF FREE, ADV SECTR POINTER & TRY AGIN *OPT;;SEE WHAT MODE GDOW;;BR IF WRITE  RSEC1;;DO=r} READ !IOD DOW DKWRT;;DO WRITE 'IODQDBUFLO;;ADVANCE BUFFER POINTER #N>;; Add 128 to buffer pointer PDBUFLO =s}GASPT #DBUFHI (ASPT ASP;;GO ADVANCE SECTOR POINTER 0QPTR;; Check to see if we're past end of map RMAXVTOC( /FSTD=t}D1;;ALL SECTORS DONE, SWAP TO DEST DISK2 QT1;;SEE IF ROOM FOR ANOTHER< RDBUFLO;;SECTOR BELOW MEMTOPF QT1P SDBUFHIZ=u} 2ELRS;;BRANCH IF (DBUF)<=(T1) - ROOM FOR MORE.d X;n X;SWAP DISKS AND CONTINUEx X; STDDQOPT GDORD;;IF WAS WRITE, =v}GO READ STDD2"OPT;;CHANGE TO WRITE %*TWODRV;;ARE 2 DRIVES BEING USED? G:CHKFMT;;YES, SKIP THE SWAP Q>4IDD;;INSERT=w} DEST DISK $>5IDD DSPLIN CHRGET X; 6:CHKFMTQFIRSTTIME;; Is this the first write pass? HLRS1 #FIRSTTIME=x} 1QCDES;; Set destination drive as format drive L> 0 PCDSK X; X; Format destination disk X; +%> !;; Use single d=y}ensity format command !QMAXVTOC;; unless in MFM mode" I:NOTMFM, %> "6 9:NOTMFMQDSLO;; Save ending sector of first read=z} pass7 58 QDSHI9 5? Q>FORCEFMT@  DOFMT;; Try to format diskB 7C PDSHID 7E PDSLOT !LRS1^ X;h STDD1QOPT;;EN={}D OF DATAr ISTDD2;;IF READ GO WRITE| +QCDES;; Write VTOC to destination drive PICDNOZ 3Q>4DBUF;; Set VTOC buffer addr=|}ess to our buffer PVTOCPTR Q>5DBUF PVTOCPTR  CALLWVTOC ,I:WRITEOK;; Report error if write failed !CIOER1=}} *:WRITEOK!MENUSL;;IF WRITE WE ARE DONE X; AX;DOSWDP - EXCHANGE CURRENT AND SAVED BITMAP & SECTOR POINTERS X;ALSO INIT=~} BUFFER POINTER X; DOSWDP%> SWLOPQSWATL8 PRAMLO QSWATH8 .PRAMLO;;GET ADDRESS FROM TABLE TO RAMLO $>=} Q@RAMLO6;;GET WHAT'S THERE& 50 QSWDP8: P@RAMLO6D 7N PSWDP8X 1b ISWLOPl QSTVECv PDBUFLO QSTVEC PDB=}UFHI : X; FIRSTTIME X;  +SWATL 4DSLO=4DSHI=4PTR=4IPTR=4CSRC +SWATH 5DSLO=5DSHI=5PTR=5IPTR=5CSRC=} X; X; NRM ANOT ENOUGH ROOMA=CR -ISD AINSERT SOURCE DISK,TYPE RETURNA=CR 2IDD AINSERT DESTINATION DISK,TYPE RE=}TURNA=CR X; X; +X; AAM - ADVANCE ALLOCATION MAP ONE BIT.* X; RETURN MINUS IF FREE.4 X;> $AAMTCSRC;;NEXT BIT OF ALLO=}C MAPH "IPTRR !HCBIT;;IF DONE WITH THIS BYTE\ #PTR;;GET NEXT ONEf $PTRp 3QDBUF9;;VTOC IS DBUF & BITMAP STRTS IN 10TH =}BYTz PCSRC Q> PIPTR CBITQCSRC;;CHECK THE BIT : X; X; *X; ASP - ADVANCE SECTOR POINTER IN DCB. X; ASP=}#DSLO HASPX #DSHI ASPX: X;2X; RSEC1 - READ A SECTOR WHOSE NUMBER IS IN DCBX;RSEC1QUNNO$*,;;TELL DISK H=}ANDLER DOING A GET SECTOR. D:SECIO8X;BX; DKWRT - WRITE A SECTORLX;V DKWRTQCDES;;PUT DEST UNIT #`*;;;TELL DISK HAN=}DLER DOING WRITE SECTORj :SECIOt PDUNIT~! BSIOR;;GOTO FMS DISK HANDLER IDRTS;;RETURN IF GOOD STATUS$!CIOER1;;CIO =}ERROR, GO SAY WHICHDRTS:;; just returnX;.X; CKMEM - ASK IF OK TO USE USER AREAX;'CKMEMQWARMST;;IF MEMOR=}Y WAS INTACTFCPTR1;;QUERY TO BOMB IT Q>4OK$>5OK;;PRINT PROMPT DSPLINQ>4CMSI;;PRINT CAUTION MSG/$>5CMSI;=};Y RESPONSE WILL INVALIDATE MEM.SAV  DSPLIN CHRGET&R> Y;;TEST FOR OK TO BOMB USER AREA(&HDDXT;;IF SAY NO THEN DON'=}T DO DUP2Q><*PWARMST;;TELL CART NO GOOD USER MEMORYF(PMEMFLG;;TELL LOADER NO GOOD MEM.SAVP CPTR1:ZX;dDDXT7;;PO=}P RETURN ADDRESSn7x$!MENUSL;;GOTO MENU, DON'T DO DUPX; DUPLICATE DISK ROUTINE ****X;X;)X; FMS equates neede<= $)2=IUamȳ؄ +7CO[R0}'s the old code: AWDQR>5NDOS *DAWDQR;;BRANCH IF HI BYTE LT DUP START R>5NMDUP & U?0 N>: V?;;COMPLEMENT CARR,} RAMLO>BUFADRRAMLO;;SAVE AREA FOR BUFFER ADDRESS USED BY USEPGMX;X; X; Equates within FMS:X; 'VTOCPT}RE;; Address of VTOC buffer*/MAXVTOC;; Maximum byte index w/ in VTOC4.ENTSTK ;; Stack pointer on entry to FMS>/}OS  hCALLRVTOC@r &ENTSTK| RDVTOC%>:CALLWVTOC@ &ENTSTK WRVTOC%>:X; DFDRV 1 %} X;SAVE #D2:DUPMISC.M65 AMISCELLANEOUS SUBROUTINESA%X; **** MISC. SUBROUTINES ****X;X;GETLINQ>CR$M}$>O.:CLRLINPLINE980B I:CLRLINLQ>VPPTR` PIPTRjPPERt CIOGET~ SCROL:X;X;X;3X; CIOGET -M} GET LINE OF INPUT FROM SCREEN EDITORX;CIOGETQ>GETRECPICCOM;;SCREEN EDIT IOCB Q>4LBUF PICBAL Q>5LBUF PM}ICBAHQ>P  PICBLLQ> PICBLH($>2( CIO;;READ RECORD FROM SCREEN EDITOR<%)>;;CHECK FOR BREAK ABORT STATUSFM} H:GETRTNP'"PER;;PARAM ERROR FLAG IS SET IF SOZ :GETRTN:dX;nX;x+X; CHRGET - GET 1 CHAR FROM EDITOR IN A.X;CM}HRGETQ>PPER%CHRG1 CIOGET;;GET A LINE FROM E:QICBLL;;SAVE CHAR COUNT PRCNT SCROLQPER$ICHRG2;;IF BRM}EAK, CLOSE AND EXIT CLOSX !MENUSL)CHRG2QRCNT;;EXPECT 1 OR 2 CHARACTERSR>GCHRG3;;IF OK Q>4OL $>5OL"M} DSPLIN,!CHRG1;;TRY AGAIN6CHRG3QLINE;;GET 1ST CHAR@:JT"OL APLEASE TYPE 1 LETTERA=CR|X;%X; PERX - EXIT IM}F PARAMETER ERRORSX; PERX*PER GPERX1: PERX177 !MENUSLX; D;;DUPLICATE FILE ONLY FOR DISK DEVICE FISDISK)!ODMS;;IF NOT -- SAY CANNOT DO & EXIT X;:ISDISK USEPGM;;ASKA} USER IF TO USE PROG AREA OR BUFFERX;(@X; HAVE USER INSERT SOURCE FILE AND HIT WHEN DONE2X;<*$>5ISD;;ARG:A} LINE TO BE DISPLAYED ADDRFQ>4ISD;;IN REG. A & XP$ DSPLIN;;PRINT INSERT SOURCE MSGZ( GETLIN;;GOTO SCREEN & WAIT FOR d% PERX;;GOTO MENU IF BREAK KEY HITnX;x- LOOKWC;;SEE IF FILE SPEC. USES WILDCARDS9HNOWC;;BRANCH IF NO WILD CARDS UA}SED - USE OLD ROUTINE&Q>@;;SET 'DUPLICATE WILDCARD' MODE/!WCINIT;;OPEN WILDCARD DIRECTORY FILE, ETC.X; NOWC XA};&X; MAKE SURE DEST NOT DOS.SYSX;/$>;;ENTRY-INDEX TO FIRST CHAR OF FILE NAME' TSTDOS;;WON'T RETURN IF IS DOA}S.SYSX;HX; OPEN SOURCE FILE - ADDR OF FILENAME STRING IN PARAM LIST IS)X; ALREADY ASSIGNED TO IOCB # 2A}X;WCDUPS$>;;USE IOCB #2Q>OPEN;;OPEN COMMAND" PICCOM9,Q>;;READ ONLY6 PICAX19@7 CIOCL;;CALL CIO - IF ERR PA}RNT MSG,CLOSE, GOTO MENUJX;TLX; EOFFLG - SOURCE FILE EOF FLAG FTRF - FLAG TO SHOW IF 1ST TIME SOURCE^X; FILE WAS READhA}X;rQ>|PEOFFLG;;CLEAR EOF FLAG!PFTRF;;CLEAR MEANS FIRST TIMEX;2X; DO UNTIL (SOURCE EOF FLAG (EOFFLG) IS SETA})GX; SET UP IOCB#2 TO DO GET CHAR. ZP LOC BUFADR HAS BUFFER ADDRESS X; BUFLEN HAS BUFFER LENGTHX;DODUP$>;;UA}SE IOCB #2QBUFADR;;IN LSB,MSB ORDER'PICBAL9;;SET BUFFER ADDR IN IOCB #2QBUFADR PICBAH9QBUFLEN;;IN LSB,MSA}B ORDER PICBLL9;;STORE BUFFER LENGTHQBUFLEN;;IN IOCB #2 PICBLH95Q>GETCHR;;COMMAND TO GET CHAR - IGNORE EOL'S A}(9B)& PICCOM90 CIO;;CALL CIO:X;DJX; CHECK FOR ENDFILE. IF YES, THEN SET FLG. CHECK FOR ERR. IF ERRN;X; TA}HEN PRINT MSG, CLOSE FILE, AND RETURN TO MENU.XX;b&IINSDES;;IF GOOD READ WRITE BUFFERl)>EOF;;WAS IT EOF?vFSETFLG;;YA}ES, THEN SET FLAG0!CIOER1;;WAS ERR - PRINT MSG,CLOSE,GOTO MENU$SETFLG"EOFFLG;;SET ENDFILE FLAGX;LX; WHEN GA}OOD READ OR EOF GET HERE. ASK USER TO INSERT DESTINATION;X; DISK AND ATTEMPT TO WRITE TO DESTINATION FILE.X;6A}INSDES$>5IDD;;ARG: ADDRESS OF LINE TO BE PRINTEDQ>4IDD;;IN REGS A AND X DSPLIN;;SAY TO SWAP DISKS$ GETLIN;;WAIT A}TIL USER HITS *PER;;WAS BREAK KEY HIT?IDODEST;;NO, TRY WRITE#!CLSSRC;;YES, CLOSE & GOTO MENUX; JX; CA}HECK IF FIRST TIME SRC WAS READ. IF YES, THEN OPEN FOR OUTPUT5X; ONLY. OTHERWISE, OPEN FOR OUTPUT APPEND. X;*+DOA}DEST$> ;;USE IOCB #3 FOR DESTINATION4%> ;;ASSUME APPEND>QFTRF;;IS FLAG CLEAR?H,HOPNDES;;NO,NOT FIRST TIME - OPEN APPA}ENDR %>;;YES, THEN OPEN OUT ONLY\/#FTRF;;SET TO SHOW NOT FIRST TIME NEXT TIMEfX;pOPNDESC;;GET OPEN TYPE CODEzPICA}AX19;;SET AUX1 BYTEQ>OPEN;;OPEN COMMAND PICCOM9X;FX; THE FILENAME IS THE FIRST FILE IN THE PARAMETER LIST-A}PAR.X;3Q>4PAR;;SET BUFR ADDR TO FILE SPEC TO BE OPENED %>5PAR3*WCFLAG;;IF WLDCARD-WLDCARD BUFR INSTEAD OF PAR JA}SKIPWCX; Q>4WCBUF2 %>5WCBUF2X; SKIPWCPICBAL9 C PICBAH9$ ( CIOCL;;CALL CIO, IF ERROR GOTO MENU. X;8 IXA}; CHECK IF SOURCE BUFR LEN IS NOT EQUAL TO ZERO. IF NOT = ZEROB 6X; THEN WRITE BUFFER TO THE DESTINATION FILE.L A}X;V %>;;SOURCE IS AT IOCB #2` $> ;;DEST IS AT IOCB #3j "Q>;;CHECK LENGTH LOW FOR ZEROt RICBLL8;;LOW=0~ !HDOWRIT;;NA}O THEN WRITE BUFFER RICBLH8;;IS HI=0? *FCLSDES;;YES, DON'T WRITE EMPTY BUFFER X; *DOWRITQ>PUTCHR;;PUT CHAR COMMAND A}CODE PICCOM9;;IGNORE EOLS (9B) QBUFADR;;GET BUFFER ADDRESS PICBAL9 QBUFADR PICBAH9 'QICBLL8;;GET BUFFER LA}ENGTH TO WRITE %PICBLL9;;FROM IOCB OF SOURCE FILE &QICBLH8;;SET BY GET TO ACTUAL BYTE #PICBLH9;;COUNT READ INTO BUFFER A} ' CIOCL;;DO WRITE - IF ERR GOTO MENU X; #X; CLOSE DESTINATION FILE( X;2 &CLSDESQ>CLOSE;;CLOSE COMMAND CODE< &PA}ICCOM9;;CALL CIO - IF ERROR GOTOF CIOCL;;MENU AFTER PRINT MSGP X;Z HX; TEST ENDFILE FLAG. IF IT IS SET THEN COMPA}LETED DUPLICATION.d =X; OTHERWISE, DO LOOP BODY AGAIN (READ THEN WRITE).n X;x "QEOFFLG;;IS SOURCE AT ENDFILE? HCLA}SSRC;;YES, THEN DONE X; GX; ASK USER TO INSERT SOURCE FOR NEXT READ & THEN REPEAT LOOP X; .$>5ISD;;ARGS: ADDREA}SS OF LINE TO PRINT IN Q>4ISD;;REGS A AND X ! DSPLIN;;SAY TO INSERT SOURCE $ GETLIN;;WAIT TIL USER HITS *PER;;A}WAS BREAK KEY HIT? #GCLSSRC;;YES, CLOSE & GOTO MENU !DODUP;;REPEAT LOOP X; ;;SOURCE AT IOCB #2, Q>CLOSE;;CLOSE COMA}MAND CODE6 PICCOM9@  CIO;;CALL CIOJ X;T .*WCFLAG;;TEST IF 'DUPLICATE WILDCARD' MODE^ 0JDUPFEX;;BR IF NOT 'DUPLICATE WIA}LDCARD' MODEh !$>5ISD;;INSERT SOURCE MESSAGEr Q>4ISD| 2 DSPLIN;;NEEDED TO GET NEXT WILDCARD DIR ENTRY  GETLIN;;WAIT FOA}R CR , PERX;;IF BREAK-KEY ABORT - EXIT TO MENU "!WCOPYL;;JUMP TO WILDCARD LOOP DUPFEX X; !MENUSL;;GO TO THE MENA}U  ?X; **** ASK IF OK TO USE PROGRAM AREA ROUTINE **** X; X; 4OK;;ARGS: IN A AND X ADDRX $>5OK;;OF LINE TO DISPLA}AYb DSPLIN;;ASK TO USE PGM AREAl "Q>4CMSI;;SAY A Y RESPONSE WILLv $>5CMSI;;INVALIDATE MEM.SAV  DSPLIN;;PRINT CAUTIONA}  CHRGET;;GET 1ST CHAR OF R> Y;;USERS RESPONSE HUSEBUF;;NO, THEN USE DBUFF X; *X;USE ALL MEMORY AVAILABLE-PROGRAM A}AREA 3X;MEMLO,MEMTOP,BUFADR,BUFLEN ARE IN LSB,MSB FORM X; $USEDB4Q>;;CLEAR WARMSTART FLAG "PWARMST;;TO SHOW PGM AREAA} USED 0PMEMFLG;;SHOW NO USER AREA GOOD-MEM.SAV ALSO Q>4NMDUP;;USE ALL AVAILABLE -PBUFADR;;MEMORY-FROM END OF DUP TO MEA}MTOP Q>5NMDUP;;BUFADR HAS BUFFER PBUFADR;;ADDRESS QMEMTOP;;GET LENGTH OF ;;;PGM AREA* S>4NMDUP4 PBUFLEN;;LSA}B,MSB ORDER> QMEMTOPH S>5NMDUPR PBUFLEN\ X;f IX; FIND THE GREATEST MULTIPLE OF 125 LESS THAN THE PROGRAM A}AREAp JX; THEN SET BUFR LEN TO IT. THIS PREVENTS FRAGMENTATION TO FILEz +X; WHEN APPEND IS USED IN DUPFIL. XA}; .Q>;;INIT MULTIPLE OF 125 (MLT125) TO ZERO PMLT125 PMLT125 X; &X; DO UNTIL (MLT125 > BUFLEN) X; .FA}INDGMQ>};;INC THE MULTIPLE OF 125 BY 125 %,;;TO GET THE NEXT HIGHER MULTIPLE OMLT125 PMLT125 Q> *OMLT125;;MLA}T125 IS IN LSB,MSB ORDERPMLT125X;1X; TEST FOR MLT125 > BUFLEN - LOOP TEST$X;.1QBUFLEN;;IS MSB OF MLA}T125 > MSB OF BUFLEN?8RMLT125BDGETMLT;;YES, THEN END LOOPL'HFINDGM;;IF MLT LSB BUFLEN?jEFINDGM;;NO, REPEAT LOOPt3X; A} ;ELSE END LOOP.~>X;********************** END OF LOOP***********************X;LX; CHECK IF MULTIPLE = TO 1A}25. IF IS, THEN LEAVE BUFLEN AS IS. IFEX; ISN'T THEN SET BUFLEN TO THAT NULTIPLE OF 125 MINUS 125.X;)GETMLTQA}MLT125;;IS MSB NOT = ZERO? HREPLAC;;YES, VALUE IS > 125Q>};;IS LSB > 125? RMLT125,DREPLAC;;YES, REPLACE BUFLEA}N WITH MLT125:;;ELSE LEAVE BUFLEN AS ISX;3REPLACQMLT125;;SUBTRACT 125 FROM MLT125 TO GET*;;;GREATEST MULTIPLE LESA}S THAN OR EQUAL S>};;TO THE PROGRAM AREA.)PBUFLEN;;USE IT AS THE BUFFER LENGTH.QMLT125(S>2PBUFLEN< :;A};RETURNFX;P8X;USE BUFFER DBUF (250 BYTES) INSTEAD OF PROGRAM AREAZX;dUSEBUFQ>4DBUF;;USE DBUF ASnPBUFADR;;BUFFER AA}DDRESSxQ>5DBUF;;IN LSB,MSB ORDERPBUFADRQ>4EDBL;;STORE DATAPBUFLEN;;BUFFER LENGTHQ>5EDBL;;=TO 256(100HEXA}) PBUFLEN;;IN LSB,MSB ORDER :;;RETURN=X; **** CHECK FILENAME FOR WILDCARD CHARACTERS ****X;X;JX;A} CHECKS THE STRING AT PAR,X FOR WLDCARD CHARACTERS (* OR ?). IFJX; THEY ARE FOUND THE ROUTINE SETS THE = FLAG. A}IF A IS FOUNDEX; RETURNS TO THE CALLING ROUTINE WITH THE EQUAL FLAG RESET.X;LOOKWCQPAR92"R> *, FLA}OOKW26R> ?@ FLOOKW2JR>CRT FLOOKW1^#R> ,;;TERMINATE WITH CR OR COMMAh HLOOKWCrX;| LOOKW12 LOOKW2:; DU@sXX;SAVE #D2:DUPTST.M65!ATEST FILE SPEC FOR DOS.SYSA+X; **** TEST FILE SPEC FOR DOS.SYS ****X;X;X; E} SUBROUTINE - TSTDOS$X;.GX; CHECKS A FILE SPEC IN THE STORAGE LOC FOR DOS.SYS. USED TO8JX; PREVENT COPYING TE}O A FILE NAMED DOS.SYS. IF DOS.SYS IS OPENEDB@X; OUTPUT FMS WILL WRITE A COPY OF DOS OUT TO THE FILE.LX;VGX; E} ENTRY - REG X HAS INDEX INTO PAR TO FIRST CHAR OF FILE SPEC`/X; ASSUMES COMPLETE FILE SPEC.jMX; EXIT E}- WILL NOT RETURN IF FILE NAME = DOS.SYS, BUT GOES TO MENU.tX;~)X; FIND END OF DEVICE ID - COLONX; TSTDOS2;;NEE}VER IS FIRST CHARQPAR9;;GET 2ND CHARR> :;;IS IT A COLON?,FGOTCOL;;YES, THEN NAME STARTS AT CHAR 3 2;;ELSE NAME STE}ARTS AT CHAR 4(GOTCOL2;;POINT AT FIRST CHAR OF NAMEX;1X; COMPARE FILE NAME IN PAR WITH DOS.SYSX;%%>;;INDE}EX INTO DOS.SYS FILE SPECX;*NXTCHARQDS8;;GET NEXT DOS.SYS CHAR $RPAR9;;TEST IF FILE NAME IS SAMEHNOTSAM;;NO, E}THEN RETURN3(2;;ELSE TRY NEXT CHAR2%)>;;ARE THERE MORE CHARS TO TRY?<HNXTCHAR;;YES, DO AGAINFX;P1X; FILE E}NAME EQUALS DOS.SYS - ERROR EXITZX;d.Q>4DCDS;;PRINT MSG - DEST CAN'T BE DOS.SYSn $>5DCDSx DSPLIN!MENUSL;;GOTO MEE}NUX;3X; NOT EQUAL TO DOS.SYS - RETURN TO CALLERX; NOTSAM:X;+DCDS ADESTINATION CANT BE DOS.SYSA=CR DzX;SAVE #D2:DUPSAVE.M65ASAVE A BINARY FILEA&X; **** SAVE FILE ROUTINE ****X;X;SAVFIL SFMG$Q>I}. PINITQ8 PRUNQB GETIC1LQOPTV5`$PTR;;PUT EOL ON FILENAMEjQ>CRt PPAR9~ GETNO;;GET HEX PARAMETEI}R PLDST &LDST(>5NMDUP *EDSLMFG;;BRANCH IF NOT SAVING DUP AREA "WDR1DSLMFG GETNO;;END ADDRESSI} PLDND &LDND; SLDST PWDRLA SLDST -EADDOK;;BR IF ENDING ADDR > THAN STARTING!MENUSL;;ELSE BAI}CK TO MENUADDOKPWDRH()>CR2%FNRUNAD;;BRANCH IF NO MORE PARAMS<$ GETNO;;GET A RUN ADDRESS IF ANYF PINITADP&I}INITADZLINITADd,FNINTAD;;BRANCH IF NO INIT ADDRESS GIVENn"INITQ;;SET FLAGxNINTAD)>CR+FNRUNAD;;BRANCH I}IF NO RUN ADDRESS GIVEN GETNO;;GET RUN ADDRESS PERX;;CHECK FOR ERRORS PRUNAD &RUNAD LRUNAD%FNRUNAD;I};BRANCH IF NO RUN ADDRESS"RUNQ;;SET FLAGNRUNADQ>POPT7;;OPTION CHAR FROM FILENAMER> A;;IF APPEND H:SI}VOPEN"OPT;;SET OT=$FFX;X; OPEN THE FILE"X;,:SVOPEN$>6 Q>OPEN@ PICCOM9J*OPT;;IF APPENDTG:ISAPPEND^I}Q>h H:SVO1r:ISAPPENDQ> |:SVO1PICAX19 CIOCLX;X; WRITE SAVE FILE HEADERX; Q>PUTCHR PICCOM9 Q>I}4SAVH PICBAL9 Q>5SAVH PICBAH9Q> PICBLL9Q> PICBLH9*OPT IWHEAD;;BRANCH IF NOT APPEND&Q>0 I}PICBLL9: Q>4LDSTD PICBAL9N Q>5LDSTX PICBAH9bWHEAD CIOCLlX;vX; WRITE DATA RECORDX; WDR$>+WDRLQ>;I};THIS IMMEDIATE VALUE MODIFIED PICBLL9+WDRHQ>;;THIS IMMEDIATE VALUE MODIFIED PICBLH9 #ICBLL9 H:WDRH1 #ICBI}LH9:WDRH1QLDST PICBAL9 QLDST PICBAH9 WEX!WDR1 3SFMG ASAVE-GIVE FILE,START,END(,INIT,RUN)A=CRG$Q>Hu TO IT IN IOCB1X;GETIC1 GETLINGETIC2$> PIOCB !GETFILX;&X;0/GETNAMEQ>;;ENTRY TO GETFIL USED BY RN}ENAME:)PCTR;;WHICH DOES NOT HAVE A DEVICE IDD"%PTR;;FOR THE SECOND FILE SPECN $IPTRX !CFTEbX;lX; SUBROUTINEN} - GETFILvLX; REMOVES ONE FILE SPECIFICATION FROM THE INPUT LINE. WILL SET UPJX; THE SPEC FOR DEFAULTS FOR INN}COMPLETE DRIVE ID. DEFAULT DRIVE #X; IS 1.X;X;!X;GET FILESPEC FROM INPUT LINEGETFIL%PTR $IPTRQ> N}PCTRX;,X;AVOID GETTING JUNK ON VERY SHORT PARAMSX; QLINE9R> ,  FADDCR>CR  FADDC* QLINE94R> ,N}>FGT1HR>CRRFGT1\Q> :;;LOOK FOR : IN FILESPECf4RLINE9;;SEE IF HAVE COMPLETE FILESPEC ALREADYp FCFTEz RLINEN}9HGT1"CTR QLINE9R> A)ICFTE;;HAVE X:FILE, COMPLETE FILESPECX;'X;IF FALLS THRU, IS UNIT:FILE, ADD DN}X; GT2Q> D PPAR83 ICFTE GT1"CTR "CTR $RLINE9;;AN UNLIKELY CASE (:FILE) FGT2;;TREAT FILE AS U:FILE$ "N}CTR. ADDCQ> D8 PPAR8B 3L Q> :V PPAR8` 3j CFTEQ>t POPT~ CFTE1QLINE9 PPAR8 2 3 R>CR;;LOOK FOR TERMN }INATOR FEOC R> , FEOC R> / FPOPT R> .;;LOOK FOR START OF .EXT HCFTE2 Q>;;FOUND, 4 MORE CHARS MAX PCTN }R CFTE2"CTR ICFTE1 X;( ,X;GETS HERE IF TOO MANY CHARS IN FILENAME2 X;< Q>4NTLF $>5NTLP  DSPLIN;;NAME TOO LONGN }Z ""PER;;SET PARAMETER ERROR FLAGd STEQLINE9;;SKIP TO ENDn 2x R> , FEOC R>CR HSTE EOC&IPTR 'PTR : N }POPTQLINE9 POPT 2 QLINE9 8PPAR8;;CHANGE STORED TERMINATOR TO , OR CR I HOPE 2 IEOC NTL ANAME TOO LONGAN }=CR, X;6 X; DSPMSG - DISPLAY N BYTES@ 4X; BUFFER POINTER AND LENGTH ARE ALREADY IN IOCB0J X;T DSPMSGQ>PUTCHR^ PICCOMN}h $>r X;| (CIO1 CIO;;CALL CIO AND GO TO MENUSL )>;;IF BREAK KEY ABORT H:CIO2 !MENUSL :CIO2: X; 'X; DSPLN}IN - DISPLAY ONE LINE OF TEXT X; A=LO,X=HI ADDRESS 0DSPLIN PRNTMSG;;USE RESIDENT DUP SUBROUTINE -!SCROL;;SCROLL N}SCREEN BELOW MENU & RETURN X; X; -X; SCROL - DO SCROLLING OF AREA BELOW MENU X; SCROLQ> > PICBLH9& Q> 0 PN}ICBLL9: Q>5ZAPD PICBAH9N Q>4ZAPX PICBAL9b !DSPMSGl v ZAP CUP=CUP=CUP=CUP=CUP  DLL=CDN=CDN=CDN=CDNN} X; $X; PIOCB - POINT IOCB AT PAR(PTR) X; PIOCBQ>4PAR , OPTR PICBAL9 Q>5PAR O> PICBAH9 : X; -XN}; CIOCL - CALL CIO AND PROCESS ANY ERRORS* X;4 CIOCL CIO;;CALL CIO> CH GCIOER1R :;;OK, RETURN\ CIOER1C;;ERROR STATUN}Sf CIOER;p &S>d;;ERROR NUMS ALWAYS ARE 1XX DECz $> 0;;CONVERT TENS CTNS2 ; S> ICTNS;;THE EASY (SLOW) WAY N}, O>  0;;CONVERT PEUN &ETN $>5CIE Q>4CIE CIEX DSPLIN  CLOSX;;CLOSE IOCBS 10,20 !MENUSLCIE AERN}ROR- 1A ETN  EUN $ CRLX;VX;`8X; GETNO - GET HEX NUMERIC PARAMETER FROM LINE(IPTR).j8X; RETURN A=N}LO, X=HI. PER SET MINUS IF ERROR.t"X; INC IPTR PAST PARAM.~X;GETNOQ>;;MAX NO DIGITSPCTRQ>PT1(N}PT1;;INIT TEMP TO BUILD NUMBER IN GHB$IPTRQLINE9;;GET CHAR #IPTRR>CR;;SEE IF TERMINATORFGNDR> ,FN}GND$ HEXCON;;CONVERT ASCII TO NIBBLE GERRX;;IF ERROR%>;;SHIFT T1,T1+1 BY 4 SHT1,( UT12UT1<1F ISHT1N}PLT1;;OR IN NEW NIBBLEZ PT1d"CTR;;COUNT DIGITn%IGHB;;LOOP UNLESS TOO MANY DIGITSx Q>4TMD $>5TMDERRX1N} DSPLIN"PER:GND? QT1$T1:"ERRXQ>4IHP;;INVALID HEX PARAM $>5IHP HERRX1TMD ATOO MANY DIGN}ITSA=CR,IHP AINVALID HEXADECIMAL PARAMETERA=CR@X;JX;TAX; HEXCON - CONVERT ASCII CHAR IN A TO HEX NIBBLE IN A. RETUN}RN^.X; MINUS CONDITION, A=FF IF ERROR.hX;r HEXCON;|S> 0GERRX2;;ASCII BELOW '0'R> GOKX;;0-9 CONVERN}TED SO EXIT; S> A 0 +R> ;;CONVERTED VALUE MUST BE 10 OR MOREGERRX2;;BETWEEN '9' AND 'A'R>GOKX;;A-F CON}NVERTED ERRX2Q>%OKXR>;;SET STATUS BY VALUE IN A:X;7X; GETDN - GET A DEVICE NUMBER FROM LINE(IPTR)XN }; RETURN IT IN AX;&*GETDN*PER;;SEE IF PARAM ERROR ALREADY0GGDR;;IF SO DON'T BOTHER: $IPTRDGETDQLINE9N2N!}XR> D;;IF DNbFGETD;;GO GET DIGITl;vS> 0;;CONVERT DIGITFBDS;;CAN'T BE ZEROGBDS;;IF NOT DIGITR> IBDS;;N"}TOO LARGE5GD1QLINE92R> ,FGDX;;IF TERMINATORR>CRHGD1;;KEEP LOOKINGGDX&IPTR;;ADVANCE POINTER7N#}GDR:  BDS"PER Q>4NDS;;NEED DEVICE SPEC MSG  $>5NDS* !DSPLIN4NDS ANEED D1 THRU D8A=CR9 @ORG 3> NMDUPN$} HLENNMDUPEDNpMLENNMDUPNDOSNEOUS SUBROUTINESA%X; **** MISC. SUBROUTINES ****X;X;GETLINQ>CR$L+X;$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X; X; Start of main DUP.SYS codeX;*@ALIGN DOS;; Check for dos org=$1540 &}Q>&POPT0 Q>4MNDUP: PDOSVECD Q>5MNDUPNPDOSVECXX;b1Q;; Check for Rev A and patch, if necessarylR>v '}H:NEWROM Q>4ISRBUGPINTRVEC Q>5ISRBUGPINTRVECX;X; Initialize file managerX;:NEWROM FMINIT (}444X;@ALIGN d+QWARMST;;ON COLDSTART, LOAD AUTORUN.SYS /HCKMDOS;;WARMSTART CHECK IF DUP WAS RUNNING )}NEWINIT :*X;4&X; Subroutine to load files at boot>X;HTRYLOADPICBALR &ICBAH\0 INITX;;CLEAR DUPFLG SHOW DU *}P NOT IN MEMORY.fQ>p0 STLOAD;;LOAD, INIT AND RUN THE AUTORUN FILEz0!CLOSX;;MAKE SURE IOCB #1 IS CLOSED & RETURNX; }TYPE Y TO STILL RUN DOSA=CR65ACREATE MEM.SAV FILEA(X; **** CREATE MEM.SAV FILE ****X;X;+X;ROUTINE WRITTEYD AWDQR:N X; *** End of unused code!X @ALIGN b X;l X;v JMPINT!@INITAD: JMPRUN!@RUNAD: X; X; MEMLDD .} X; WRITE MEMORY.SAVE TO DISK X; MCONT MWRITE;;WRITE FILE IMOUT MERR!CIOER1;;DISPLAY ERROR X; ,MEMSG AMEM2i} AF AD1:AUTORUN.SYSA=CR /NMSF ANEED MEM.SAV TO LOAD THIS FILE.A=CR ****X;X;5X; LOADS FROM THE FILE M`  `1  ɐ     `TU  L ? .  t`GV6}gs̄Ԅ߄  *5AMYeq}R1}ĄЄЄЄЄЄЄЄЄ(2(=(H(S(^(i(t((((R2}„΄΄  V2?VccV̄kwR3}h ?&2V^i)5@LXdR4} Ljtp|)p   H^itAHR5})|^|it)5pp'3>3HSS]jHR<}BJ ~DEHI B V0dVQDEHI VF9 ,0 ,V7}0 s0hhL  L` H hDHEhDEL8HI:V8}3 0 HI,0 0  9 .G VLO,0 L4*IJ`llD1:AUTORUN.SYSNEEDV9} MEM.SAV TO LOAD THIS FILE.;D1:MEM.SAV J y08 B|DEHI V0 0`B;DEL`?<0LVV:}rʆ v s? F0Ξ05: [ BDEHI VY8 B V  @  /V;}DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO STILL RUN DOSsn B;DE J VB}5܇5|^|iuu|| |||^|iu||t|| ||pR=}ptp d)܄ۄ  v ЄcR>}̄S̅ot̄5 +5H^i6t6)+5+@  H^i+R?}?I)chU@@pa'>m>x@mx]]MH^iR@}t)m*H)jUU^ ī̄Ī̅=RA}B' H^i΄ڇ)#   RM} (` 9 V⪍ ઍ  -LLu ÝDEHVC}ILV 9 .l 9 .l  `` s$B BHI|DE Vo BLV nB,DVD}E JLV B V BLVDEIʩ BꭝL   E: }DISK OPERATING SYSTEM II VERSION COPYRIVE}GHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDGE J. DUPLICATE DISKC. COPY FILE K. BINARY SAVVF}ED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRESSF. LOCK F !ILE N. CREATE MEM.SAVG. UNLOCK FVG}ILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N'#"&))9(&*)/h)''-&؆莟R'S VH} vL/ˢ L }Insert DOS 2.0s, type Y Λx DEfH!!I 1莏#q! @ y0ɛVS}***`X;jX;tX; CODE ALIGNMENT MACROS:~&X; (to test for 2.0s compatibility)X;"@ORG ;; BUMP ORG IF NECESSARY   J}@SPACE      @SPACE   ACODE ALIGNMENT!AX; /@ALIGN ;; ASSURE CODE IS ATK} PROPER ADDRESS   @SPACE  ( ACODE ALIGNMENT!A2<FX;P>D2:DUPEQU.M65Z>D2:DUPINIT.M65d>D2:DUL}PLOAD.M65n>D2:DUPMEMSV.M65x>D2:DUPSUB.M65X; .INCLUDE #D2:DUPSIO.M65>D2:DUPBUF.M65>D2:DUPCMD1.M65>j} #5@//w;;^it)0EdQd΄dUU>@XRN}X'[g[ HAH6t6^ i)g*H)am H^i)5* H)RO}*H)]^i YH r~k;  ƄƄRP}ƄЄل   ! + 5 ? H R [ c [ o z o  ̅  RQ}̅ ń w  ! - 8 C N Z f r } <pyya~ RR}̄   „ ^ i t   ] !  - - 8 DRY}8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT ITEM OR FOR MENU!"! 0 .z:VT}*{}.|{ 1 0 0JB 18L%|DL%DIRECTORY--SEARCH SPEC,LIST FILE?"#[# VU}0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BDED:}:1BJVV}|DE 1DEBHI 1 h0ߢ 0.  0?詛 VW}#k#1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPECl##COPY--FROM, TO?OPTION NOT ALVX}LOWED## COPYING---DN:#$l# 0|D .L/%###JB|DE 1BHID#E 1V_}΄  - a a 8 ā ̄ j  t ~ ?  ?  5  H ! RZ}? 5 ˄ 5 t̅  ~    8 ̄  qH  ' ' 8 HqHR[}^iƄ < H^i ^iMH ? Ft  P ? ? H F Z d Z dR\}Ƅ n n 5ƅ 8 ! F ? H 5Ƈ  x < P x x*H '̄ ̅ ̄ ̄ R]} Ą ~ ? 5   H^i  #MH tR^} ^ i / /*H /  : # : *H E Q ] E  Q ] h h Ѕ t  Re}#0: B 1L!#͑### B 1#c$0SYS1}:## # # .#Ƚ# # V`}𩛙## 1,#PD#EL$%J- <.BJD#E 1 1HH 0hh|DL%1}:̳# LVa}% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT ALLOWED IN DESTINATION 0 <.|KD2:DUPDEL.M65>D2:DUPCOPY.M65>D2:DUPCMDS.M65>D2:DUPDOS.M65>D2:DUPCMD2.M65>D2:DUPDUk}P.M65>D2:DUPFIL.M65>D2:DUPTST.M65>D2:DUPSAVE.M65>D2:DUPMISC.M65X; ENDDUP 'X;CHANGED FOR SYSTEM Rd w !*H) +*H) +]   L ! ~ eH Rm}   N}$0; EE 8 !NWN WHb^bi ̄Ru}BJD'EJL1WHICH DRIVE TO FORMAT?TYPE "Y" TO FORMAT DISK I'J'DL'8(:'U ' 1L!Vo} v_ \b \LNO CARTRIDGE' 70 2 0P vL RUN FROM WHAT ADDRESS?TYPE "Y" TO CREATE MEM.SAVVp}' y0Y s0 ( 1 L! FL1MEM.SAV FILE ALREADY EXISTS9(4)( 70 2 0 0+)') S)) 1 y0Yr( 1B*DVq})EJ 1 B 1 .{+)} 1 //3Hu ξL/L!DRIVE TO WRITE DOS FILES TVr}O?WRITING NEW DOS FILESTYPE "Y" TO WRITE DOS TO DRIVE .D1:DOS.SYS5)g)ERROR - NOT VERSION 2 FORMAT. t* 5) 1L!`Vs}h)*) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 0#B 1L!WHAT FILE TO LVt}OCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?* +DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO USE PROGRAM AREACAUTION: AV{}Ēb;̅kUva  8 akk IRv}vvIĒ }$  Ra Q̅̄  !' 85 Rw} ̅ C$$0 0888 8 !BKK 8 H0^0i *H UU0 ? Rx} ;ajat;w w ~B $̄K̅8̄0̄̅ $ 8 Ry} r ~  85 ̄̅ - ~ H ̄ 8 ~ Rz}H ̅.̄̄"̄7 ? ! H Z $0R} "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2 0.* 1 y0 V|}0)INSERT BOTH DISKS, TYPE RETURN^, 1 y03 +,8逍 N, 1L! ,C, t*  V}}Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0Ξ, 0 }, 1 y0CV~},ШC, 0K'!" H H 'h h Lx+!,B,EF 5L1L!D,I,Hh`D,V}- NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURN` V} `8 rL1`-* 1P* 1 y0Y`hhL!--NAME OF FILE TO MOVE?- 0 0|DL% <.,^ 1 70 V}0 + "9 +CLL 8 ! UL̄Caa 8 !U o o= [= [ [ o [ ojt~~ 8R} j   ?  H  !  aa 8 !R}  ? [ [# ;; 8 ! +; W# +7R} _ju   _ o oj ? H !u ? H !~̄ā ;̄ !R} H ? ? ! H ! + 8"" 8 !@ R}̄  ~ ɇ aa 8$    H ^i ct cR}AH) ;; 8$*   H & Є &^i t2>R}0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  JBV}|,#P#DE 1 HI BDEHHII 1 B-. 1 ,^ 1 70,0La- B V,#P,^ V}1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭ}V}`8}``|* ? ɛ,`.(/|:-)| / 1L!`DESTINATION CANT BE DOS.V}SYS)/$00 0H{ 24Δ 28/L!/) 2 Π 2 0 ξV}25H^مitt  >*H aa 8$߄ "*H) Jaa 8$ J R} : V 8"" 8 ! V@ه  c c z zb z z z z c znb c zbnR} zz zzz z c z c  c c  0R} 8 ̅ f ~ ?ڄ;;j t~R}~    ~~ H 5H^it!t^i! ,jtR}tt^iAڄ̅$ ? HW DWMH^i t) !pWt  DR}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVV}E FILE,STA%060RT,END(,INIT,RUN)7021O S0 1`BDEPHI V` S0H 1 V}L!0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥV}A"D|ݤD31.2|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`V}轤{NAME TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:2V}22 1 L!ERROR- 1/22ɛ+,' 20*.. өr2 1``2TOO MANY DV}{5 {  8p̄  ~$  R ? H ? H R R} R R  R R R R 8R} H ?ᄇ ̄ 5H) 8] D  Dti^ 脺 R} ?^ i )%%/8AAJ 85 A8/̄ R [ [T H H]]frR} MDEND   / MDEND;;SET END ADDR IN FMS PAST RES DUP SO >X; ;BUFFERS DON'T CLOBBER}| [ [| [ [ RT 8] [ [r̄̄f&0 HR}@ALIGN },CKMDOSQDUPFLG;;SEE IF DUP WAS IN MEMORYFINITX;;=ZERO THEN WASN'TX;0QMEMFLG;;SEE IF USER AREA WRI }RDVTOCT;; Routine to read vtoc from diskH-WRVTOC;; " " write " to "RX;. DKHNDS3,SECSIZ;; As^ IT. STAK2:DUPSUB.M65ARESIDENT SUBROUTINESA2X; **** SUBROUTINES FOR RESIDENT DUP ****X;X;6X; TTEN TO MEM.SAVFCLDSET;;=ZERO THEN WASN'T) LDMEM1;;ELSE GET USER MEMORY BACK INX;' RELDIN;;RELOAD SAVED DOSINI V }ECTOR$ INITX;;CLEAR DUP IN MEMORY FLAG WRMSTR;;REDO WARMSTARTX; $INITXQ>;;SAY DUP NOT IN MEMORY PDUPFLG;;CLE }AR FLAG :$ X;. (CLDSETPWARMST;;NO VALID USER MEMORY8 FINITX;;SET TO COLD START ****X;X;>X; INITIALIZATIOUECTION!@RAMLO:;;JUMP TO ROUTINE SELECTED BY MENU. RANGEQ>4NSI $>5NSI ! DSPLIN;;NO SUCH ITEM MESSAGE$ !MENUSL. 8"} NSI ANO SUCH ITEMA=CRB X;L GX;PROMPT FOR MENU SELECTION OR REDISPLAY MENU - RETURN IS IN INVERSEV X;` SIT ASELECT I"}TEM OR Aj  =ARETURNAt  A FOR MENUA=CR~ MNSLMENUSL**** DOS MENU ****X;X;DMENU CLSCR$( ADISK OPERAT =ʄӄ H 8>a 6) !pWt  DP]IGITSINVALID HEXADECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 TV}HRU D833L!ERROR- 1/22ɛ+,' 20*.. өr2 1``2TOO MANY DT