– - M àL é ý¬ X¬®ð c0¬±C)HÈCð±CH Mh¨hÝ©À h
¨`eC¨¥Di „C…DŒ`Œ
©Ry„H©PŒ©€Êð
®Ð®
à
* 1Œ ÆH0®èŠ¢@)Т€Ž Yäˆ0æ¦.Ș`ÿ[`ù#(PM RÒÒÒÒÒÒÒ\\b
Æ
Pg©i»©¼¢Ž ¶½Ë0 šð ¹%™ˆ÷½ËÉ@°¼Ã /ÊÐÕ ®Š™`ˆÐúîdç¬
¢ì Þè0˜øÈÊîŒèèèè½ðÉDÐô©D©Ô©LŒ ÿ <œ þþ‚èX;SAVE #D2:DUP.M65òAAºDISK UTILITY PROGRAMS (DUP) VER 3.0 for DOS 2.5 01/10/85AüX;X;'X;CHANGED FOR SYSTEM RES‚T -- DUPFLG,X;ADDED INTERRUPT ROUTINES FROM SIO -- KB$.X;ADDED SAVE/RESTORE OF DOSINI VECTOR -- KB./X;Modified this mess‚ ýfor DOS 2.5 -- 1/85 MER8X;BTX;*******************************************************************************L7X; ‚HIS IS FINAL VERSION OF DUP ---- 2.5 ----VSX;*****************************************************************************‚` ýX;jX;tX; CODE ALIGNMENT MACROS:~&X; (to test for 2.0s compatibility)ˆX;’"…@ORG ;; BUMP ORG IF NECESSARYœ
‚†@SPACE
°ºÄ
Ά@SPACE
Ø
ACODE ALIGNMENT!Aâìö X;
/‡@ALIGN ;; ASSURE CODE IS AT P‚OPER A ýDDRESS
†@SPACE
(
ACODE ALIGNMENT!A2<FX;P>D2:DUPEQU.M65Z>ŽD2:DUPINIT.M65d>ŽD2:DUPL‚AD.M65n>D2:DUPMEMSV.M65x>D2:DUPSUB.M65‚X; .INCLUDE #D2:DUPSIO.M65Œ>D2:DUPBUF.M65–>ŽD2:DUPCMD1.M65 >D2‚DUPDIR.M6 ý5ª>D2:DUPDEL.M65´>ŽD2:DUPCOPY.M65¾>ŽD2:DUPCMDS.M65È>D2:DUPDOS.M65Ò>ŽD2:DUPCMD2.M65Ü>D2:DUPDUP.‚65æ>D2:DUPFIL.M65ð>D2:DUPTST.M65ú>ŽD2:DUPSAVE.M65>ŽD2:DUPMISC.M65X;†ENDDUP
65–>ŽD2:DUPCMD1.M65 >D2‚DUPDIR.M6 Õþþ‚èX;SAVE #D2:DUPEQU.M65òA‡EQUATESAüX; **** EQUATES ****X;X;X;$ƒCIOVä.
…DKHNDSä3,†SECSIZ€;; Assu‚e 128 byte sectors only8†SETVBV\äB†SYSVBV_äL†XITVBVbäV†CIOINVnä`7†POKMSK;; Pokey interrupt mask (shadow ‚
ýor IRQEN)j-…IRQENÒ;; IRQ interrupt enable on pokeyt†MEMTOPå~
†BRKKEYˆ
†DOSVEC
’†DOSINI;;DOS INIT VECTOR‚
†WARMST¦
†LMARGNR°
†RMARGNSº†CARTSTú¿Ä3‡INTRVEC
;;INTERRUPT VECTOR LOC FOR SIO PATCHÎ
…MEMLOç؆SHFL‚Ký¾â†INITADâì
…RUNADàö
†ICHIDZ
†ICDNOZ!
†ICBALZ$
†ICBAHZ%
†ICIDNO.(
†MAXDEV!2†HATABS‚†USRDOS FƒFMS P†FMINITƒFMSàZ7†DRVBYT
;; Drive byte - tells which drives exist.dƒDOSƒFMS@n!†WRMSTR‚tä;;WAýRM START VECTORx?…BSIORr;;ENTRY POINT TO FMS DISK HANDLER USED BY DUP DISK‚X;Œ ‚CR›–…SPACE
ƒCUPª
ƒ‚DN´
ƒCLF¾
ƒCRTÈ
ƒDLLœÒ…CLSCR}Ü(ƒEOFˆ;;ENDFILE RETURN CODE FROM CIOæX;ðX;ú„OPEN…CLOSE
†‚UTCHR
ý
†GETCHR"
†GETREC,
†PUTREC 6
†RENAME @
†DELETE!J
†FORMATþO9ˆFORCEFMTý;; Forces sgl or dbl fo‚mat (aux1 is flag)T„LOCK#^
†UNLOCK$h0†STAREQS;;STATUS COMMAND TO DISK CONTROLLERrX;|…IOCB1†X;3†DVSTAT‚;;ADDRESS OýF STATUS INFO STORED BY OSšX;¤X;®ƒDCB ¸…DUNITƒDCB†DCOMNDƒDCB̆DSTATSƒDCBÖ†DBUFLOƒ‚CBà†DBUFHIƒDCBê„DSLOƒDCB
ô„DSHIƒDCBþX;„IOCB@…ICHID„IOCB …ICDNO„IOCB&…ICCOM„IOCB‚0…ICSTA„IOCýB:…ICBAL„IOCBD…ICBAH„IOCBN…ICBLL„IOCBX…ICBLH„IOCB b…ICAX1„IOCB
l…ICAX2„IOCB‚vX;€…SYSED Š…OWRIT”
†ORDWRTžX;¨X;²(X; **** ZERO PAGE VARIABLES ****¼X;ÆX;ÐÚ
†JMPTBLä‚…RAMLOî>†BUFAýDR…RAMLO;;SAVE AREA FOR BUFFER ADDRESS USED BY USEPGMøX;X;X; Equates within FMS:X; '‡VTOCPTR‚E;; Address of VTOC buffer*/‡MAXVTOC;; Maximum byte index w/ in VTOC4.†ENTSTK
;; Stack pointer on entry to FMS>/†R‚VTOCT;; Routine toý read vtoc from diskH-†WRVTOC”;; " " write " to "RX;Equates within FMS:X; '‡VTOCPTR‚E;; Address of VTOC buffer*/‡MAXVTOC;; Maximum byte index w/ in VTOC4.†ENTSTK
;; Stack pointer on entry to FMS>/†R‚VTOCT;; Routine to Fþþ‚
èX;SAVE #D2:DUPINIT.M65òA’DUP INITIALIZATIONAü$X; **** INIT CODE FOR DUP ****X;X;>X; INITIALIZATION ‚ODE FOR DUP - CALLS FMS INIT CODE.$0X; CALLED ON WARM START AND COLD START..X;8$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;B‚ýX;L$í;; Message for wrong DUP diskV1‰:WRONGDUP}=A™Need DOS2.5,type Y ÒÅÔÕÒÎA=‚CR`-…@ORG ;; Make sure there's en‚ugh roomjX;t$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;~X;ˆ,Ø;; ??? SPACE FOR ADDITIONAL INIT CODE’%‡NEWINITT†DRVBYT;; Disa‚le ýRAMDISKœV†DRVBYT¦Q>
1°
P…DFDRVºX;ÄX; Try to load "RAMDISK.COM"ÎX;Ø
Q>4†:RAMFNâ
$>5†:RAMFNì ‡TRYLOAD;; and ‚ry to loadöX; #Q>4‚AF;; Try to load AUTORUN.SYS
$>5‚AF!‡TRYLOADX;(†:RAMFNAD:RAMDISK.COMA=‚CR2X;<$X;;;;;;;;‚;;;;;;ý;;;;;;;;;;;;;;;;;FX;P0X; Code for PRINTMSG which checks for dup 2.5ZX;d†CHK2.5Q>LnR…DOSOS;; Check for DUP2.5‚H‡:NOT2.5‚ !„CIO1ŒX;–'‡:NOT2.5Q> ;; Set DUP not in memory P†DUPFLGªQ>4‰:WRONGDUP´$>5‰:WRONGDUP¾3 …WAITY;; Prin‚ message ýand wait to load 2.0 DUPÈ!‡:NOT2.5ÒX;Ü$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;æX;ð*X; Rev A SIO patch (a la Paul ‚aughton)úX;
†ISRBUGQ;
H…:BUG1!ê"
…:BUG1C,56!³ê@X;J$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;TX;^…@ORG ƒDOS‚
h‰ýCALLRVTOC@r&†ENTSTK| †RDVTOC†%>:š‰CALLWVTOC@¤&†ENTSTK® †WRVTOC¸%>Â:ÌX;Ö…DFDRV
1àX;‚$X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ôX;þ X; Start of main DUP.SYS codeX;*‡@ALIGN ƒDOS;; Check for dos org=$1540Q>‚ &PƒOPT0Q>4ý…MNDUP:P†DOSVECDQ>5…MNDUPNP†DOSVECXX;b1Qœê;; Check for Rev A and patch, if necessarylR>vH‡‚NEWROM€
Q>4†ISRBUGŠP‡INTRVEC”
Q>5†ISRBUGžP‡INTRVEC¨X;²X; Initialize file manager¼X;Ƈ:NEWROM †FMINITÐ4‚4ä4îX;ø‡@ýALIGN d+Q†WARMST;;ON COLDSTART, LOAD AUTORUN.SYS/H†CKMDOS;;WARMSTART CHECK IF DUP WAS RUNNING ‡NE‚INIT :*X;4&X; Subroutine to load files at boot>X;H‡TRYLOADP…ICBALR
&…ICBAH\0 …INITX;;CLEAR DUPFLG SHOW DUP ‚OT IN MEMORY.fQ>Àpý0 †STLOAD;;LOAD, INIT AND RUN THE AUTORUN FILEz0!…CLOSX;;MAKE SURE IOCB #1 IS CLOSED & RETURN„X;Ž‚‡@ALIGN }˜,†CKMDOSQ†DUPFLG;;SEE IF DUP WAS IN MEMORY¢F…INITX;;=ZERO THEN WASN'T¬X;¶0Q†MEMFLG;;SEE IF USER AREA WRITT‚N TO MEM.SAVÀF†CLDSET;ý;=ZERO THEN WASN'TÊ) †LDMEM1;;ELSE GET USER MEMORY BACK INÔX;Þ' †RELDIN;;RELOAD SAVED DOSINI VEC‚ORè$ …INITX;;CLEAR DUP IN MEMORY FLAGò †WRMSTR;;REDO WARMSTARTüX; $…INITXQ> ;;SAY DUP NOT IN MEMORY P†DUPFLG;;CLEAR‚FLAG :$ X;. (†CLDSETP†WAýRMST;;NO VALID USER MEMORY8 F…INITX;;SET TO COLD STARTK INÔX;Þ' †RELDIN;;RELOAD SAVED DOSINI VEC‚ORè$ …INITX;;CLEAR DUP IN MEMORY FLAGò †WRMSTR;;REDO WARMSTARTüX; $…INITXQ> ;;SAY DUP NOT IN MEMORY P†DUPFLG;;CLEAR‚FLAG :$ X;. (†CLDSETP†WA 7þþ‚èX;SAVE #D2:DUPLOAD.M65òAŽLOADER ROUTINEAü!X; **** LOADER ROUTINE ****X;X;5X; LOADS FROM THE FILE (M‚ST 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‡@ALI‚N t.†DUPFLG ;;FLAG -IF DUP IN MEMORY NOT ZERO~/ƒOPT ;;HOLDS VALUE OF OPTION GIVEN BY USERˆ>†LOADFG ;;FLAG = $80 ‚F MýEMORY FILE DOESN'T HAVE TO BE LO’…HDBUFœ†SFLOADQ>€¦†STLOADP†LOADFG°„LOADQ>4ƒRTSº
P…RUNADÄ
Q>5ƒRTSÎ-P…RUNAD‚;;MAKE RUN AT EOF DEFAULT TO RTSØ$>â
Q>„OPENìP…ICCOM9öQ>;;OPEN TYPE=INPUT P…ICAX19
†CIOOPN;;TRY TO OPEN FI‚EI„ ýRDLF;;CONT IF OKQ>;;OPEN ERRORS(H„CLFX;;CLOSE AND EXIT2„RDLF$><Q>4„DBUFFP…ICBAL9PQ>5„DBUFZP…ICBAH9d‚Q>nP…ICBLL9xQ> ‚P…ICBLH9Œ&P†MEMLDD;;CLEAR MEM.SAV LOADED FLAG–Q>†GETCHR P…ICCOM9ª ƒCIO´G„ERST;;IF ERRS¾‚>ÿÈ$R„D!ýBUF;;CHECK FOR VALID LOAD FILEÒ H„LNLFÜR„DBUFæ$H„LNLF;;BRANCH IF NOT A LOAD FILEð
…RDDRC$>úQ>4…HDBUF‚…ICBAL9Q>5…HDBUFP…ICBAH9"Q>,†RDDRC1P…ICBLL96Q> @P…ICBLH9J) ƒCIO;;NO ERROR CHECK SO CAN CATCH EOFTI„STOK;‚IF NO ERROR^"ý)>ˆ;;SEE IF EOFhH„ERST;;IF SOME ERROR STATUSrX;|X;EOF SO DONE, EXIT†X; …CLOSX;;CLOSE IOCB'S 1 AND ‚š*ƒOPT¤"G„DRUN;;BRANCH IF NO RUN OPTION®$ †JMPRUN;;JUMP THROUGH RUN VECTOR¸„DRUNQ> ;;OK STATUS *†LOADFG;;WAS MEMORY‚SWAPPED?ÌP†LO#ýADFGÖ*G„CLFX;;BRANCH IF MEMORY WASN'T SWAPPEDà) †MEMSVQ;;DOES MEMORY SAVE FILE EXIST?êG…DRUN1;;BRANCH IF ‚OTô7þ7&!„GOOD;;WRITE MEMORY AND RELOAD DUPX;MX; SEE IF DUP WRITTEN OVER. IF IS RELOAD & TELL USER NEED MEM.‚AV TO&X; L$ýOAD THIS FILE.0X;:'…DRUN1Q†DUPFLG;;SEE IF DUP CLOBBEREDDH…DRUN2;;NO, THEN RETURNN(Q>4„NMSF;;ELSE TEL‚ USER NEED MEM.SAVX$>5„NMSFb ‡PRNTMSG;;PRINT MSGl!…RRDUP;;RELOAD & RUN DUPvX;€%X; RETURN TO CALLING ROUTINEŠ‚X;”$…DRUN2Q> ;;NO D%ýUP ERR MSG ON EOFž „CLFX>¨ƒRTS:²X;¼X; ERROR RETURNSÆX;ЄLNLF …CLOSXÚQ>;;BAD LOAD F‚LEä H„CLFXî „ERSTCø5
…CLOSX7? H„CLFX*X;4>X; CONTINUE WITH LOAD - CHECK LOAD ADDRESS FOR HEADER>2X; ‚ HEADER IF HAVE CONC&ýATENATED LOAD FILESHX;R„STOK$>\Q…HDBUF;;MOVE PARAMS TO IOCBfP…ICBAL9p5z
Q…HDBUF„P…‚CBAH9Ž?˜7¢3;;WAS ADDRESS FF?¬H„ADOK;;BRANCH IF NOT¶?À3;;OTHER BYTE FF?ÊH„ADOK;;BRANCH IF NOTÔX;ÞOX; H‚VE A HEADER & START ADDRESS'ý - GET END ADDRESS FOR TEXT & DO AGAINèX;ò
Q…HDBUFü
P…HDBUF
Q…HDBUF P…HDBUF;;MOV‚ LOAD ADDRESS Q>4…HDBUF$ P…ICBAL9. Q>5…HDBUF 8
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~ ‚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 w‚s shorter,œ 0X; filler was requi)ýred (The new version also¦ X; works!).° X;º „ADOKQ…HDBUFÄ ;Î
S…HDBUFØ P…ICBLL9â
‚…HDBUFì
S…HDBUFö P…ICBLH9
Q…HDBUF
*R>5…NMDUP ;; IS BEGINNING PAST DUP?
4
E„ANWD;; BRANCH IF SO(
Q…HDB‚F2
R>5„NDOS;; IS END BELOW DUP?<*ý
4F
EƒAWD;;BRANCH IF NOTP
X;Z
8X; SINCE TEXT IN DUP, LOAD MEM.SAV IF NECCESARYd‚X;n
„ANWDQ†MEMLDDx
*GƒAWD;;BRANCH IF MEM.SAV ALREADY LOADED‚
Q>€Œ
L†LOADFG–
7P†LOADFG;;SET MEM.SAV DOESN'T HAVE TO BE L‚ADED FLAG
ƒAWD#…ICBLL9ª
H…:AWD1´
#…+ýICBLH9¾
0…:AWD1*†LOADFG;;DOES MEMORY HAVE TO BE LOADEDÈ
GƒDLM;;BRANCH IF NOTÒ
(Q†MEM‚DD;;WAS MEM.SAV ALREADY LOADED?Ü
GƒDLM;;BRANCH IF SOæ
"†MEMLDDð
- …LDMEM;;LOAD MEM.SAVE FILE (IF IT EXISTS)ú
)Q> ;;SHOW U‚ER AREA NOT DUP IN MEMORYP†DUPFLG1 †R,ýELDIN;;RESTORE DOS IN VECTOR FROM SAVED LOCX;"EX; SET NO INIT ADDR DEFAU‚T THEN READ IN TEXT & ATTEMPT INIT,X;6ƒDLM$>@
Q>4ƒRTSJP†INITADT
Q>5ƒRTS^'P†INITAD;;INIT DEFAULTS TO AN RTSh& ‚CIO;;READ DATA DIRECTLY TO MEMORYr I„DLM1|-ý!„ERST;;IF ERRORS†
„DLM1*ƒOPT"G…DINIT;;BRANCH IF NO GO OPTIONš †JMPINT;;DO‚INIT¤/…DINIT!…RDDRC;;GET NEXT SECTION OF LOAD FILE®X;¸2X; *** A subroutine existed here in DOS 2.0s toÂ3X; supposedly ‚heck for a load file overwritingÌ0X; DUP.SYS. .ý It didn't work properly, so theÖ1X; code was rewritten without the subrou‚ine.à/X; The final result used less code than theêX; original!ôX;þBX; But we must fill up the old space... so here's‚the old code:„AWDQR>5„NDOS*D…AWDQR;;BRANCH IF /ýHI BYTE LT DUP STARTR>5…NMDUP &U?0N>:V?;;COMPLEMENT CARRYD‚
…AWDQR:NX; *** End of unused code!X‡@ALIGN bX;lX;v†JMPINT!@†INITAD:€†JMPRUN!@…RUNAD:ŠX;”X;ž
†MEMLDD ‚‚AFAŽD1:AUTORUN.SYSA=‚CR²/„NMSFAŸNEED MEM.SAV TO 0ýLOAD THIS FILE.A=‚CRR>5…NMDUP &U?0N>:V?;;COMPLEMENT CARRYD‚
…AWDQR:NX; *** End of unused code!X‡@ALIGN bX;lX;v†JMPINT!@†INITAD:€†JMPRUN!@…RUNAD:ŠX;”X;ž
†MEMLDD ‚‚AFAŽD1:AUTORUN.SYSA=‚CR²/„NMSFAŸNEED MEM.SAV TO þþ‚
èX;SAVE #D2:DUPMEMSV.M65òA“CREATE MEM.SAV FILEAü(X; **** CREATE MEM.SAV FILE ****X;X;+X;ROUTINE WRITTEN ‚Y M.E., APRIL 21,1980$…OWRIT;;º
P…ICAX19;;Ä …OREST;;OPEN FOR WRITEÎ%G…ERRWR;;IF ERROR THEN JMP AND RETØX;âX‚ìX;WRITE MEMORY BLOCKöX; Q>†PUTCHR
P…ICCOM9)Q>4„NDOS;;STORE START OF BLOCK FOR CIOP…ICBAL9(Q>5„NDOS;;START AD‚R (HIG4ýH)2P…ICBAH9<!Q>4„MLEN ;;LENGTH OF BLOCKFP…ICBLL9PQ>5„MLEN;;LENGTH(HIGH)ZP…ICBLH9d ƒCIO;;WRITE DATA BLOC‚n#G…ERRWR;;IF WRITE ERROR THEN JMPx
…CLOSX‚
G…ERRWRŒ%> –ƒRET: X;ª…ORESTQ>4„OPEN´P…ICCOM9¾7Q>4„NAME;;ROUTINE ‚O COMPLET5ýE OPEN OF 'D1:MEMORY.SAVÈ3P…ICBAL9;;CALLING SUB SUPPLIES 'READ' OR 'WRITE'ÒQ>5„NAME;;IN ICAX1ÜP…ICBAH9æ!†CIO‚PNðX;ú%…ERRWR:;; Return with error statusûX;ü=†CIOOPNQ…DFDRV;; Set default drive for MEM.SAV and DUP.SYSý
PˆMEMSVDRVþ‚P†DUPDRVÿ6ý!ƒCIO X;@J0X; **** ENTRY POINT ON 'DOS' CALL ****TX;^X;c
…@ORG œh%†INISAV
;;DOSINI VECTO‚ SAVE LOCr
†MEMFLG |
…MNDUP$> †&†MEMFLG&†LOADFGš0¤&†WARMST® †INITIO¸X;Â/ †MEMSVQ;;FIND OUT IF FILE D1:MEM‚SAV EXISTSÌ'I„7ýGOOD;;BRANCH IF MEM.SAV FILE EXITSÖQ> à"P†WARMST;;CLEAR WARM START FLAGê
F…FINALôX;þX;,„GOOD †MWRI‚E;;WRITE USER AREA TO MEM.SAV
G…ERROR "†MEMFLG;;SHOW MEMORY WRITTEN&
G…FINAL0X;:,…ERRORQ>4†ERRMES;;PRINT ERROR OCCUR‚D MSGD
$>5†ERRMES8ýN ‡PRNTMSG;;GOTO MSG PRINTERXX;b"Q>4ƒERR;;PRINT QUERY TO RUN DOSl
$>5ƒERRq,…WAITY
;; Print message‚and wait for 'Y'v ‡PRNTMSG;;GOTO MSG PRINTER€X;Š!X; WAIT FOR Y TO RUN DOS”X;žQ>†GETREC¨
P…ICCOM²Q>4„STAK¼‚P…ICBALÆQ>5„STAKÐ
9ýP…ICBAHÚQ>ä
P…ICBLLîQ> ø
P…ICBLH ƒCIOQ„STAK;;SEE IF Y TYPEDR>
Y H†RTCART;;BRANCH IF‚NOT*Q> 4P†WARMST>X;H
…FINAL$> RQ>…CLOSE\!P…ICCOM9;;SET UP CLOSE COMMANDf ƒCIO;;PERFORM CLOSE COMMANDpX;z'…R‚DUPQ†DOSINI;;SAVE DOS IN:ýIT VECTOR„P†INISAVŽQ†DOSINI˜P†INISAV¢X;¬#Q>4ƒDOS;;SET UP DUP INIT ADDR AS¶P†DOSINI;‚DOS INIT VECTORÀ
Q>5ƒDOSÊP†DOSINIÔX;Þ†RRDUP1Q>4†DUPSYSè$>òP…ICBAL9ü
Q>5†DUPSYS P…ICBAH9 %> ''ƒOPT;;A‚SURE NO /N OPTION IN EFFECT;ý$ 1;;SHOW THAT DUP IS IN MEMORY. '†DUPFLG8 $ †SFLOAD;;LOAD DUP.SYS AND RUN ITB †RTCART:L ‚EC‚‚E:A=‚CR’ †DUPSYSAŠD1:DUP.SYSA=‚CR— †DUPDRV†DUPSYSœ X;¦ 2†ERRMESA ERROR-SAVING USER MEMORY ON DISKA=‚CR° &ƒERRA—TY‚E Y TO STILL RUN DOSA=‚CRFFECT øþþ‚èX;SAVE #D2:DUPSUB.M65òA”RESIDENT SUBROUTINESAü2X; **** SUBROUTINES FOR RESIDENT DUP ****X;X;6X; ‚OUTINE TESTS IF MEM.SAV IS PRESENT ON THE$(X; RETURNS - MINUS IF NOT THERE./X; PLUS IF MEM.SAV IS T‚=ýERE8X;=
…@ORG sB"†MEMSVQ †CLOS20;;CLOSE IOCB # 2L
Q>„OPENVP…ICCOM9`Q>4„NAMEjP…ICBAL9tQ>5„NAME~P…ICBAH9ˆQ‚†ORDWRT’2P…ICAX19;;TRY TO OPEN D1:MEM.SAV FOR READ/WRITEœ †CIOOPN¦6;;SAVE STATUS° †CLOS20;;CLOSE MEM.SAVº8;;RESTORE‚STA>ýTUSÄ:ÎX;ØX;âGX; SAVE FILE SUBROUTINE - WRITE FILE BODY, INIT, & RUN VECTORSìX;ö+„WDR1Q> ;;THIS IMMEDIATE‚VALUE MODIFIED 2F„WDR2;;BR IF MEM FILE DOESNT HAVE TO BE LOADED
…LDMEM„WDR2$>& ƒCIO;;DO SAVE - WRITE BODY TO DISK‚3…INI?ýTQQ> ;;THIS IMMED VALUE CHANGED DURING SAVE22F„RUNQ;;SET TO FF WHEN AN INIT VECTOR IS PRESNT<
#…INITQFQ†INITAD‚+P…VECTR;;IF INIT VECTOR FOR FILE SAVE ITZQ†INITADd
P…VECTRn
Q>4†INITADx>‚ P„LDSTŒ
Q>5†INITAD–
…WRVEC +„RU‚QQ> ;;TH@ýIS IMMEDIATE VALUE MODIFIEDª3F†NORNAD;;SET TO FF WHEN A RUN VECTOR IS PRESENT´#„RUNQ¾
Q…RUNADÈ*P…VECTR;;IF ‚UN VECTOR FOR FILE SAVE ITÒ
Q…RUNADÜ
P…VECTRæQ>4…RUNADð>ú P„LDSTQ>5…RUNAD
…WRVEC#†NORNAD …CLOSX;;CLOSE ‚OCBS 1 &2"AýQ†MEMFLG,M„WDR16F†DRRDUP@/#„WDR1;;RESET MEM.NEEDS TO BE LOADED FLAGJ!†RRDUP1;;RELOAD & RUN DUPT)†D‚RDUP!…DOSOS;;RUN THE SWAPPED IN DUP^X;hX;rX;|…WRVECP„LDST†2 &„LDNDšP„LDND¤$>®Q>4„LDST¸P…ICBAL9‚Q>5„LDSTÌP…ICBýBAH9ÖQ>àP…ICBLL9êQ> ôP…ICBLH9þ#!ƒCIO;;WRITE INIT OR RUN ADDRESSX;X;X; JUMP TO CART‚IDGE&X;0†CLMJMP …LDMEM:%Q> ;;SHOW DUP NO LONGER IN MEMORYDP†DUPFLGN* †RELDIN;;RESTORE DOS INIT VECTOR SAVEDX !@†CA‚TST:;;JUMP TO CARTCýRIDGEbX;lX;v=X; LOAD MEM.SAV (IF IT EXISTS) BEFORE RUN AT ADDRESS€X;Š+„LMTR …LDMEM;;LOAD MEM‚SAVE IF IT EXISTS”*Q> ;;SHOW THAT DUP NO LONGER IN MEMORYžP†DUPFLG¨* †RELDIN;;RESTORE DOS INIT VECTOR SAVED²!@…RAMLO:‚;RUN AT ADDRESS¼X;ÆDý5X; RESTORE DOSINI VECTOR FROM SAVED LOCATIONÐX;Ú†RELDINQ†INISAVäP†DOSINIîQ†INISAVø‚†DOSINI:X;X; X; SUBROUTINE - LDMEM*%X; LOAD MEM.SAV IF IT EXISTS4X;>…LDMEMQ†MEMFLGH'H†LDMEM1‚;BRANCH IF MEMORY WAS SAEýVEDR:\†LDMEM1 †MEMSVQf.I†LDMEM2;;BRANCH IF MEM.SAV FILE DOES EXISTp%Q> ;;TELL CART PGM AREA C‚OBBEREDzP†WARMST„"F…CLOS2;;GO CLOSE AND GOTO CARTŽX;˜†LDMEM2Q>„OPEN¢P…ICCOM9¬ †CIOOPN;;REOPEN MEM.SAV¶Q>†GETCHR‚P…ICCOM9ÊQ>4„MLEN ÔFýP…ICBLL9ÞQ>5„MLENèP…ICBLH9òQ>4„NDOSüP…ICBAL9 Q>5„NDOS P…ICBAH9 ƒCIO$ …CLOS2Q>…C‚OSE. P…ICCOM98 !ƒCIO;;CLOSE MEM.SAVB X;L ;X; CLOSE ALL IOCBS & RE-OPEN ZERO AS SCREEN EDITORV X;` 2†INITIO †CIOINV‚;THIS ROUTINE CLOSES ALL IOCB'GýSj #;THEN REOPENS THE SCREEN EDITORt $> ~
Q>„OPENˆ P…ICCOM9’ Q>4‚ECœ P…ICBAL9¦ Q>5‚EC°‚P…ICBAH9º Q>†ORDWRTÄ P…ICAX19Î !ƒCIOØ X;â X; CLOSX - CLOSE IOCBS 10,20ì X;ö …CLOSXQ>…CLOSE
$>
P…ICCOM9
ƒCI‚
X;(
(X; ENTRY TO CLOSE IHýOCB # 2 ONLY2
X;<
†CLOS20$> F
Q>…CLOSEP
P…ICCOM9Z
†:GOCIO!ƒCIOd
X;n
X; SUBROU‚INE - PRNTMSGx
KX; PUTS A CHARACTER STRING TERMINATED BY A CARRIAGE RETURN CHAR TO‚
X; SCREEN EDITOR.Œ
X;–
0X;‚ ENTRY - REG A : LOW BYTE MSG AIýDDRESS
/X; REG X : HI BYTE MSG ADDRESSª
X;´
=X; PUT PARAMS IN IOCB‚- USE IOCB 0 FOR SCREEN EDITOR¾
X;È
2‡PRNTMSGP…ICBAL;;SET MSG ADDR IN IOCB BUFF ADDRÒ
&…ICBAHÜ
X;æ
X; SET UP REST ‚F IOCBð
X;ú
$>;;SET IN BUFFER LENGTJýH!&…ICBLH;;ASSUME 256+ BYTES MAX0"Q>†PUTREC;;PUT MSG,
P…ICCOM14246X;@I‚; TEST IF DUP IS RESIDENT - IF IS THEN USE INDIRECT CIO ROUTINEJ'X; TO TEST FOR BREAK KEY ABORTTX;^1Q†DUPFLG‚;=ZERO IF NON-RESIDENT DUP NOT IN MEMh1F†Ký:GOCIO;;IN MEMORY THEN USE INDIRECT CIO CALLm‡@ALIGN ¾r?ˆOLDPRMSG!†CHK2.5;; ‚o to insure that dup.sys is version 2.5|X;†X;„SAVHÿ=ÿš„LDST¤„LDND®…VECTR¸X;Â,X; Allow for 3 VTOC‚buffers of 144 bytes.Ì)X; (128 bytes plus 3 LýVTOCs w/ 16 bytesÖ(X; extra data in comparison to 2.0s)à…@ORG |€‚…MDEND
ôþ/ …MDEND;;SET END ADDR IN FMS PAST RES DUP SO>X; ;BUFFERS DON'T CLOBBER I‚.„STAK 144 bytes.Ì)X; (128 bytes plus 3 Úþþ‚èX;SAVE #D2:DUPSIO.M65òAREV A SIO PATCHAü4X; **** SIO INTERRUPT SERVICE ROUTINES ****X;X;9X; EQU‚TES FOR INTERRUPT ROUTINES MOVED FROM SIO$X;.X; ZERO PAGE8X;B1†BUFRLO2;;POINTER TO BYTE TO SEND OR RECEIVEL
‚NýBUFRHI3V2†BFENLO4;;POINTER TO BYTE AFTER END OF BUFFER`
†BFENHI5j/†CHKSUM1;;LOC TO STORE DATA FRAME CHECKSUMt+†C‚KSNT;;;CHECKSUM SENT FLAG- =FF SENT~8†NOCKSM<;;FLAG NO CHECK SUM TO BE RECEIVED-NOT ZEROˆ/†STATUS0;;HOLD FOR STATUS ‚O BOýE PUT IN DCB’0†BUFRFL8;;FLAG-IF FF RECEIVE BUFFER IS FULLœ7†RECVDN9;;FLAG RECEIVE NOT DONE. USED BY WAIT LOOP¦4†PO‚MSK;;POKEY INTERRUPT MASK SHADOW FOR IRQEN°X;º=X; HARDWARE REGISTERS USED IN SIO INTERRUPT ROUTINESÄX;Î0…SKRE‚
Ò;;PýSERIAL PORT STATUS RESET ON POKEYØ&†SEROUT
Ò;;SERIAL OUTPUT REGISTERâ1…SERIN†SEROUT;;SERIAL PORT INPUT REG ON POK‚Yì,…IRQENÒ;;IRQ INTERRUPT ENABLE ON POKEYö/†SKSTATÒ;;SERIAL PORT STATUS REG ON POKEY X;
'X; ERROR CODES RET‚RNED BY SQýIOX;%†FRMERRŒ;;FRAMING ERROR ON INPUT(3†OVRRUNŽ;;DATA FRAME OVER RUN-BIT D5 IN SKSTAT2(†CHKERR;;DATA ‚RAME CHECKSUM ERROR<FHX; **** INTERRUPT SERVICE ROUTINE TO OUTPUT DATA NEEDED ****PX;ZX;dX;n@X; IT‚UPDATES THE Rý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 WHENŒKX; PTR EQUALS THE END OF BUFFER PTR (POINTS TO ‚YTE AFTER BUFFESýR).–JX; RETURNS TO THIS ROUTINE AFTER CHECKSUM PASSED AND RESETS POKEY IX; INTERRUPT REG TO HAV‚ THE TRANSMIT DONE ROUTINE CALLED TO ENDª(X; WAIT LOOP (SEE SIO LISTING).´X;¾X; K.B. 6/10/80ÈX;Ò †ISRODN‚;;SAVE Y REG ON STTýACKÜ5æX;ð#†BUFRLOú'H†NOWRP0;;INCREMENT PTR TO NEXT BYTE#†BUFRHI;;TO SENDX;,X; PATCH T‚ ROUTINE - CHANGED CHECK"X;,1†NOWRP0Q†BUFRLO;;CHECK IF PTR IS WITHIN BUFFER6+R†BFENLO;;DO A DOUBLE PRECISION SUBTRACT@‚†BUFRHIJS†BFENHIT3UýD†NOTEND;;BRANCH IF (BUFR) < (BFEN)-MORE TO SEND^X;h*Q†CHKSNT;;TEST IF CHECKSUM ALREADY SENTr#H†REL‚NE;;BRANCH IF ALREADY SENT|X;†&X; SEND CHECKSUM AND SET FLAGX;šQ†CHKSUM¤+P†SEROUT;;PUT CHECKSUM IN SERIAL OUT‚REG®"†CHKSNT;;SET FLAGVý TO FF HEX¸H†CHKDON;;RETURNÂX;ÌJX; AFTER CHECKSUM SENT AND CAUSE NEXT INTERRUPT THEN CHAN‚E POKEYÖKX; MASK TO ENABLE TRANSMIT DONE INTERRUPT AND TERMINATE WAIT LOOP.àX;ê"†RELONEQ†POKMSK;;GET POKEY MASKô‚>;;OR IN ENABLEþP†POKMSWýK!P…IRQEN;;ENABLE THE INTERRUPTSX;#X; RESTORE REGS AND RETURN&X;0†CHKDON7:?;;R‚STORE Y REGD57;;RESTORE A REG SAVED IN OS IRQ INTERRUPT HANDLERN9XX;b=X; MORE TO SEND. SEND NEXT BYTE POINTED A‚ BY BUFR.lX;v†NOTEND%> €XýQ@†BUFRLO7;;GET NEXT BYTEŠ"P†SEROUT;;PUT IN SERIAL OUT REG”X;ž,¨!O†CHKSUM;;ADD BYTE TO ‚HECKSUM²O> ¼P†CHKSUMÆX;Ð-!†CHKDON;;GO RETURN AND WAIT FOR NEXT BYTEÚX;ä9X; ******** END OF OUT SERVICE ROU‚INE ********îøDX; **** SERIYýAL INPUT READY INTERRUPT SERVICE ROUTINE ****X;X;X; FX; AFTER SERIAL ‚ECEIVE IS ENABLED ROUTINE IS USED TO COLLECT*CX; BYTES FROM THE SERIAL INPUT REG AND PUT THEM IN BUFFER.4EX; W‚LL STOP WHEN BUFFER IS FULL. IF A CZýHECKSUM IS EXPECTED>EX; ROUTINE WILL MARK BUFFER FULL AND CONTINUE. WHEN CHECKSUM‚BX; RECEIVED IT WILL CHECK IF = TO CHECKSUM IT WAS MAKING.R7X; WILL STORE ERRORS FOUND IN STATUS LOCATION.\X‚fLX; THE IRQ INTERRUPT HANDLER I[ýN THE OS PUSHES THE USER'S A REGISTERp7X; ONTO THE STACK BEFORE CALLING THIS R‚UTINE.zX;„X; K.B. 6/11/80ŽX;˜ †ISRSIRC;;SAVE Y REG ON STACK¢5¬X;¶0X; GET STATUS FROM POKEY THEN RE‚ET IT.ÀX;ÊQ†SKSTATÔ'P…SKRES;;IGNORES \ýVALUE- JUST STROBEDÞX;èX; CHECK FOR ERRORSòX;ü*G†NTFRAM;;BIT 8 SET IF‚NO FRAMING ERROR %>†FRMERR #'†STATUS;;SET FRAME ERROR STATUS X;$ 2†NTFRAMM> ;;IF BIT 5 CLEAR THEN FRAME OVER RUN. "H†N‚OVRN;;BRANCH IF NO OVER RUN8 %>†OVRRUNB *'†S]ýTATUS;;ELSE SET OVERRUN ERROR STATUSL X;V HX; CHECK IF BUFFER FULL AND T‚IS IS A CHECKSUM. IF IT IS, THEN` )X; CHECK IF DATA SENT WAS VALID.j X;t 3†NTOVRNQ†BUFRFL;;TEST FOR BUFFER FULL (NOT‚ZERO)~ 0F†NOTYET;;IF ZERO THEN NOT YET, THIS IS ^ýDATA.ˆ !Q…SERIN;;ELSE THIS IS CHECKSUM’ R†CHKSUM;;ARE THEY EQUAL?œ F†SRETR‚;;YES,THEN RETURN¦ -%>†CHKERR;;ELSE SET CHECK SUM ERROR STATUS° '†STATUSº X;Ä -X; SET RECEIVE DONE TO END WAIT LOOP΂X;Ø †SRETRNQ>ÿ;;DONE VALUEâ P†RECVDNì X;ö #X; _ý RESTORE REGS AND RETURN
X;
†SUSUAL7
?;;RESTORE Y REG
7;;RES‚ORE 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
†NOTYETQ…SERIN;;GET DATA BYTEd
%> n
%P@†BUFRLO`ý7;;STORE IT IN THE BUFFERx
X;‚
,Œ
&O†CHKSUM;;ADD DATA BYTE TO CHECKS‚M–
O>
P†CHKSUMª
X;´
*#†BUFRLO;;INCREMENT POINTER TO LOCATION¾
H†NTWRP1;;FOR NEXT BYTE INPUTÈ
#†BUFRHIÒ
X;Ü
9X; ‚ THE PATCH CHANGED THE TEST FOR END OF BUFFERæ
X;ð
0†NTaýWRP1Q†BUFRLO;;DO DOUBLE PRECISION SUBTRACTú
R†BFENLOQ†BUFRHI"‚†BFENHI;;CARRY CLEAR IF BORROW:D†SUSUAL;;BRANCH IF (BUFR) < (BFEN)-WITHIN BUFFER LIMIT"X;,7X; DONE WITH DATA. SE‚ IF CHECKSUM TO BE SENT6X;@&Q†NOCKSM;;IF = ZERO THEN A CHbýECKSUMJF„GOON;;WILL FOLLOW THE DATATX;^#Q> ;;ELSE NO CHECK‚UM TO FOLLOWh#P†NOCKSM;;CLEAR NO CHECKSUM FLAGr/F†SRETRN;;RETURN AFTER SET RECEIVE DONE FLAG|X;†4X; SET BUFFER FU‚L AND THEN GO GET CHECKSUMX;š,„GOON"†BUFRFL;;SET BUFFER FULcýL FLAG TO FF¤H†SUSUAL;;GO RETURN®X;¸KX; ******** E‚D OF RECEIVE SERIAL INPUT INTERRUPT ROUTINE ********Â…MDEND
êô/ …MDEND;;SET END ADDR IN FMS PAST RES DUP SOþ>X; ‚ ;BUFFERS DON'T CLOBBER IT.„STAK ýþþ‚èX;SAVE #D2:DUPBUF.M65ò.A§BUFFERS - BEGINNING OF NON-RESIDENT DUPAüHX; ******** BEGINNING OF NON-RESIDENT PORTION‚ OF DUP ********X;X;3„NDOS|;;END OF THE SYSTEM BUFFERS AND MINIDUPB „NDOSLƒPAR(;;PARAMETER AREAj „LINE‚eý;;TYPE IN LINE BUFFERt„LBUF„LINEˆ"„DBUF ;;DATA BUFFER FOR COPY’ƒDB1„DBUF€œƒDB3„DBUF ƒDBL ;; DATA BUFF‚R LENGTH.„EDBLú;;DATA BUFFER LENGTH USED IN USEPGM(
†MENUSZ2
ƒPER<„UNNOF„RCNTP…SSTATZ„SWDPd‚„CSfýRCn„CDESx„SAVX‚
ƒPTRŒ„IPTR–
ƒCTR ‚T1ª6†BUFLEN‚T1;;SAVE AREA FOR BUFR LEN, USED IN USEPGM‚!…STVEC;;A TEMP OF SOME KIND¾9†MLT125…STVEC;;TEMP STORE FOR MULTIPLE OF 125, USEPGMÈ2;; Junk!!! Just takes up spac‚ for agýlignmentÒ0†EOFFLG;;ENDFILE FLAG FOR SOURCE IN DUPFILÜ0„FTRF;;FIRST TIME READ FLAG USED IN DUPFILæ@†TWODRV„FT‚F;;FLAG TO SHOW IF 1 OR 2 DRIVES. USED IN DUPDISKð ƒDTH
ƒEDNA‚E:A=‚CRLE OF 125, USEPGMÈ2;; Junk!!! Just takes up spac‚ for a Âþþ‚èX;SAVE #D2:DUPCMD1.M65òA’MAIN MENU ROUTINESAüX; **** DOS MENU ****X;X;…DMENU…CLSCR$(A¡DISK OPERATIN‚ SYSTEM II VERSION A.€=A… 2.5 A8)AšCOPYRIGHT 1984 ATARI CORP.A=‚CR=‚CRB,A¡A. DISK DIRECTORY I. FORMAT DISKA=‚CRL/‚ iýA¤B. RUN CARTRIDGE J. DUPLICATE DISKA=‚CRV,A¡C. COPY FILE K. BINARY SAVEA=‚CR`,A¡D. DELETE FILE(S) L. BINARY LO‚DA=‚CRj/A¤E. RENAME FILE M. RUN AT ADDRESSA=‚CRt/A¤F. LOCK FILE N. CREATE MEM.SAVA=‚CR~/A¤G. UNLOCK FILE ‚O. jýDUPLICATE FILEA=‚CRˆ.A£H. WRITE DOS FILES P. FORMAT SINGLEA=‚CR’ƒCDN=ƒCDN=ƒCDN=ƒCDN=ƒCDNœ…DMEND
¦…DULEN…DMEND‚DMENU°X;º‡@ALIGN u Ä…DOSOS!†:DOSOSÎX;Ø>…DUJPT †DIRLST=…STCAR=†CPYFIL=†DELFIL=†RENFIL=…LKFIL=…ULFILâ7 …WBOOT=†FMT‚SK=†DU kýPDSK=†SAVFIL=…LDFIL=„BRUN=†MEMSAVì †DUPFIL=†SGLFMTö!…DUNUM;;NUMBER OF FUNCTIONS
0X; **** DISK OPERATING ‚SYS MONITOR ****X;X;(†:DOSOS$>ÿ2 -;;MAKE SURE DECIMAL MODE OFF<&†BRKKEYF2P&†LOADFGZQ>dP†LMARGNnQ>‚xP†RMAR lýGN;;SET MARGINS‚%Q†POKMSK;;ENABLE BREAK INTERRRUPTSŒL>€–P†POKMSK
P…IRQENª †INITIO;;CLOSE FILES´X;¾#X; ‚heck for mini-dup of DOS 2.5ÈX;Ò
QˆOLDPRMSGÜ!R>L;; If not a JMP, then 2.0sæF†DSKUTLðX;ú(ˆ:NEED2.0Q> ;; Set DUP no‚ in memory mýP†DUPFLGQ>4Š:WRONGMINI$>5Š:WRONGMINI"
…WAITY'
!ˆ:NEED2.0,X;67Š:WRONGMINI}=AžInsert DOS 2.0s, type‚Y ÒÅÔÕÒÎA=‚CR@X;J X; DISK UTILITY MONITORTX;^
†DSKUTLhƒDU1Q>…DUNUMrP†MENUSZ;;SET MENU SIZE|Q>4…DUJPT†P†J‚PTBLQ>5…DUJP nýTš)P†JMPTBL;;SET UP JUMP TABLE ADDRESS¤X; FALL THRU TO MENU SELECT®X;¸X;ÂX;ÌCX; MENU SELECT MONI‚OR -- VECTORS TO ROUTINE SELECTED FROM MENU.ÖX;à$…SHMENQ>4…DMENU;;GET MENU ADDRESSê
P…ICBALôQ>5…DMENUþ
P…ICBAHQ>4…‚ULEN;;GET MENU LEN oýGTH
P…ICBLLQ>5…DULEN&
P…ICBLH0 †DSPMSG;;SHOW MENU:X;D!X; SELECT ITEM FROM MENUNX9X; ‚*** FUNCTIONS COME HERE WHEN THEY ARE DONE ****bX;l)†MENUSL$>ÿ;;RESET STACK AT THIS POINTvB€2Š!&†WCFLAG;;CLEAR WI‚D-CARD FLAG”Q>4ƒSIT pý;;SELECT ITEM MESSAGEž
$>5ƒSIT¨ ‡PRNTMSG²Q>@;;MAKE SURE UPPER CASE¼P†SHFLOKÆ" †CHRGET;;GO GET ‚EYBOARD CHAR.ÐX;ÚR>‚CR;;IF CR RE-DISPLAY MENUä
F…SHMENîX;ø;0S>
A;;CONVRT ASCII CHAR. TO BINARY # & SUB. 10G…RAN‚E;;IF ASCII CHAR NOT A # qý, GO READ AGAIN*R†MENUSZ;;IS THE # ENTERED > MENU SIZE? "I…RANGE;;IF YES, GO READ AGAIN.*T?4#?‚;SET INDEX TO (MENU # - 1) * 2>
Q@†JMPTBL7H3RP…RAMLO;;GET STRING POINTER\
Q@†JMPTBL7f
P…RAMLOp+%>;;LOAD STRING ‚OINTER INTO REGISTERSzQ@… rýRAMLO7;;FOR DSPLIN„>Ž1˜Q@…RAMLO7¢) †DSPLIN;;PRINT MODULES INITIAL STRING¬ …SCROL;;SCROLL‚INPUT WINDOW¶1Q…RAMLO;;INC BY 2 TO POINT PAST STRING POINTERÀ,ÊO>Ô
P…RAMLOÞDŒ:DOSELECTIONè
#…RAMLOü<Œ:DOSELEC‚ION!@…RAMLO:;;JUMP TO ROUTINE sýSELECTED BY MENU. …RANGEQ>4ƒNSI
$>5ƒNSI ! †DSPLIN;;NO SUCH ITEM MESSAGE$ !†MENUSL. 8 ‚NSIAŒNO SUCH ITEMA=‚CRB X;L GX;PROMPT FOR MENU SELECTION OR REDISPLAY MENU - RETURN IS IN INVERSEV X;` ƒSITASELECT ITE‚ OR Aj €=A†RETURNAt A‰ FOR týMENUA=‚CR~ „MNSL†MENUSLEQ>4ƒNSI
$>5ƒNSI ! †DSPLIN;;NO SUCH ITEM MESSAGE$ !†MENUSL. 8 ‚NSIAŒNO SUCH ITEMA=‚CRB X;L GX;PROMPT FOR MENU SELECTION OR REDISPLAY MENU - RETURN IS IN INVERSEV X;` ƒSITASELECT ITE‚ OR Aj €=A†RETURNAt A‰ FOR þþ‚èX;SAVE #D2:DUPDIR.M65òAŽLIST DIRECTORYAü.X; **** DIRECTORY LISTING ROUTINE ****X;X;†DIRLST „DLMG$ †G‚TIC1.! †USEBUF;;INIT BUFADR & BUFLEN8$ƒPTRB&QƒPAR9;;LAST CHAR OF SEARCH SPECLR>
:;;IF COLON, ADD *.*VHƒGLF`Q>
*‚$výPƒPAR9tPƒPAR9~Q>
.ˆ PƒPAR9’2œ2¦2°&ƒPTRº'ƒGLFQ>‚CR;; Put RETURN at end of bufÄPƒPAR9Î &„SAVXØ$>‚ â
…PIOCBì †GETFILö „PERX )Q>;;READ DIR INFO - use new mode!!!!
$>P…ICAX19Q>„OPEN;;OPEN(P…ICCOM92%&„CS‚C;;$wýCOPY SOURCE=DIRECTORY INFO<
…CIOCLFQƒPTRP;Z S„SAVXd0R>;;IF ONLY 3 CHARS, IS 'D:'CR, USE DEFAULTn
F…DLST1x…DL‚T0!„PDES;;GO INTO COPY‚…DLST1$„SAVXŒ QƒPAR9–R>
D
H…DLST0ª&!…PDES1;;GO INTO COPY WITH DES='E:'´X;¾1„DLMGA¡DIRECTO‚Y--SEA$xýRCH SPEC,LIST FILE?A=‚CRFO<
…CIOCLFQƒPTRP;Z S„SAVXd0R>;;IF ONLY 3 CHARS, IS 'D:'CR, USE DEFAULTn
F…DLST1x…DL‚T0!„PDES;;GO INTO COPY‚…DLST1$„SAVXŒ QƒPAR9–R>
D
H…DLST0ª&!…PDES1;;GO INTO COPY WITH DES='E:'´X;¾1„DLMGA¡DIRECTO‚Y--SEA$ þþ‚ èX;SAVE #D2:DUPDEL.M65òAŒDELETE 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 - ALLOW‚(zýONLY FOR DISK DEVICE ID`X;jQƒPAR;;GET DEVICEt!R>
D;;ONLY ALLOW DELETE FOR D:~FƒDF1ˆ
Q>4ƒNDF’
$>5ƒNDFœ †DSPLIN¦!‚MENUSL°ƒNDFANOT A DISK FILEA=‚CRØX;âƒDF1$>ìQƒOPTöR>
N;;IF OPTION=N, NO QUERY HƒDWQ;;NO, DELETE WITH QUERY
‚>†D({ýELETEP…ICCOM9
…CIOCL(!†MENUSL2ƒDWQQ>4ƒTYQ<
$>5ƒTYQF$ †DSPLIN;;SAY TYPE Y TO DELETE...PQ> Z0P„IPTR;;HOW MA‚Y FILES TO SKIP, NONE AT FIRSTd$> ;;SET UP DELETE IOCBnQ>†DELETExP…ICCOM9‚
Q>4ƒDB3ŒP…ICBAL9–
Q>5ƒDB3 P…ICBAH9ª‚Q>
D´(|ýP„DBUF¾Q>
:ÈP„DBUFÒ-QƒPAR;;DEVICE NUMBER OR : FROM OP INPUTÜR>
:æH†:HASDNð#Q>
1;; NO DRIVE NUMBER ‚ USE D1:ú)†:HASDNP„DBUF;;KLUDGE KLUDGE KLUDGE„IDRD$>
Q>„OPENP…ICCOM9"Q>,P…ICAX19;;DIR READ OPEN6
Q>4ƒPA‚@P…ICBA(}ýL9J
Q>5ƒPARTP…ICBAH9^
…CIOCLhQ>4„DBUFrP…ICBAL9|Q>5„DBUF†P…ICBAH9Q>†GETRECšP…ICCOM9¤Q> ®(PƒPTR‚;HOW MANY FILES WE HAVE SKIPPED¸X;Â.X; READ FILENAME FROM DIR, QUERY AND DELETEÌX;Ö„RDFN$>àQ> êP…ICBLL9ôQ>‚P…ICBLH9(~ý& …CIOCL;;READ A LINE FROM DIRECTORY)Q„DBUF;;IF FILE LINE, THIS IS BLANKR> ;; Is it a space?&#H„DELX;;‚HIS IS FREE BLOCKS LINE0#ƒPTR;;COUNT THIS FILE:"QƒPTR;;HAVE WE SKIPPED ENUF YETD R„IPTRNG„RDFN;;BR IF NOX$> ;;PUT P‚Rb%>;;GET P(ýTRlX;vX; MESSAGE DELETE FILE NAMES€X;Š„MDN1Q„DBUF8”R>
;;END OF FILENAMEž F„MDN2¨
P„DBUF9²2¼3‚(>Ð G„MDN1ÚX;ä!X; FILENAME IS MOVED, PUT .EXTîX;ø„MDN2Q>
.
P„DBUF92%>
;;WHERE EXT IS „MDN3Q„DBUF8*
P‚DBUF943>2H)>(€ý
R G„MDN3\&„SAVX;;PUT CR HERE LATERfQ>
?;;FOR QUERYp
P„DBUF9z2„Q>‚CRŽ
P„DBUF9˜
Q>4ƒDB3¢
$>5ƒ‚B3¬# †DSPLIN;;GO ASK ABOUT THIS FILE¶ †CHRGETÀR>
YÊH„RDFN;;GO DO NEXT FILENAMEÔ/QƒPTR;;NUMBER FILES WE HAVE GONE THR‚ SO FARÞ!P„IPTR;;IS (ýNEW NUMBER TO SKIP.è $„SAVXòQ>‚CRü
P„DBUF9 $> ;;DELETE IOCB
…CIOCL
…CLOS1$ )!„IDRD;;CLOSE ‚ND REOPEN DIR READ FILE. $„DELX …CLOS1;;CLOSE DIR READ FILE8 !†MENUSLB
…CLOS1$>L Q>…CLOSEV P…ICCOM9` !…CIOCL;;DO CLOS‚ AND RETURNj 0ƒTYQA…TYP(‚ýE A="=AYA="=A TO DELETE...A=‚CR’ X;œ „DEMGADELETE FILE SPECA=‚CR¦ X;LISTCLOS1$ )!„IDRD;;CLOSE ‚ND REOPEN DIR READ FILE. $„DELX …CLOS1;;CLOSE DIR READ FILE8 !†MENUSLB
…CLOS1$>L Q>…CLOSEV P…ICCOM9` !…CIOCL;;DO CLOS‚ AND RETURNj 0ƒTYQA…TYP( Qþþ‚èX;SAVE #D2:DUPCOPY.M65òAŠCOPY FILESAü$X; **** COPY FILE ROUTINE ****X;X;„CPMGACOPY--FROM, TO?A=‚CR$ ‚‚EA’OPTION NOT ALLOWEDA=‚CRLX;VX;`X;jX;tX;~
†WCFLAGˆ
†WCSKP1’
†WCSKP2œ
†WCBUFL¦…WCBUF†WCBUFL°‚,„ýWCOPYMAŒ COPYING---Aº†WCBUF2AƒDN:AĆWCBUFLÎ"†CPYFIL „CPMG;;COPY FILE PROMPTØ$ †GETIC1;;GET SOURCE DEVICE, ETC.â‚QƒPTRì P„SAVXö!QƒPAR;;GET 1ST CHAR. OF DEVICE R>
D;;TEST IF IT IS THE DISK
3H†JMPNWC;;BR IF NOT THE DISK (THEN USE OLD‚COD,…ýE)"$> ;;LOOK AT SOURCE FILE SPEC.- †LOOKWC;;LOOK FOR WILDCARDS IN FILE SPEC.(3F†CPYFL1;;BRANCH IF WILDCARDS USED IN‚DISK SPEC.2†JMPNWC!…NOTWC;;USE OLD CODE<†CPYFL1Q>€FX;PX;Z9†WCINITP†WCFLAG;;'WLDCARD' MODE (COPY-FILE OR DUP-FILd‚Q> n,†ýP†WCSKP1xX;‚†WCOPYLQ> ŒP†WCSKP2–$>;;OPEN DIRECTORY Q>ªP…ICAX19´
Q>„OPEN¾P…ICCOM9È
Q>4ƒPARÒP…IC‚AL9Ü
Q>5ƒPARæP…ICBAH9ð
…CIOCLúX;X;#†WCOPYRQ>†GETREC;;READ DIRECTORYP…ICCOM9"Q>†WCBUFL,P…ICBLL96Q> @P‚ICBLH9J,‡ýQ>4…WCBUFTP…ICBAL9^Q>5…WCBUFhP…ICBAH9r
…CIOCL|X;†3Q…WCBUF;;IF 1ST CHAR. OF DIR READ IS A #-IT IS TR>
‚š
D…WCGOT¤R>
:®
E…WCGOT¸X;Â3Q>…CLOSE;;ALL DONE -- NORM EXIT OF WILDCARD COPYÌP…ICCOM9Ö
…CIOCLà!†MENUSLêX;ôX‚þ9…WCGOTQ†W,ˆýCSKP1;;IF ALREADY COPIED OR SKIPPED THIS FILER†WCSKP2
F…SKIP1X;&#†WCSKP20H†WCOPYR:X;D…SKIP1#†WCS‚P1NX;X&Q>…CLOSE;;CLOSE DIRECTORY READ FILEbP…ICCOM9l
…CIOCLvX;€X;Š %>;;DON'T COPY .SYS FILES”†SYSLOPQ…WCBU‚
8žR†DOTSYS,‰ý8¨
H…NOSYS²1¼I†SYSLOPÆG†WCOPYLÐX;Ú†DOTSYSAƒSYSAäX;î'…NOSYS%>
1;;CALC SOURCE DRIVE NUMBERøQƒP‚RR>
:F†WCGOT1? †WCGOT1'†WCBUF2*X;4X;>+$>;;COMPRESS SPACES, ADD ':', ADD 'CR'H%>RX;\†COMPR1Q…‚CBUF9fR>…SPACEp,ŠýF†COMPR2zP†WCBUF28„3ŽX;˜†COMPR22¢(>
¬H†COMPR1¶X;ÀQ…WCBUF9ÊR>…SPACEÔF†COMPR5ÞQ>
.è‚P†WCBUF28ò3ü†COMPR3Q…WCBUF9 R>…SPACE F†COMPR4 P†WCBUF28$ 3. †COMPR428 (>
B H†COMPR3L X;V †COMPR5Q>‚CR` P†W‚BUF28j X;t X;~ 5Q>4,‹ý†WCOPYM;;PRINT 'COPYING---DEV:FILENAME.EXT' MSGˆ
$>5†WCOPYM’ †DSPLINœ X;¦ *†WCFLAG° 2J…WCOPY;;BR T‚ MIDDLE OF DUP FILE ROUTINE IF DUº X;Ä /$>;;SET UP BUFR ADDR TO PNT TO WLDCARD FILÎ
Q>4†WCBUF2Ø P…ICBAL9â
Q>5†WCBUF2ì ‚P…ICBAH9ö !†WCDUPS
X;,Œý
#…WCOPY †USEPGM;;SET BUFFER SIZES
$>;;OPEN COPY SOURCE FILE
Q>„OPEN(
P…ICCOM92
Q><
P…IC‚X19F
Q>4†WCBUF2P
P…ICBAL9Z
Q>5†WCBUF2d
P…ICBAH9n
&„CSRCx
…CIOCL‚
X;Œ
$> –
% …PIOCB;;GET COPY DESTINATION FILE
0Qƒ‚TR;;SAVE PTR,IPTR- MIGHT RE,ýPET GETTING 2NDª
ƒMES´
5¾
Q„IPTRÈ
5Ò
% †GETFIL;;GET 2ND FILE NAME TO PARÜ
7;;RECOVER IPTR,P‚Ræ
P„IPTRð
7ú
PƒPTR $„SAVX QƒPAR9R>
D"F†WCOPY0,3!„PDES;;JMP TO OLD CPY-FILE CODE IF NOT DSK DEST6X;@-†WCOPY0‚>
1;;CALCULATE DESTINATION DRI,ŽýVE #JQƒPAR9TR>
:^F†WCOPY1hX;r?|†WCOPY1)†WCBUF2†H†WCOPY23 …CLOSX;;CANT CO‚Y TO SAME DRVE NMBR - ERR & EXIšX;¤ !„ODMS®X;¸X;†WCOPY2$> Ì.'†WCBUF2;;CHANGE FILESPEC TO DESTINATIONÖ
Q>4†WC‚UF2àP…ICBAL9ê
Q>5†WCBUF2ôP…I,ýCBAH9þ-!†OPDES1;;CONTINUE INTO OLD COPY-FILE CODEX;X;…NOTWC
&$> ;;IOCB 30
…‚IOCB: †GETFIL;;GET SECOND FILENAMEDX;N0X; MAKE SURE DESTINATION IS NOT DOS.SYSXX;b($„SAVX;;ENTRY-INDEX TO DEST‚FILE SPECl' †TSTDOS;;WON'T RETURN I,ýF IS DOS.SYSvX;€ $„SAVXŠ †LOOKWC”2H†NWCIND;;BRANCH IF NO WILDCARDS IN DESTINATIONž‚
Q>4ƒNWA¨
$>5ƒNWA² †DSPLIN¼!†MENUSLÆ4ƒNWAA¥WILD CARDS NOT ALLOWED IN DESTINATIONA=‚CRîX;ø†NWCIND
„PERX;;IF P‚RAM ERRS, EXIT
4 †USEPGM;;ASK USR IF C,‘ýAN USE PGM AREA OR DATA BFR
„PSRC
QƒPAR;;GET 1ST LETR OF PARAM*
R>
K4
4F„ODMS;‚K:GETS 'OPTION DOESNT MAKE SENSE' FOR NOW>
R>
CH
6F„ODMS;;C: GETS 'OPTION DOESNOT MAKE SENSE' FOR NOWR
R>
E;;E: AS SOURCE ‚S SPECIAL\
'H…OPSRC;;IF NO THEN OPEN SOURC,’ýE FILEf
$> p
&„CSRCz
!„PDES„
…OPSRCR>
SŽ
-F„ODMS;;S: AS SOURCE GETS O.D.M.S. ‚OR NOW˜
X;¢
X; OPEN SOURCE FILE¬
X;¶
$>À
Q>„OPENÊ
P…ICCOM9Ô
Q>;;OPEN INÞ
P…ICAX19è
&„CSRC! …CIOCL;;OPEN‚SOURCE FILE HEREX;)X; READY FOR OP,“ýEN OF DESTINATION$X;.„PDES$„SAVX8 QƒPAR9BX;LR>
K;;IS DEST KEYBOARD?V ‚„ODMS;;YES, THEN CAN'T DO IT`X;jR>
E;;CHECK FOR SPECIAL CASEtH…OPDES;;IF NOT~:…PDES1Q> ;;SPECIAL CASE - DONT OPEN, U‚E EXISTING IOCBˆ P„CDES’
!…DOCPYœ„ODMSQ>4‚OE,”ý¦!$>5‚OE;;SAY OPTION NOT ALLOWED° †DSPLINº …CLOSX;;CLOSE IOCB 1 & 2Ä!‚MENUSLÎX;Ø
…OPDESR>
Câ6F„ODMS;;C: GETS 'OPTION DOESNOT MAKE SENSE' FOR NOWì$ƒOPT;;GET 2ND FILE OPTIONöX; (>
A;;APP‚ND TO DISK FILE
H†OPDES1R>
D H„ODMS(Q> 2,•ýH†OPDES3<†OPDES1Q>F†OPDES3$> PP…ICAX19;;OPEN TYPE OUTZ
Q>„OPEN‚P…ICCOM9;OPENn &„CDESx
…CIOCL‚Q> ŒP…ICAX29–X; X;COPY FROM CSRC TO CDESªX;´…DOCPYQ>†GETCHR¾
ƒGC1$„CSRCÈ %‚CDESÒP…ICCOM9ÜQ>†PUTCHRæP…ICCOM8ð'Q†BUFADR;;ADD,–ýRESS OF BUFFER - EITHERú3P…ICBAL9;;PGM AREA (MEMLO) OR DATA BUFFER (D‚UF)P…ICBAL8'Q†BUFADR;;BUFADR IN LSB,MSB ORDERP…ICBAH9"P…ICBAH8,…CLOOP$„CSRC6'Q†BUFLEN;;LENGTH OF BUFFER ADDR‚SSED@P…ICBLL9;;BY BUFADRJ1Q†BUFLEN;;BOTH BUFADR & B,—ýUFLEN ARE ASSIGNEDT!P…ICBLH9;;IN SUBROUTINE USEPGM^ ƒCIO;;READ F‚OM INPUTh
'…SSTATr $„CDES| %„CSRC†Q…ICBLL8P…ICBLL9šQ…ICBLH8¤P…ICBLH9®&L…ICBLL8;;IF SOURCE FILE LENGTH = 0¸F„C‚RS;;DON'T DO WRITEÂ! …CIOCL;;WRITE, ABORT IF ERRORÌ/„CKRSQ,˜ý…SSTAT;;GET READ OPERATION STATUS BACKÖ$I…CLOOP;;IF OK, GO READ‚SOME MOREàR>ˆ;;EOF STATUSê F„CLOCô!…CIOER;;IF NOT, ABORTþ„CLOC$„CSRCFƒDU4;;IF E:, DONT CLOSEX;X;CLOSE SOURC‚ FILE&X;0Q>…CLOSE:P…ICCOM9D ƒCION
ƒDU4$„CDESXFƒDU3;;,™ýIF DES=E:bQ>…CLOSElP…ICCOM9v ƒCIO€
ƒDU3$„CDESŠHƒDU6”‚Q>4„DDSKž$>5„DDSK ¨5 ‡PRNTMSG;;PRNT A CR BEFOR SELECT OR WLDCARD PRMPT² ƒDU6
¼X;Æ*†WCFLAGÐIƒDU5Ú*!†WCOPY‚;;BRANCH BACK TO WILD CARD LOOPäƒDU5!†MENUSLƒDU4$„CDESXFƒDU3;;, éþþ‚èX;SAVE #D2:DUPCMDS.M65òAŒRENAME, ETC.Aü(X; **** RENAME FILE ROUTINE ****X;X;IX;RENAME SETS UP IOCB #1 W‚TH THE OLD FILE NAME AND THE BUFFER ADDRESS$IX;POINTS TO THE NEW FILE NAME. THE NEW FILE SPECIFICATION CANNOT HAVE.JX;A D‚0›ýVICE ID. THE DEVICE ID IS THE SAME AS SPECIFIED FOR THE OLD FILE8CX;D2:ABC.S2,QQQ.R3 THIS RENAMES ABC.S2 ON DRIVE #2 T‚ QQQ.R3BX;L†RENFIL „RNMGV1 †GETIC1;;GET OLD FILE SPEC & PUT ADDR IN IOCB` ‡GETNAME;;GET NEW FILE NAMEj# „PERX;;EXIT ‚F P0œýARAMETER ERRORStX;~% †CHKVER;;MAKE SURE VER 2 DISKETTEˆX;’ X; CONTINUE WITH RENAMEœX;¦Q>†RENAME°$>º‚…ICCOM9Ä
…CIOCLÎ!†MENUSLØ+„RNMGA›RENAME - GIVE OLD NAME, NEWA=‚CRâX;ì;X;******************* SUBROUTINE ********‚******0ý****öX; 5X; MAKE SURE THIS IS A VERSION 2 FORMAT DISK
X;+†CHKVER%>;;ASSUME DRIVE 1- GET DRIVE #3QƒPAR‚;;TEST CHAR 2 OF FILE SPEC FOR SEMICOLON('R>
:;;IF IS, USING DEFAULT DRIVE (1)2!F„DRV1;;IT IS, SO SAVE DRIVE #<,M>;;E‚SE CHAR 20žý IS ASCII REP OF DRIVE #F!?;;CONVERT TO BINARY & SAVE ITP„DRV1'„UNNO;;SAVE DRIVE #ZX;d5!‡TSTVER2;;TST FOR VER‚. 2 DISK- WONT RTURN IF NOTnX;x‚(X; **** FORMAT DISK ROUTINE ****ŒX;–X; (†SGLFMT ƒWHD;; Single density forma‚!ªQ>ˆFORCE0ŸýFMT´H‹:FMTOPTIONS¾X;ȆFMTDSK ƒWHDÒQ>†FORMATÜ‹:FMTOPTIONSP‡FMTTYPEæ †GETLINð
…GETDNú,O>
0 P„‚DSK P„CDSK" „PERX,(Q>4ƒVFM;;QUERY TO VERIFY DRIVE NUMBER6
$>5ƒVFM@ †DSPLINJ †CHRGETTR>
Y;;SEE IF OK^HƒFMXhQ‡‚MTTYPEr%>
!|0 ý
…DOFMT†ƒFMX!†MENUSL;;EXIT.X;š‡FMTTYPE¤X;®
…DOFMT$>¸P…ICCOM9Â
Q>4ƒFDPÌP…ICBAL9Ö
Q>5ƒFDP‚P…ICBAH9êCôP…ICAX19þ!!…CIOCL;;CALL CIO TO DO FORMAT%ƒWHDA–WHICH DRIVE TO FORMAT?A=‚CR/ƒVFMA…TYPE A="=AYA="=A‚ TO FORMAT DISK A0¡ý„DDSK&‚CR0ƒFDPADA:„CDSKDA:A=‚CRNX,X; **** START CARTRIDGE ROUTINE ****bX;l‚X;v…SYVBL†SYSVBV€…XTVBL†XITVBVŠ%…STCAR „SCMG;;NO MSG, PRINT A ”†ROMTSTý¿ž!%†ROMTST;;TEST IF RAM OR OTHER¨‚>ª;;PATTERN #1²P†R0¢ýOMTST¼R†ROMTSTÆH†NOTRAM;;BRANCH IF NOT RAMÐQ>U;;PATTERN #2ÚP†ROMTSTäR†ROMTSTîH†NOTRAM;;BRA‚CH IF NOT RAMøX;-'†ROMTST;;THERE IS VALID RAM - SAY NO CART†NOCARTQ>4ƒNCA$>5ƒNCA;;SAY NO CART †DSPLIN*!†MENUS‚4X;>/X; CHECK I0£ýF ROM OR EMPTY ADDRESS SPACEHX;R#†NOTRAMQü¿;;KNOWN ROM ZERO BYTE\*H†NOCART;;BRANCH IF EMPTY ADD‚ESS SPACEfX;p+>;;SINCE EMPTY ADDR SPACE GIVES A RANDOMz8†CKCARTQ†ROMTST;;VALUE, TEST THE SAME LOC MANY TIMES.„#F†NOCART‚;BRANCH IF NO CARTRIDGEŽR0¤ý†ROMTST˜#H†NOCART;;BRANCH IF NO CARTRIDGE¢2¬H†CKCART;;LOOP BACK¶X;ÀX;Ê=X; RESET V‚RTICAL BLANK VECTORS BEFORE ENTERING CARTÔX;Þ †INITIOèQ>;;SET VVBLKIò$>5…SYVBL;;HI BYTEü%>4…SYVBL †SETVBV Q‚;;SET VVBLKD $>5…XTVBL$ %0¥ý>4…XTVBL. †SETVBV8 !†CLMJMPB L ƒNCAAŒNO CARTRIDGEAV „SCMG‚CR` X;j X;t +X; ***‚*** RUN AT ADDRESS *******~ X;ˆ X;’ X;œ „BRUN „BRMG¦ †GETLIN°
…GETNOº „PERXÄ
P…RAMLOÎ
&…RAMLOØ QƒCTRâ R>‚ 2F…MOUT1;;RETURN TO MENU IF NO R0¦ýUN ADDRESS GIVENö . †INITIO;;CLOSE ALL IOCB'S, THEN REOPEN S/E
)!„LMTR;;LOAD MEM.SAV & JUM‚ TO ADDRESS
X;
X;
&„BRMGA–RUN FROM WHAT ADDRESS?A=‚CR(
2
2X; **** CREATE MEM.SAV FILE ON DISK ****<
X;F
X;P‚6„MEMSA…TYPE A="=AYA="=A’ TO CRE0§ýATE MEM.SAVA=‚CRZ
†MEMSAV „MEMSd
†CHRGET;;GET CHAR (CR)n
R>
Yx
*H„MOUT;;BRANCH IF US‚R'S ANSWER NOT A Y‚
†MEMSVQ;;TRY TO OPEN MEM.SAVŒ
+G…MCONT;;IF FILE DOESN'T EXIST THEN JUMP–
-Q>4…MEMSG;;ELSE 'MEMORY.SAVE‚ AREADY EXIST
$>5…MEMSG;;ª
†DSPLIN;0¨ý;DISPLAY THIS FACT´
)„MOUT …CLOSX;;EXIT AFTER CLOSING IOCB1¾
…MOUT1!†MENUSL;;È
X;Ò
‚X; WRITE MEMORY.SAVE TO DISKÜ
X;æ
…MCONT †MWRITE;;WRITE FILEð
I„MOUTú
„MERR!†CIOER1;;DISPLAY ERRORX;,…MEMSGA›MEM.S‚V FILE ALREADY EXISTSA=‚CRSG;;ª
†DSPLIN;0 íþþ‚
èX;SAVE #D2:DUPDOS.M65òAWRITE DOS FILESAü%X; **** WRITE DOS & DUP ****X;X;,…WBOOT †DOSDRV;;ADDRESS OF ‚RIVE # PROMPT$X;.,X; RETRIEVE DRIVE NUMBER FROM USER.8X;B †GETLIN;;GET INPUTL* …GETDN;;GET DRIVE AS NUMBER, VE‚4ªýIFY ITV „PERX;;EXIT IF ERROR`P„UNNO;;SAVE IT FOR TSTVER2jL>
0;;TURN BACK TO ASCII REPt&P‚DS;;STORE IN DOS.SYS FILE‚SPEC~P„QWMG;;& IN PROMPTˆX;’5 ‡TSTVER2;;TST IF VERS. 2 DISK - IF ISNT WONT RTRNœX;¦>X; ASK USER IF CAN WRIT‚ DO4«ýS & DUP TO SPECIFIED DRIVE°X;ºQ>4„QWMG;;PRINT PROMPTÄ$>5„QWMGÎ †DSPLINØ †CHRGETâR>
YìHƒWBX;;EXIT UNLESS Yö‚X; GX;TELL USER WRITING DOS FILES AND WRITE DOS.SYS FIRST- JUST OPEN IT.
X;Q>4„WBMG$>5„WBMG( †DSPLIN2X;<
Q>„OP‚NF $>4¬ý;;OPEN DOS.SYS ON IOCB #1P2P…ICCOM9;;WILL CAUSE FMS TO REWRITE BOOT SECTORZQ>4‚DS;;& A COPY OF DOS.SYSdP…ICBAL9‚ Q>5‚DSxP…ICBAH9‚Q>ŒP…ICAX19–' …CIOCL;;DO OPEN, IF ERROR GOTO MENU X;ª$>´Q>…CLOSE¾P…ICCOM9È …CIOCL;;DO‚E CLOSE I4ýT.ÒX;Ü*X; WRITE DUP.SYS - SWAP AREA FILEæX;ð$>;;MOVE 11 CHARSú†MDUPBLQ†DUPSYS9.PƒPAR9;;MOV‚ FILE NAME TO PARAMETER LIST0H†MDUPBL"Q‚DS;;GET DRIVE NUMBER,(PƒPAR;;PUT IT IN DUP.SYS FILE SPEC6X;@&ƒPTR‚$>T) …P4®ýIOCB;;PUT FILE NAME POINTER IN IOCB^
Q>4ƒDTHh P„LDSTr
Q>5ƒDTH|P„LDST†Q>4…NMDUP P„LDNDš
Q>4ƒLEN¤P„‚DRL®
Q>5ƒLEN¸P„WDRHÂQ>5…NMDUPÌP„LDNDÖ5;;NO /AàQ>4…DOSOSê
P…RUNADôQ>5…DOSOSþ&P…RUNAD;;SET DUP.SYS ‚UN ADDRESS"„4¯ýRUNQ;;SET RUN FLAG!†NRUNAD;;WRITE DUP.SYSƒWBX!†MENUSL&.†DOSDRVAœDRIVE TO WRITE DOS FILES TO?A=‚CR0‚%„WBMGA•WRITING NEW DOS FILESA=‚CRXX;bl=„QWMGA…TYPE A="=AYA="=A™ TO WRITE DOS TO DRIVE .A=‚CR”X;ž‚DSAŠD1:DO‚.SYSA=‚CRÆX;Ð,ƒ4°ýWVDAERROR - NOT VERSION 2 FORMAT.A=‚CRøX;7X; **** TEST FOR VERSION 2 FORMAT - SUBROUTINE ****‚X; X;*X;4 X; SUBROUTINE - TSTVER2>X;HIX; READS THE DISK'S VTOC AND CHECKS IF VERSION BYTE IS SET AS 2.R‚X;\2X; 4±ý ENTRY - DRIVE # STORED IN UNNOf?X; EXIT - RETURNS ONLY IF IS A VERSION 2 DISKp@X; ‚ ELSE DOES AN ERROR EXIT BACK TO MENUz-X; CALLS - DRVSTAT AND RVTOC„6X; CALLE‚ BY - DELFIL, RENFIL, WB4²ýOOT.ŽX;˜X;¢IX; GET DRIVE TYPE SO KNOW CORRECT SECTOR SIZE - NEEDED FOR RVTOC¬X;¶
‡TSTV‚R2
X; .X; READ THE VTOC & CHECK IF VERSION 2 X;$ &…OKTYP …RVTOC;;READ IN VTOC TO DBUF. Q„DBUF;;1ST BYTE IS VER‚ION #8 R>;;IS IT VERSION4³ý 2?B &F…SMVRS;;YES, SAME VERSION - RETURNL X;V 8X; NOT A VERSION 2 DISK - PRINT MSG & GOTO‚MENU` X;j "Q>4ƒWVD;;ELSE, NOT SAME VERSIONt "$>5ƒWVD;;PRINT INCOMPATIBLE MSG~ †DSPLINˆ !†MENUSL;;GOTO MENU’ X;œ )X; ‚ DISK IS VERSION TWO SO RETUR4´ýN¦ X;° …SMVRS:;;RETURN VERSION - RETURNL X;V 8X; NOT A VERSION 2 DISK - PRINT MSG & GOTO‚MENU` X;j "Q>4ƒWVD;;ELSE, NOT SAME VERSIONt "$>5ƒWVD;;PRINT INCOMPATIBLE MSG~ †DSPLINˆ !†MENUSL;;GOTO MENU’ X;œ )X; ‚ DISK IS VERSION TWO SO RETUR4 þþ‚èX;SAVE #D2:DUPCMD2.M65òAVARIOUS COMMANDSAü-X; **** LOAD USER FILE FUNCTION ****X;X;…LDFIL „LFMG$ †‚ETIC1.Q> 8$ƒOPTBPƒOPTL+(>
N;;IS OPTION N FOR DON'T LOAD AND GO?VH„NOTN;;BRANCH IF NOT`"ƒOPTj„NOTN „PERXt „LO‚8¶ýD~#(> ;;PROCESS LOAD SUBR RESPONSEˆ F„LDFX;;BRANCH IF LOAD WAS OK’(>œFƒNLF;;IF BAD LOAD FILE¦"C;;OTHERWISE WE GOT ‚ CIO ERROR°!…CIOER;;GO SAY WHAT IT ISºƒNLFQ>4ƒBLFÄ
$>5ƒBLFÎ †DSPLIN;;BAD LOAD FILE MSGØ …CLOSX;;CLOSE THE FILEâ„L‚FX!8·ý†MENUSL;;EXITìƒBLFABAD LOAD FILEA=‚CRX;$„LFMGA”LOAD FROM WHAT FILE?A=‚CR(22X; **** LOCK & UNLOCK FILE ‚COMMANDS ****<X;FX;P…LKFIL „LKMG;;DO LOCKZ †GETIC1d „PERXn
Q>„LOCKx$>‚P…ICCOM9Œ
…CIOCL–!†MENUSL "„LKM‚A’WHA8¸ýT FILE TO LOCK?A=‚CRªX;´…ULFIL „ULMG;;DO UNLOCK¾ †GETIC1È „PERXÒQ>†UNLOCKÜ$>æP…ICCOM9ð
…CIOCLú!†ME‚USL$„ULMGA”WHAT FILE TO UNLOCK?A=‚CRKMG;;DO LOCKZ †GETIC1d „PERXn
Q>„LOCKx$>‚P…ICCOM9Œ
…CIOCL–!†MENUSL "„LKM‚A’WHA8 žþþ‚èX;SAVE #D2:DUPDUP.M65òAŽDUPLICATE DISKAü+X; **** DUPLICATE DISK ROUTINE ****X;X;)X; FMS equates needed ‚or VTOC access:$X;.*†DVDWRQ;; Write required flag offset8)†DVDSMP
;; Offset of start of bitmapVX;`X;j,„DDMGAœ‚<ºýUP DISK-SOURCE,DEST DRIVES?A=‚CRt<‚OKA…TYPE A="=AYA="=Aš IF OK TO USE PROGRAM AREAA=‚CR~X;ˆ?„CMSIA‹CAUTION: A A="=‚YA="=A• INVALIDATES MEM.SAV.A=‚CR’X;œ7X; RVTOC READS VOLUME TABLE OF CONTENTS SECTOR¦X;°2…RVTOCQ>5„DBUF;; Use ‚ata<»ý buffer as VTOC bufferºP‡VTOCPTRÄQ>4„DBUFÎP‡VTOCPTRØ1Q„UNNO;; Use source drive number for VTOC readâP†ICDNOZì‚&Q> ;; Turn off write required flagö)P„DBUF†DVDWRQ;; so VTOC will be read. ‰CALLRVTOC
6I‡:READOK;; If error occurred,‚tell u<¼ýser and abort.!†CIOER1X;(‡:READOKQ>†DVDSMP2PƒPTR<Q„DBUF†DVDSMPFP„CSRC;;BYTE OF ALLOC MAPPQ>ZP„IPT‚;;COUNT BITS IN BYTEdQ> nP„DSHI;;POINT TO SECTOR ONExQ>‚ P„DSLOŒ:–X; X;ª†DUPDSK „DDMG´Q> ;;ASSUME SINGL‚ DRIVE¾<½ýP†TWODRV;;CLEAR FLAGÈ †GETLINÒ
…GETDNÜP„UNNO;;UNIT NO FOR READæ
…GETDNð#P„CDES;;CDES IS THE DEST DRIVE #ú‚ „PERXX;2X; CHECK IF TWO DRIVE OR SINGLE DRIVE DUPX;"„SAMEQ„UNNO,!R„CDES;;IF BOTH UNITS THE SAME6FƒSDD;;S‚NGLE DRIVE D<¾ýUP@
$>5ƒIBDJ
Q>4ƒIBDT( †DSPLIN;;PROMPT TO INSERT BOTH DISKS^ †CHRGETh"†TWODRV;;SET TWO DRIVE FLAGrG†DOD‚DP;;GO DUP DISK|-ƒIBDAžINSERT BOTH DISKS, TYPE RETURNA=‚CR†X;X;šX;¤LX;USED BY BOTH SINGLE & DOUBLE DRIVE DUP. WILL‚NOT ASK TO SWAP<¿ý IF 2 DRIVE®X;FLAG (TWODRV) IS SET.¸(X;IF THE TWO DRIVE FLAG IS CLEAR WILLÂ6X;FILL FROM SOURCE DISK, SWAP‚ EMPTY, SWAP, REPEAT.ÌX;Ö*ƒSDDQ>4ƒISD;;TELL USER TO INSERT SOURCEà3$>5ƒISD;;FOR INITIAL READ - USED ONLY FOR SINGLEê †‚SPLIN;;DRIVE DUPLI<ÀýCATEô †CHRGETþ-†DODKDPQ>4…NMDUP;;SET BUFFER AT END OF DUP
P…STVECQ>5…NMDUP
P…STVEC&X;04X; ‚ BUFFER BOTTOM MOVES FROM NMDUP TO MEMTOP:@X; SET END OF BUFFER TO MEMTOP MINUS 1 SECTOR IN BYTES.DFX; WHE‚ BUFFER BOTTOM IS LES<ÁýS THAN OR EQUAL TO BUFFER END, ATN5X; LEAST ONE MORE SECTOR WILL FIT IN MEMORY.XX;bQ†MEMTOPl‚;v"S>4†SECSIZ;;T1 IS END OF BUFFER€P‚T1ŠQ†MEMTOP”
S>5†SECSIZž+P‚T1;;T1 IS MEMTOP MINUS SECTOR SIZE.¨X;²)X;S‚E IF ROOM FOR AT LEAST O<ÂýNE SECTOR!¼X;Æ!Q‚T1;;DO DOUBLE PRECISION TESTÐR…STVEC;;TO SEE IF ROOMÚ+Q‚T1;;IF T1 IS = STV‚C THEN ENUF ROOMäS…STVEC;;FOR ONE SECTORî"E„ENUF;;BRANCH IF (T1)>=(STVEC)ø„NORMQ>4ƒNRM
$>5ƒNRM †DSPLIN!†MENU‚L X;*+„ENUF …CKMEM;;SEE <ÃýIF OK TO USE USER AREA4Q> >)PƒOPT;;SET UP FOR READ HERE FIRST PASSH0P‰FIRSTTIME;; and set th‚ pass number to zeroR …RVTOC;;READ VTOC\&Q„DSLO;;COPY INITIAL WRITE POINTERSf#P„SWDP;;TO INITIAL READ POINTERSp Q„DSHIz‚P„SWDP„QƒPTRŽP„SWDP<Äý˜ Q„IPTR¢P„SWDP¬ Q„CSRC¶P„SWDPÀ!!„LRS1;;SKIP FIRST READ PROMPTÊX;Ô7X;READ FROM‚SOURCE DISK TIL BUF FULL OR END OF DATA.ÞX;è!„DORDQ> ;;FLAG WE ARE READINGòPƒOPTü*†TWODRV;;TEST FOR 2 DRIVES G„LRS‚;;YES, SKIP THE SWAP Q>4ƒISD;;I<ÅýNSERT SRC DISK
$>5ƒISD$ †DSPLIN. †CHRGET8 X;B "X;SWAP POINTERS TO WHERE WE AREL X;V‚1„LRS1 †DOSWDP;;SWAP SECTOR AND BITMAP POINTERS` X;j 0X;LOOP READING/WRITING SECTORS TO BUFFER AREAt X;~ $ƒLRS ƒAAM;;ADVAN‚E ALLOCATION MAPˆ 0G„ASPT;;IF FREE, <ÆýADV SECTR POINTER & TRY AGIN’ *ƒOPT;;SEE WHAT MODEœ GƒDOW;;BR IF WRITE¦ …RSEC1;;DO R‚AD° !ƒIODº ƒDOW …DKWRT;;DO WRITEÄ 'ƒIODQ†DBUFLO;;ADVANCE BUFFER POINTERÎ #N>€;; Add 128 to buffer pointerØ P†DBUFLOâ G„‚SPTì #†DBUFHI
(„ASPT ƒASP;;GO ADVANCE<Çý SECTOR POINTER
0QƒPTR;; Check to see if we're past end of map
R‡MAXVTOC(
/F…STDD1‚;ALL SECTORS DONE, SWAP TO DEST DISK2
Q‚T1;;SEE IF ROOM FOR ANOTHER<
R†DBUFLO;;SECTOR BELOW MEMTOPF
Q‚T1P
S†DBUFHIZ
2‚ƒLRS;;BRANCH IF (DBUF)<=(T1) - ROOM FOR M<ÈýORE.d
X;n
X;SWAP DISKS AND CONTINUEx
X;‚
„STDDQƒOPTŒ
G„DORD;;IF WAS WRITE, GO‚READ–
…STDD2"ƒOPT;;CHANGE TO WRITE
%*†TWODRV;;ARE 2 DRIVES BEING USED?ª
G‡:CHKFMT;;YES, SKIP THE SWAP´
Q>4ƒIDD;;INSERT D‚ST DISK¾
$>5ƒIDD¿
†DSPLINÀ
†CHRGETÈ
X;Ò<Éý
6‡:CHKFMTQ‰FIRSTTIME;; Is this the first write pass?Ü
H„LRS1æ
#‰FIRSTTIMEç
1‚„CDES;; Set destination drive as format driveè
L>
0é
P„CDSKð
X;ú
X; Format destination diskX;+%>
!;; Use single den‚ity format command!Q‡MAXVTOC;; unless in MFM m<Êýode"I‡:NOTMFM,%>
"69‡:NOTMFMQ„DSLO;; Save ending sector of first read p‚ss758 Q„DSHI95?Q>ˆFORCEFMT@ …DOFMT;; Try to format diskB7C P„DSHID7E P„DSLOT !„LRS1^X;h…STDD1QƒOPT;;END ‚F DATArI…STDD2;;IF READ GO WRITE|+Q„CDES;; Write<Ëý VTOC to destination drive†P†ICDNOZ‡3Q>4„DBUF;; Set VTOC buffer addres‚ to our bufferˆP‡VTOCPTR‰Q>5„DBUFŠP‡VTOCPTR ‰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 B‚FFER POINTERÖX;à†DOSWDP%>ê…SWLOPQ…SWATL8ô
P…RAMLOþQ…SWATH8.P…RAMLO;;GET ADDRESS FROM TABLE TO RAMLO$> ‚Q@…RAMLO6;;GET WHAT'S THERE&50
Q„SWDP8:P@…RAMLO6D7<ÍýN
P„SWDP8X1b
I…SWLOPl
Q…STVECvP†DBUFLO€
Q…STVECŠP†DBUF‚I”:žX;¨‰FIRSTTIME²X;¼Æ+…SWATL4„DSLO=4„DSHI=4ƒPTR=4„IPTR=4„CSRCÐ+…SWATH5„DSLO=5„DSHI=5ƒPTR=5„IPTR=5„CSRCÚ‚;äX;îƒNRMANOT ENOUGH ROOMA=‚CRø-ƒISDAžINSERT SOURCE <ÎýDISK,TYPE RETURNA=‚CR
2ƒIDDA£INSERT DESTINATION DISK,TYPE RETU‚NA=‚CR
X;
X;
+X; AAM - ADVANCE ALLOCATION MAP ONE BIT.*
X; RETURN MINUS IF FREE.4
X;>
$ƒAAMT„CSRC;;NEXT BIT OF ALLOC ‚APH
"„IPTRR
!H„CBIT;;IF DONE WITH THIS BYTE\
#ƒPTR;;GET NEXT <ÏýONEf
$ƒPTRp
3Q„DBUF9;;VTOC IS DBUF & BITMAP STRTS IN 10TH BY‚z
P„CSRC„
Q>Ž
P„IPTR˜
„CBITQ„CSRC;;CHECK THE BIT¢
:¬
X;¶
X;À
*X; ASP - ADVANCE SECTOR POINTER IN DCB.Ê
X;Ô
ƒASP#„‚SLOÞ
H„ASPXè
#„DSHIò
„ASPX:ü
X;2X; RSEC1 - READ A SECTOR WHO<ÐýSE NUMBER IS IN DCBX;…RSEC1Q„UNNO$*,;;TELL DISK HAN‚LER DOING A GET SECTOR.D†:SECIO8X;BX; DKWRT - WRITE A SECTORLX;V …DKWRTQ„CDES;;PUT DEST UNIT #`*;;;TELL DISK HANDL‚R DOING WRITE SECTORj
†:SECIOt
P…DUNIT~! …BSIOR;;GOTO FMS DISK HAN<ÑýDLERˆ I„DRTS;;RETURN IF GOOD STATUS’$!†CIOER1;;CIO ER‚OR, GO SAY WHICHœ„DRTS:;; just return¦X;°.X; CKMEM - ASK IF OK TO USE USER AREAºX;Ä'…CKMEMQ†WARMST;;IF MEMORY ‚AS INTACTÎF…CPTR1;;QUERY TO BOMB ITØ Q>4‚OKâ$>5‚OK;;PRINT PROMPTì<Òý †DSPLINöQ>4„CMSI;;PRINT CAUTION MSG /$>5„CMSI;;Y‚RESPONSE WILL INVALIDATE MEM.SAV
†DSPLIN †CHRGET&R>
Y;;TEST FOR OK TO BOMB USER AREA(&H„DDXT;;IF SAY NO THEN DON'T ‚O DUP2Q> <*P†WARMST;;TELL CART NO GOOD USER MEMORYF(P†MEMFLG;;TELL LOA<ÓýDER NO GOOD MEM.SAVP
…CPTR1:ZX;d„DDXT7;;POP ‚ETURN ADDRESSn7x$!†MENUSL;;GOTO MENU, DON'T DO DUP‚X;&R>
Y;;TEST FOR OK TO BOMB USER AREA(&H„DDXT;;IF SAY NO THEN DON'T ‚O DUP2Q> <*P†WARMST;;TELL CART NO GOOD USER MEMORYF(P†MEMFLG;;TELL LOA<