B, :6 "UTILITY.LIB" : SREG%( ) 8J PROG$"ZAP-600":VERS$"V01.00" :V NULL$():CR$( ):ESC$():TRUE%:FALSE% NULLREG$"": I% :NULLREG$NULLREG$NULL$: I% SREG$NULLREG$"":RREG$NULLREG$"" $ SEGMENT%:OFFSET%:SCRATCH.SEG%:SCRATCH.OFF%:LENGTH%:BYTE%6 . AX%:BX%:CX%:DX%:SI%:DI%:BP%f 8 ES%:DS%:FLAGS%:CS% :SS% :SP% | B MAX.SECTOR% L SECTOR.SIZE% V TRACK.SIZE% ` MEDIA$( ) j MAX.DRIVE%  :  "$$Buffer.$$$" AS 1   ,  AS BUFFER$/  : main menuK  (,)(,),,BFu  : ,!,: PROG$;" ";VERS$;:   (,k)((,),,BF  , : "M A I N M E N U"  I% : (I%) rB,|B,B,B: I%   ,: "Use ARROW keys to highlight command."O   ,: "To select command, press ENTER";\  CMD%f 4 : > : (CMD%) rB,|B,B,B:  H ANS$: ANS$"" H R (CMD%) rB,|B,B,B \ ANS%(ANS$) a ANS% (CMD%)  ,,@,I f (ANS$) H : ANS%((ANS$,))s p ANS%K ANS%M CMD%CMD%  z ANS%P ANS%H CMD%CMD%   4 : read/write/edit sector : ,,: 2 : display track/sector infoE MSG$"READ": ,3: ,:OLD.DRIVE%DRIVE%:DRIVE% I%  :  0: ESC%  : CR% DRIVE%OLD.DRIVE%:  DRIVE%DRIVE%(ANS%(I%)): I% DRIVE% DRIVE%MAX.DRIVE%   ,:OLD.SECTOR%SECTOR%:SECTOR%d I%  :  0: ESC%  : CR% SECTOR%OLD.SECTOR%:   SECTOR%SECTOR%(ANS%(I%)): I% SECTOR% SECTOR%MAX.SECTOR%   2 : display ABS-SEC, TRK, SEC, OFFSET info& t' : request disk@0 ' : initialize disk^: <( : build BPBD NUM.SEC%: ( : read sectorN h) : deactivate diskX ) : release disk : SOURCE.COL%:SOURCE.ROW%:NUM.COL%H:NUM.ROW%= * : blank data display regionv DPY.LINE% :BUFFER.OFFSET%(DPY.LINE%) 3 : display one line (16 bytes) of buffer DPY.LINE% BUFFER.OFFSET% DPY.LINE% : MSG$"DISPLAY": ,3? DPY.LINE%,(BUFFER.OFFSET% ) ^ ANS$: ANS$""   ANS$(((ANS$,)) _) : trim & xvt to uppercase ANS$ESC$  : exit to main menu ANS$"R"  : read new sector4 ANS$"W"  : write sectorg* ANS$"E"  : edit sector dataH : scroll through sector(s)R ANS%: I% : ANS$("M"()"PQK"()"HI",I%,) ANS%I% \ I%: ANS%  : NEW.DPY%FALSE%;f ANS% *,\+,+,$,,,,,,P-,-Gz  d : write sector} MSG$"WRITE": ,3$ OLD.DRIVE%DRIVE%:OLD.SECTOR%SECTOR%:DRIVE%:SECTOR%. ,: I%  :  0: ESC%  : CR% DRIVE%OLD.DRIVE%: B:8 DRIVE%DRIVE%(ANS%(I%)): I%gB DRIVE% DRIVE%MAX.DRIVE% .L ,: I%  :  0: ESC% . : CR% SECTOR%OLD.SECTOR%: `V SECTOR%SECTOR%(ANS%(I%)): I%` SECTOR% SECTOR%MAX.SECTOR% L:j MSG$"CONFIRM": ,3: ,dt ANS$: ANS$"" t : ANS$;~ ANS$"Y" ANS$"y"   t': ': <(: ): h): ) MSG$"WRITING": ,3 t': ': <(: (: h): )  & : edit sector data> MSG$"EDIT": ,3p ,:  0: ESC%  : BYTE%ANS% ,:  0: ESC%  : BYTE%BYTE%ANS% DSVARPTR(BUFFER$,LENGTH%,SEGMENT%,OFFSET%)   RPOKE(SEGMENT%,OFFSET%BUFFER.OFFSET%,BYTE%): DPY.LINE%,(BUFFER.OFFSET% ) W ("0"(BYTE%),);( DPY.LINE%,(BUFFER.OFFSET% )?2 BYTE% BYTE% (BYTE%); : ".";< BUFFER.OFFSET% *:    : copy disk sector(s). (,k)((,),,BFV ,: "C O P Y S E C T O R S" SOURCE.DRIVE%: ,,: "Source Drive: ";("00"(DRIVE%),);: ,,, I%  :  0: ESC%  : CR% SOURCE.DRIVE%DRIVE%:  1 SOURCE.DRIVE%SOURCE.DRIVE%(ANS%(I%)): I%l  SOURCE.DRIVE% SOURCE.DRIVE%MAX.DRIVE% P START.SECTOR%: ,,: "Starting Sector: ";("00"(SECTOR%),);: ,/,Z I%  :  0: ESC%  : CR% START.SECTOR%SECTOR%: nLd START.SECTOR%START.SECTOR%(ANS%(I%)): I%n START.SECTOR% START.SECTOR%MAX.SECTOR% P NUM.SECTOR%: ,,: "Number of Sectors: 000";: ,1, I%  :  0: ESC% P : CR% NUM.SECTOR%: H NUM.SECTOR%NUM.SECTOR%(ANS%(I%)): I%v NUM.SECTOR% NUM.SECTOR%  START.SECTOR%NUM.SECTOR%MAX.SECTOR%  DEST.DRIVE%:  ,,: "Destination Drive: ";("00"(DRIVE%),);:  ,1P" I%  :  0: ESC%  : CR% DEST.DRIVE%DRIVE%: 6, DEST.DRIVE%DEST.DRIVE%(ANS%(I%)): I%6 DEST.DRIVE% DEST.DRIVE%MAX.DRIVE% | DEST.SECTOR%:  ,,: "Starting Sector: ";("00"(SECTOR%),);:  ,/,c I%  :  0: ESC%  : CR% DEST.SECTOR%SECTOR%:  DEST.SECTOR%DEST.SECTOR%(ANS%(I%)): I% DEST.SECTOR% DEST.SECTOR%MAX.SECTOR% | DEST.SECTOR%NUM.SECTOR%MAX.SECTOR% | :2 LOOP% NUM.SECTOR% SOURCE.DRIVE%DEST.DRIVE%  ,: "Insert SOURCE disk & press ENTER "; SOURCE.DRIVE%DEST.DRIVE% ANS$: ANS$CR$  SOURCE.DRIVE%DEST.DRIVE% ANS$ESC$ > DRIVE%SOURCE.DRIVE%:SECTOR%START.SECTOR%LOOP%j t': ': <(: (: h): ) SOURCE.DRIVE%DEST.DRIVE%  ,: "Insert DESTINATION disk & press ENTER "; & SOURCE.DRIVE%DEST.DRIVE% ANS$: ANS$CR$ &; + SOURCE.DRIVE%DEST.DRIVE% ANS$ESC$ q 0 DRIVE%DEST.DRIVE%:SECTOR%DEST.SECTOR%LOOP% : t': ': <(: ): h): ) D LOOP% W  @ : analyze disk ^ (,k)((,),,BF!h ,: "A N A L Y Z E D I S K"4! OLD.DRIVE%DRIVE%J! DRIVE%: ,! "Drive Number: ";("00"(OLD.DRIVE%),);: ,-,! I%  :  0: ESC%  : CR% DRIVE%OLD.DRIVE%: ! DRIVE%DRIVE%(ANS%(I%)): I%," DRIVE% DRIVE%MAX.DRIVE% P" ,: " ";" : analyze boot block information" :" START.SEC%:NUM.SEC%"& t' : request disk"0 ' : initialize drive #: <( : build BPB+#D ( : read sectorO#N h) : deactivate diskp#X ) : release disk#b ,  AS BOOT$#l :#v # ,: "Booter Jump ";: (BOOT$) "No" : "Yes"$ ,: "OEM Name/Vers ";(BOOT$,,)I$ ,: "Bytes/sector ";((BOOT$, ,))$ ,: "Sectors/gran ";((BOOT$,,))$  ,: "Reserved sectors ";((BOOT$,,))$  ,: "Number of FATs ";((BOOT$,,))$%  ,: "Root DIR entries ";((BOOT$,,))Z% ,-: "Number of sectors";((BOOT$,,))% ,-: "Media Descriptor ";(((BOOT$,,)))% ,-: "Sectors per FAT ";((BOOT$,,))& ,-: "Sectors per Track";((BOOT$,,))8&  ,-: "Number of Heads ";((BOOT$,,))o&  ,-: "Hidden Sectors ";((BOOT$,,))& ! MAX.SECTOR%((BOOT$,,))&*! SECTOR.SIZE%((BOOT$, ,))&4! TRACK.SIZE%((BOOT$,,))&>! MEDIA$(BOOT$,,)'! :2'!  ,-,: "Locate Sectors (Y/N) ";\'! ANS$: ANS$"" ! : ANS$;'! (ANS$,)"Y" (ANS$,)"y" '(# : find & list disk sectors'-# (,k)((,),,BF: ,: "L O C A T E S E C T O R S"(2# t' : request diskF(<# ' : initialize disk drived(F# <( : build bpb(P# NUM.SEC%: ,: "Track";: ,+: "Sector";(Z# : locate/read each sector on disk(d# BAD.SECTOR%: SECTOR% MAX.SECTOR%O)n# (SECTOR% TRACK.SIZE%) ,!: ("00"((SECTOR%TRACK.SIZE%)),);w)x# ( : read sector)# ,2: ("00"(SECTOR% TRACK.SIZE%),);*# BIOS.ERR% , : "Bad Sector: ";: ("00"(SECTOR%),);:BAD.SECTOR%BAD.SECTOR%G*# ANS$: ANS$ESC$ # : bailoutY*# SECTOR%c*# :*# h) : deactivate disk*# ) : release disk*#  ,: "Bad Sectors Found: ";: BAD.SECTOR% "None"; : BAD.SECTOR%;.+#  ,,: "Press ANY key to continue: ";M+# ANS$: ANS$"" #Y+# +' : perform BIOS interrupt function+' I%  :(SREG$,(I%),)(SREG%(I%)): I%+$' DBSYSINT(INTERRUPT%,SREG$,RREG$)1,.' (RREG$) BIOS.ERR%FALSE% : BIOS.ERR%TRUE%::GOSUB 100508,8' j,B' "BIOS Error ";("0"((RREG$)),);"h";,L' ", Interrupt ";("0"(INTERRUPT%),);"h";,V' ", Function ";("0"((SREG$)),);"h" -`' h): ): "Press any key to continue: "; : release+-j' ANS$: ANS$"" j'2-s' T-t' : request disk drivez-y':PRINT "Requesting disk device"-~' INTERRUPT% W: I%  :SREG%(I%): I%-' SREG%(AX%) -' '-' -' : initialize disk device.':PRINT "Initializing disk device"P.' INTERRUPT% W: I%  :SREG%(I%): I%d.' SREG%(AX%) o.' '.( SCRATCH.SEG%((RREG$,(DS%),)). ( SCRATCH.OFF%((RREG$,(SI%),)).;( .<( : build BPB/A(:PRINT "Building BPB"4/F( INTERRUPT% W: I%  :SREG%(I%): I%O/P( SREG%(AX%) DRIVE%l/Z( SREG%(DS%)SCRATCH.SEG%/d( SREG%(SI%)SCRATCH.OFF%/n( SREG%(CX%)(MEDIA$)/x( '/( SCRATCH.SEG%((RREG$,(DS%),))0( SCRATCH.OFF%((RREG$,(SI%),))0( )0( : read sectorG0(:PRINT "Reading sector"x0( INTERRUPT% W: I%  :SREG%(I%): I%0( SREG%(AX%) DRIVE%:SREG%(BX%)(MEDIA$):SREG%(CX%)0( SREG%(DX%)SECTOR%1( DSVARPTR(BUFFER$,LENGTH%,SEGMENT%,OFFSET%),1( SREG%(DS%)SEGMENT%:SREG%(SI%)OFFSET%71( '>1) ]1) : write sector(s){1 ):PRINT "Writing sector"1) INTERRUPT% W: I%  :SREG%(I%): I%1) SREG%(AX%) DRIVE%:SREG%(BX%)(MEDIA$)2") SREG%(CX%):SREG%(DX%)SECTOR%42,) DSVARPTR(BUFFER$,LENGTH%,SEGMENT%,OFFSET%)p26) SREG%(DS%)SEGMENT%:SREG%(SI%)OFFSET%:SREG%(FLAGS%){2@) '2g) 2h) : deactivate disk device2m):PRINT "Deactivating disk device"3r) INTERRUPT% W: I%  :SREG%(I%): I%3|) SREG%(AX%) 3) ''3) J3) : release disk deviceo3):PRINT "Releasing disk device"3) INTERRUPT% W: I%  :SREG%(I%): I%3) SREG%(AX%) 3) '3/* 30* : scroll portion of screen display'4:* INTERRUPT% Q: I%  :SREG%(I%): I%`4D* SREG%(AX%) :SREG%(BX%)(DEST.COL%)DEST.ROW%4N* SREG%(CX%)(NUM.COL%)NUM.ROW%4X* SREG%(DX%)(SOURCE.COL%)SOURCE.ROW%4b* ' : perform BIOS interrupt4* 5* : blank screen regionC5* INTERRUPT% Q: I%  :SREG%(I%): I%W5* SREG%(AX%) 5* SREG%(CX%)(NUM.COL%)NUM.ROW%5* SREG%(DX%)(SOURCE.COL%)SOURCE.ROW%5* ' : perform BIOS interrupt5* 6* : advance one byte (right arrow)6+ BUFFER.OFFSET%(BUFFER.OFFSET%) : BUFFER.OFFSET% SECTOR%MAX.SECTOR% BUFFER.OFFSET%6+ BUFFER.OFFSET% SECTOR%SECTOR%: t': ': <(: (: h): )7 + (BUFFER.OFFSET% ) DPY.LINE%DPY.LINE%n7+ DPY.LINE% DEST.COL%:DEST.ROW%:SOURCE.COL%:SOURCE.ROW%:NUM.COL%H:NUM.ROW%: 0*7*+ DPY.LINE% DPY.LINE%: .74+ J.7[+ 7\+ : advance to end of line (shift/right arrow) 8f+ BUFFER.OFFSET%BUFFER.OFFSET% 8p+ J.8+ K8+ : advance 16 bytes (down arrow)q8+ BUFFER.OFFSET%BUFFER.OFFSET%8+ DPY.LINE% DEST.COL%:DEST.ROW%:SOURCE.COL%:SOURCE.ROW%:NUM.COL%H:NUM.ROW%: 0*9+ BUFFER.OFFSET% SECTOR%MAX.SECTOR% BUFFER.OFFSET%9+ BUFFER.OFFSET% BUFFER.OFFSET%BUFFER.OFFSET% :SECTOR%SECTOR%: t': ': <(: (: h): )9+ DPY.LINE% DPY.LINE%DPY.LINE% : .9+ J.9#, :$, : advance 256 bytes (shift/down arrow)F:), SECTOR%MAX.SECTOR% BUFFER.OFFSET% ,u:., BUFFER.OFFSET%(BUFFER.OFFSET%) :3, BUFFER.OFFSET% SECTOR%SECTOR%:8, NUM.COL%H:NUM.ROW%:SOURCE.COL%:SOURCE.ROW%: *:B, J.:L, |.:, +;, : backup one byte (left arrow);, BUFFER.OFFSET%(BUFFER.OFFSET%) : BUFFER.OFFSET% SECTOR% BUFFER.OFFSET%;, BUFFER.OFFSET% SECTOR%SECTOR%: t': ': <(: (: h): )<, (BUFFER.OFFSET% ) DPY.LINE%DPY.LINE%}<, DPY.LINE% DEST.COL%:DEST.ROW%:SOURCE.COL%:SOURCE.ROW%:NUM.COL%H:NUM.ROW%: 0*<, DPY.LINE% DPY.LINE%: .<, J.<, <, : backup to beginning of line (shift/left arrow)=, BUFFER.OFFSET%BUFFER.OFFSET% (=- J./=O- Y=P- : backup 16 bytes (up arrow)=Z- BUFFER.OFFSET%BUFFER.OFFSET%=d- DPY.LINE% DEST.COL%:DEST.ROW%:SOURCE.COL%:SOURCE.ROW%:NUM.COL%H:NUM.ROW%: 0*>n- BUFFER.OFFSET% SECTOR% BUFFER.OFFSET%>x- BUFFER.OFFSET% BUFFER.OFFSET%BUFFER.OFFSET% :SECTOR%SECTOR%: t': ': <(: (: h): )>- DPY.LINE% DPY.LINE%DPY.LINE% : .>- J.>- ?- : backup 256 bytes (shift/up arrow)6?- SECTOR% BUFFER.OFFSET% .e?- BUFFER.OFFSET%(BUFFER.OFFSET%) ?- BUFFER.OFFSET% SECTOR%SECTOR%?- NUM.COL%H:NUM.ROW%:SOURCE.COL%:SOURCE.ROW%: *?- J.?- |.?. @. : display current lineV@". BUFFER.OFFSET% SECTOR%MAX.SECTOR% SECTOR%SECTOR%@,. BUFFER.OFFSET% SECTOR% SECTOR%SECTOR% A6. BUFFER.OFFSET% BUFFER.OFFSET% t': ': <(: (: h): ):BUFFER.OFFSET%(BUFFER.OFFSET%) A@. 3AI. LAJ. : update track/sector/offset infoqAT. ,: ("00"(SECTOR%),);AY.  ,: ("00"(SECTOR% ),);A^. ,: ("00"((SECTOR%TRACK.SIZE%)),);Ah. ,: ("00"(BUFFER.OFFSET%),);B{. 'B|. : display full screenzB. OLD.DPY.LINE%DPY.LINE%:OLD.BUFFER.OFFSET%BUFFER.OFFSET%:OLD.SECTOR%SECTOR%B. BUFFER.OFFSET%(BUFFER.OFFSET%((DPY.LINE%))) B. DPY.LINE% PC. BUFFER.OFFSET% SECTOR% SECTOR%SECTOR%: t': ': <(: (: h): ):BUFFER.OFFSET%BUFFER.OFFSET%C. BUFFER.OFFSET% SECTOR%MAX.SECTOR% SECTOR%SECTOR%: t': ': <(: (: h): ):BUFFER.OFFSET%BUFFER.OFFSET%D. 3:BUFFER.OFFSET%BUFFER.OFFSET%: DPY.LINE%iD. DPY.LINE%OLD.DPY.LINE%:BUFFER.OFFSET%OLD.BUFFER.OFFSET%:SECTOR%OLD.SECTOR%D. BUFFER.OFFSET% BUFFER.OFFSET% BUFFER.OFFSET%(BUFFER.OFFSET%) D. D 0 : input HEX nibbleE0 ANS$: ANS$"" 08E 0 ANS%: ANS$"9" ANS$((ANS$) _)E*0 LOOP% : ANS$("0123456789ABCDEF",LOOP%,) ANS%LOOP%E40 LOOP%E>0 ESC%FALSE%: ANS$ESC$ ESC%TRUE%EH0 CR%FALSE%: ANS$CR$ CR%TRUE%ER0 ANS% ANS$;+F\0 ANS% ESC%FALSE% CR%FALSE% 02Fo0 dF2 : display track, sector, offset infoF2 ,: "DRV";: ,: ("00"(DRIVE%),);F2 ,: "ABS";: ,: "SEC";F2 ,: ("00"(SECTOR%),);F2 ,: "TRK";(G2 ,: ("00"((SECTOR%TRACK.SIZE%)),);=G3  ,: "SEC";gG3  ,: ("00"(SECTOR% ),);G3 ,: "SECTOR";: ,: "OFFSET";G"3 ,: ("00"(BUFFER.OFFSET%),);G+3 G,3 : display vertical message,H63 MSG$"" MSG$" " : (MSG$) MSG$(MSG$, )PH@3 I%  : I%,: " ";: I%HJ3 I% (MSG$): I%,: (MSG$,I%,);: I%H3 H3 : display line from sector bufferH3 DPY.LINE%,: ("00"(BUFFER.OFFSET% ),);" ";I3 DPY.LINE%, :NI3 LOOP%(BUFFER.OFFSET% ) (BUFFER.OFFSET% )I3 DSVARPTR(BUFFER$,LENGTH%,SEGMENT%,OFFSET%)I3 RPEEK(SEGMENT%,OFFSET%LOOP%,BYTE%)I3 ("0"(BYTE%),);" ";: LOOP%: " ";J3 LOOP%BUFFER.OFFSET% BUFFER.OFFSET%EJ3 DSVARPTR(BUFFER$,LENGTH%,SEGMENT%,OFFSET%)rJ3 RPEEK(SEGMENT%,OFFSET%LOOP%,BYTE%)J3 CHAR$".": (BYTE% ) CHAR$(BYTE% )J3 CHAR$;: LOOP%JW4 JhB : main menu choicesKrB ,,: "Edit Disk Sectors";::K|B ,,: "Copy Disk Sectors";:\KB ,-,: "Analyze Disk";:~KB ,-,: "Exit ZAP-600";:KB : display startup messageKB : : (%,)(,n),,BF: ([,*)(,+),,BF LB (,*)([,U),: (,+)([,V),=LB ([,U)({,V),,BF: (,*)(y,P),kLB (,*)(|,P),: (,*)(],P),LB (,*)(`,P),: (,?)((,@),,BFLC (,*)(q,P),: (,+)(q,Q),LC (,*)(~,*),: (,+)(~,+),,MC (~,*)(?,?),: (~,+)(?,@),QM&C :DPY$"600":  ,',: DPY${M0C  ,,: "Copyright (C) 1988 by";M:C  ,",: "Rick Richmond": MC MI : display register contentsMI "SREG$:"NI I% : "\\ "; ("0"(((SREG$,I%,))),);: I%:/NI "RREG$:"tNI I% : "\\ "; ("0"(((RREG$,I%,))),);: I%:{N7J N8J :NBJ  NN "Error";;"at line";;"in ";PROG$: N :N N "$$Buffer.$$$"N ,,:O O O O