IMD 1.18: 19/12/2012 16:29:20  Jade DD Double density format 20?8ڲ! `7O.!`m :g     !!:>ۀw# :(<22wv!:_+V+^Sx+V+^Sz:<2s2q2r<2pv ÀpC1pV !>1pv@B  *z ͑r͑á ABI2Ee:p_!^#V!"KU:sw͑2r<2s͑r^!w6( (@@::qݾ(1X::q2!"=e2we(. : P- :.e -(PP>w>! #:w:w:w ͑ (ϯ<ɀJade DD $!Î1pV !>>2s@!rCAJ&͎&͎G&͎O:IoCAC&͎͎G&͎Ö́G̈́(  ̈́> yy   ? LOAD ERROR ILL. SYS. CALL Jade DD 6ET#c30 !%)- "&*. #'+/  $(,0Ľ!ͬʧ )!F#xʺ~0wëw!" !~6ͽ:ý(!1͘A͌>>͌92^ :¥.!_~#fow]!v"!çREAD ERRORçNO FILE^: w4!Y~ʆ͌†t=ʆf ^ T 2o&)|+!<ͧADCOMf^: ! Â$$$ SUBҐ^H@Oy H H: –ͬ  #H: !  Hù H H $O͐: 2 *CN# O*!O*|!6ʝ6>*w#w*w#w'û*! J*""!N#F*^#V*~#foyx*{_zW+**{#zr+s{ozg**͕** ,w͜͸Ͳ!!N#F$**O!~#T D^6k-äPYy 5*{zBK52>2ͻ:!Z2:Eẅ́͊Ͳ>i6}2ExN! ~态O>G~G!~G} *C!r#r#r ^ͥ_y#x#{:ʑw:2E**E}DQ>2\X COPYRIGHT (C) 1979, DIGITAL RESEARCH #͘*~ "޷"͌#>?͌͘ =_.:;<> Oޅo$>!Y2*O"ʉ@ ! ~ 3#0 Wx x ހ ނ G ~ # 3x~#B!Y~ɯ2:=!ý:=!:ý^T!ÆNO SPACE^ :Ty!B*O=?_s#"^sG!~Ypsp2mÆÆf ͧ"C{2!"E9"1A22!ty)K!G_^#V*C~E ,x: 2 p&x~+é72 H! >w_: ! 5ͤNkͱ¦ͱxʊ#Nyx#*DM*s#r*s#ryOxG*0MD!!N: EG>O: \S*C :qn& ^#V>O^"**#"͕: 2Þy<_WyOxOxG* ~V5dw^ :ʈ *C ^OT *C~wD -'  -@ͦ~^*C Ox! N!Fwy2>2T*CGͻ:ẅ́n>2;O ^DM;}H>"*C ::ddslO s#r:E͊:==»s+p+q-*C ͥ!!q#p#w*:BOYG}*MD "ã:!Bw!>2*C~=2u:B2~2wE:A*Cw>"I|46;@RWF 62k CP/M vers 2.2 1>>~!T]6 b:22!3û1_͌> ͒> Ò> Ò͘~#͌ì _2<ܯ2G:ʐ:wÖx2p0ʹ#*©6?ëw˜0ï#6 ¹.0#*6?w0#6 #6" ~  6?#ˆ:`O> K{͘A͒>:͒͢>:͒͢xK > K > ͒x FILE EXISTS _: É: :ʉ=2)ͽÉ T!@k!}|q&-AGMS!!ô!ô!Bdos Err On : $Bad Sector$Select$File R/O$:BA2!~6x: ! 2 ͤ! 5™#wO~x½p Hy<< ʑ :!qMD#"*}:*)=":O:o"*C *C!ͮ~2~2ͦ:2ͮ:O:w:w |g}o*# NÎ N#Fyʝ*}|\#u*#DM*6# x±**s#r͡*6#6^>:A#~$=2Ek͌xʋ>ڋ>*Cw~#+w#w+ɯ2E22i^ *C :~w~͔͔# # y==»*Ww#*"͸*:G#š"͸:!w4!iw:Z!E~=26!""2B!"!rQQQâ~?ͦ~?rQ*"CQ-Q͜QüQrQ$Q*@4;,R|*":ڲ!4<2”>2!"2!"28!"9:O  ! ݇!2:2a{_:ʖ:>Ľʖ:=2–!B!6#5ʖ:#~?  xDIR ERA TYPESAVEREN USER!yO#< Ty#O 3߯21y_͸2y2ͽ:ܷ ͢ØÆ^ BRͧ9!5‚#~Y‚#"T<ÆALL (Y/N)?^ Tʧ͘!6!~ڇ=qf^!~2>`~22\!!B!~> >#0~O#Cx2͘1)ͽÂf zͧÆBAD LO O͐  :E B 2>: b# : y! 4 5~yy5 6y2E>! ^#V w#P:BO|^#V#"##"##"##"! ):BO!yoxg*:BO}!N#F "*#*s#r^ ~!J! J*:o$*C~i6iw*::/GyO>2!q*C"͡ʔ*JҔ^:Oyʃ?|x | s-|N-#  w ~>2!E5T*C!"C"C!w# F! w͌x2͢*C ~<wʃG:!ʎ2*C!!~~#~O~G#n,-.‹! w! yG!x͢.:E<ʄ! q!pQ:E<. ʄ$.:E<ʄ):B"*)*)Q;*"E:;:A2AQÓQÜQ*C}/_|/*W}_*"}o|g":ʑ*C6:wn&6!y2! ~2`i))))!qy2i`"`i#z n&Y!~w !w ͷ:>ƒyxz0 !%)- "&*. #'+/  $(,0PRT PLMoPIP COM:ODEBUGL COM TOD COM5 LSYSGEN1 Z805BCDEOLDPROM COMcdP68764 OV eTOD COMKmz{|}OLDPTESTOV lPIP COM:SYSGEN Z80kSYSGEN COM $TITLE('ISIS PRT UTILITY PROGRAM V1.6') PRT: /* V1.6 11 FEB 82 This utility will print an ISIS file to :LP:.  will issue a page eject following the file listing. S will skip 5 lines following the file listing. K will su file FOO.SRC 5 times, use the command PRT FOO.SRC R5 L will output a skip to top of page aftehe H switch is used). Consecutive form feeds are suppressed so that only one page will be ejected. If it is dr at the top of each page. "title" may be from 0 to 45 characters long, and is included in the header. If no title aging is also specified, handy for source files) O will overstrike on the printer output. Primarily used. Ex: to overstrike the words 'IDEN$TIFIER', '65476', 'YOURNAME', the following construct is used: O/Ie will add that list of reserved words to the list of words to be overstruck. Ex: overstrike a PLM/80 prograDDISKDCMZ80 HDMON Z80 !"#$%12345DDISK RELHDMON Z80FGGTOD Z80!TVZP2708 OV gASMZCV C 2nopqASMZCV COM"rstTab characters (^I) are expanded into spaces. PRT is invoked by the command: PRT W D P S K R L H"title" O// where W, D, P, S, K, R, L, H and O are optional switches: W will print wide left beginning of the listing if the H switch is used. R will print the file 'cnt' times, where 'cnt' is an intomitted, no page formatting (other than that explicitly determined by the location of form feeds in the file) is  Ex: to list a file at 30 lines to the page, use the command PRT FILE.EXT L30 to lier except ';' or a space, allowing the text string to contain quotes. Ex: to output a title to the listing c constant-reserved word type character strings. A "word" is defined by any combination of 'A'-'Z', 'a'-'z', words since the '-' character acts to delimit "MULTI", "PART" and "WORD". To include a subset of reserved wle occurrances of the "O" switch is permitted. Each will add to the list of words to be overstruck. If ?@AP2716 OV iP2764 OV jP27128 OV kDDISKF Z80zmargins (7 spaces) so that holes may be punched. D will double-space text lines to ease in editing. P eger between 0 and 65535. If 'cnt' is omitted, the file will be printed 0 times. Ex: to print the produced. Any form feeds in the file will cause a skip to the top of the next page and the output of a header (if tst a file at 60 lines to the page (default), use the command PRT FILE.EXT L H"title" prints a headeof PROG1.SRC, use the command PRT PROG1.SRC L H"Nebutron Integrator, Ver 32.7" (note that p '0'-'9', and '$'. Any other character acts as a word delimiter. Words located between comment brackets will be ignorords from a programming language such as PLM/80, FORTRAN, etc., a '*' preceding a valid reserved word list name> is not a legal ISIS file name, PRT will return to ISIS with a non-fatal error. */ $EJECT DO; DECLARE CR LIT0 !%)- "&*. #'+/  $(,0ERALLY '0DH', FF LITERALLY '0CH', LF LITERALLY '0AH', TAB LITERALLY '09H',  SPACING IS REQUESTED */ PAGE, /* TRUE IF PAGE EJECT AFTER LISTING IS REQUESTED */ HEADER, /* TRUE IF FORM FEEDS ARE TO BE SUPPRESSED AT START */ PCNT /* COUNTER USED IN "Printed..." OUTPUT */ OF TIMES TO PRINT FILE */ DISCBUF$INDX, /* INDEX INTO DISC BUFFER */ RESLIST$INDX, /* POINTER INTO RESUT */ FNAM(20) BYTE, /* BUFFER FOR FILE NAME TO OPEN */ DISCBUF(8000H) BYTE, /* DISC BUFFER */R5(*) BYTE DATA ('Illegal device name'); DECLARE OPEN$ERR13(*) BYTE DATA ('No such file'); DECLARE OPEN$ERR22(*) BYTE DACR,LF, '(c) 1981 Lockheed PARL, Palo Alto, CA By Greg Kremer',CR,LF,LF); DECLARE DEFAULT$LIST(DEFAULTS) STRRD IS TERMINATED BY '!' */ 'THEN!', 'ELSE!', (INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)ABORTED$BAD PARAMETER$INVALID USER NUMBER$RECORD TOO LONG$INVALID DIGIT$END OF FILE, CTL-Z?$CHECKSUM ERROR$CORRECT ERROR, TYPE R221@:2!o6+6+6!6#6!6#6:G*o .!N6:^*M^!K6!6!6+6' :$HHͯ :^!w:<2:0}:@E}:!S!W6: z!]6:cm!c6:_z!_6l TRUE LITERALLY '0FFH', FALSE LITERALLY '0', MAXLEN LITERALLY 'LENGTH(RESLIST)-1',  /* TRUE IF HEADER IS TO BE OUTPUT AFTER PAGE EJECT */ SPACE, /* TRUE IF 5 LINE SPACE AFTER LISTING IS REQUES ) BYTE; DECLARE (AFN1, /* AFTN OF FILE TO BE PRINTED */ AFNLP, /* AFTN OF :LP: */ LIST */ BUFLEN, /* CHAR COUNT RETURNED BY 'READ' */ TXTINDX, /* TEXT BUFFER INDEX */  RESLIST(500) BYTE; /* LIST OF RESERVED WORDS */ DECLARE ERR1(*) BYTE DATA ('Missing text delimiter'); TA ('Illegal file/device for input'); DECLARE OPEN$ERR23(*) BYTE DATA ('No filename given for disk file'); DECLARE COPUCTURE /* LIST OF DEFAULT LIST NAMES */ (NAME(5) BYTE, /* LIST'S NAME */  'END!', 'WHILE!', 'TO!', (INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)ETURN OR CTL-Z$INVALID FORMAT$HEX$$$$NO DIRECTORY SPACE$NO FILE$COM$START NOT FOUND$QUIT NOT FOUND$CANNOT CLOSE DESTINATION FILE::=2K  :ʤ\:ҷ\x'Ͳ:!\͢  :͈'!  ::,: HHҰͯ : 2ó:E:1:2v!q!*8!*6: > DEFAULTS LITERALLY '1'; /* CURRENT NUMBER OF DEFAULT LISTS */ DECLARE (COMMENT, /* TRUE IF SEARCH IS PRESENTED */ OVERSTRIKE, /* TRUE IF OVERSTRIKING IS REQUESTED */ CCFLAG, /* CARRIAGE CONTROL FLAG RETU LOOPCNT, /* COUNTER FOR PRINT LOOPS */ LINECNT, /* NUMBER OF LINES PER PAGE */ LINE$ FLEN, /* LENGTH OF FILE NAME STRING */ ERRS /* ISIS ERROR RETURN LOCATION */ )  DECLARE ERR2(*) BYTE DATA ('Undefined reserved word list'); DECLARE ERR3(*) BYTE DATA ('Reserved word buffer is full'); Y(*) BYTE INITIAL ('Printed: XXXXX copy ',CR); DECLARE PLURAL(*) BYTE DATA ('ies'); DECLARE MARGIN(*) BYTE DATA ('  LIST$LOC ADDRESS) /* ADDRESS OF LIST */ DATA ('PLM80', .PLM80$RESLIST);  'BY!', 'CASE!', 'CALL!',  COPYRIGHT (C) 1979, DIGITAL RESEARCH, PIP VERS 1.5$$$ SUB =.:,<> _[]INPIRDPTRUR1UR2RDROUTLPTUL1PRNLSTPTPUP1UP2PU$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$$$$$$$NOT FOUND$COPYING -$REQUIRES CP/M 2.0 OR NEWER FOR OPERATION.$UNRECOGNI:$: $͈Ͳ!N6' :!Cwͯ !6:^͢c!6{:/>!/H{ͯ :<2ͦ>ͦ!q:_  !p+q.*   !q*&!p+q*2TLY IN A COMMENT */ WIDE, /* TRUE IF WIDE MARGINS ARE SELECTED */ DOUBLE, /* = 2 IF DOUBLERNED BY 'READREC' */ NEWPAGE, /* TRUE IF NOTHING HAS BEEN PRINTED ON CURRENT PAGE */ SUPPRESS, NUM, /* LINE COUNTER FOR CURRENT PAGE */ PAGENUM, /* PAGE COUNTER */ REPCNT, /* NUMBER ADDRESS; DECLARE TXTBUF(150) BYTE, /* BUFFER FOR TEXT */ HEADBUF(80) BYTE, /* BUFFER FOR HEADER OUTP DECLARE ERR4(*) BYTE DATA ('Unrecognized switch'); DECLARE OPEN$ERR4(*) BYTE DATA ('Illegal filename'); DECLARE OPEN$ER '); /* 7 SPACE MARGIN FOR WIDE PRT */ DECLARE SIGNON(*) BYTE DATA (CR,LF, 'ISIS-II File Print Utility V1.6', DECLARE PLM80$RESLIST(*) BYTE DATA ('DO!', /* PLM-80 RESERVED WORDS */ 'IF!', /* WO 'RETURN!', 'OR!', 'AND!', NTTYCRTUC1CONNULEOFDISK READ ERROR$DISK WRITE ERROR$VERIFY ERROR$NOT A CHARACTER SINK$READER STOPPING $NOT A CHARACTER SOURCE$ZED DESTINATION$CANNOT WRITE$INVALID PIP FORMAT$CANNOT READ$INVALID SEPARATOR$1 :2L> ̈́M9 Š ::=HҮͯ !6:Ҿ:2 !6::/H͈;!6:> !/>!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*0 !%)- "&*. #'+/  $(,0!p+q* !q*& *M *M !p+q*!!p+q*"!p+q*$!6  "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{& :2!q: " *M n :c4 *M n :2!c:Q !c:2: !:cw>!n !5 Y : { !6!q/H:_2:!q:A/>Z!/H8: 2::=O>m:W!Q} Hmd>9>!6:2*M!E*M:>!(:=2%> >>!F!5+N! ~2!4<2T>>!b}*bMͭz:b2!b6:<2é>!*M8):[ͱ!N5!6ñ:5!6#6>!ڰ!6:<2O>/:!O!T *M͡H~K:÷:S:QHI:N<22: H@"2Í202O> c!6Í202O> ڍ*&O*-:>>!p+q:,!6*DM9:<!6:z 2W!6D*&L :w:<2Ov*:>= :e(''09 80}<( |}!{:e/ R>/~ NONEb*#R bR bR :Y![*M!h*M   BREAKPOINT:RETURN:REG SET: Alter/:Z2Zͣt9לg=|=(zpNܡ 6ָ_# JLE>2e>2eK {x_(  (( 7 ("_`{(w(> +w+>$ w*cp!RLINE TOO LONG c  !kp+q*j> >ڪ Þ !qp+q/ *pDM9: :M2r:N!r !:r *r& N!r4 !6: :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*M:!lwҙ  â :0O !q:O| :O| !6:]2l:o'2o:n'2n:m'2m*mMͣ *nMͣ *oMͣ :] ^#V͎ڗO **~2*#"m2m͖ 2m!6m!6m!6 m2m`ҥ*`MͭҞ!`6!6> :é:(!q:!wO! ~2*& :w>!:!4!6>:N<2N!¡!6[–ͱ!N5:2:2!4=:[¼ͱ4:!6:.2O8: :* ͇g& !sc*&P :w:·>!ұͯ :22:_!6=!6>'!E!4!p+q*0 !20O> ڒ:0:AO>Ҥ::A }}Hͬ!wͻO`idͻV[2O>2:!X!6:! SZ@HPNCFACBEDLH!:e(#!LGx808084G)))xoça8 GxG0:808 ))))oɯ2X2Y{!"nate Main FLAGS: REGISTERS: ABCDEHLI STACK PTRX INDEXY INDEX O A$Z' *-?LFCMGcBkRD[EH>=9 (K y>=9͙Y (S!A2 ͙x "{w#6:<2P !_Y(A* SLoPKL*F>O >G(>A KJKH KJKH 8\͔: :ͳ.!ws+p+q+p+q:w=2wN *s*u w*s#"s*u#"u' !"*M^7 !x6:!xھ **DM͆ ! ^#V͎ * :w*#" = = = = = ͯ  *M !6q  !6q  !6q  *& !:   *}2D" * * *&"!q:UY: Y:ҩ: ʩ:_2ʘ:€!6<ͯ m!62m!62m!62m!62m'2:2:TҒ:2> *N& N2 !p+q!6!6+6 !6: S: M!6g8:N2M*M8p!6!6!6>!:[ ͱ!N5!6:%:<2*6 * 6å!q!6> !d*&I :]>!4A>:<2O* :w:?†r+s+p+q*~$7*>*>H&>*#"*#"> 2:R͎:!6!6=2:ʙ!6:“H:=O!L NE!4 E E:/.*&L 6$L9k9.Xͯ *KM^0208͙!x`x @F##(G#:X*"8 R9>/9~ (# 6>=>2X^#Vѯs#1e*#~#fo+"2ZfQnIvPSY W #{ F]Y}(_:X* s#(*+(*k(/**#s#r{#:Y ͒ 2W6"*6":G( #!_Y( *+R (>  Filename: Drive: File not found! PHI-DECK ERROR: !!,0!*a#͕2yʭ :yʗ ͯ *"*6:2x÷ *"!x4d !"/ !j}=2| !"*KM^'_ !z6:|!z1 *6à  !6 à  !60à  *& !6  !6  !6  *& . 1 4 7 : = F P [ f q  :<2!ژ!6 >!]Ҥ; !6:Q::H: !6*M : !6!q:a/>z!!6*ME:2::Ҳ:<22ý: 2:} >ͯ :i:2:d*M:[ ڕ*&P 6!4z!6!6#6#6!6*M8:ھ:*͇g2ê::¿::,͡A<2O>!6!q!6?!:ҠgÐ!q*&*~!6:22: :]Hں:A2O>: 2ͯ 9Ž>!6-e!6ͻ2=2ʺ-é:>>"ͻ2:!!5ͻ2ͬ!\ :020:121'ͳ':²ͯ !G6!"!"7 *M^n/ :a/:H!6:ͯ !&6<2Y8!q:Z(!{!!!>2X9(>0(<> !#b~#V#b~bz bW!#^6g#V6S!*:Ww!"[!*s#r/Å/!9!(/# X Y IyGSC#y* TOO MANY ENTRIES, RETRY? (Y/N) SEQUENCE NOT FOUND, RETRY? (Y/N) *ap#z(w#BxP(Va8{0 !͙{2? @> ~˿#(~˿.(!@#F!0 !F#( =-.:;<>>>2 !@ OC0 !%)- "&*. #'+/  $(,0 O: \ ˿ #: (%^#VSH* CJ͇ >!@#~>7+˾K >2   ( ͇ K O/oG/gK "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{&P SUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAYJANUARYFEBRUARYMARCHAPRILMAYJUNEJULYAUGUSTSEPTEMBEROCTOBER#"M)! 9~#fo^#V͞"* 5* N*M)! 9~#fo^#VL**"9*M)! 9~#fo^#V"*^zʓ*^!*͞<"2'!EL**|T!}!!h !2!h !}!!?:8o&@}*;"*0!,Q!9^#V! 9~#fo .!FE!9^#V)! 9~#fo^#VErrorQ!"!l}!9^#V} Command Error: Q/_ DM!>22)) #}o|g1 :2=22 }:2=22 }DM!>))P =H }}/o|/g#}|ʡÒ|g}o{_ʙ | | 1 w# {o|g $ 1 w# !!|a{ !9^#V*:!9}|\ *:":|!Q!!!xJ!:o!!! ͢ g `i*#"+)<s#r`i#DM~g `i^! ͈U `i^! ͈d !`i#DM+sg / ß !<*͒͢ Ca^#V!@1!9^#V^! 9^#Vsz1!"!!9^#V!@h!9^#V#^! 9^#V#szh!"!! ^#V! 9^#V!s#r!H "J* 7OG " ! #~f?4 =( #@x/Gy/Oog +;;q#p #6s#r>2   :  :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*MNOVEMBERDECEMBERQ!2!h !9^#V!T!"!"M*M#"M+*M!9~#fo *!*M)! 9~#fo^#V!4W,͗ʓ*#"+n*^zʪ*#^z*M#"M)! 9~#fo^#V"*#"+*͞d"='!*M)! 9~#fo^#V!?*@  @ *@"!}! !*+}!}*9@!}*=!}*6@!9^#V^z!9^#V^! ͈ʮ! !9~#fo#s#r+^ÂQ!9^!h Q!9^#V! 0!7g}o {_ʙ )” }}o|gN#F# N#F#zڽ { ##^#VBK^#Vz #y ### #x #~#fo}|>?o&}|&@xs!} "<!xDM!"*j `i^! ͈ `i^! ͈ `i#DMì `i^zj `i^!>͈ !!9s#r `i^!<͈n't open file for redirection: Q-!9~#ʼ ! xW A:$$$.SUBQ!"!Q!con:CON:lst:LST:prn:PRN:9^#V##^! 9^#V##s!9^#V###^! 9^#V###s! ! 9^#V!s#r! 9^#V!9^#V!9^#V!9^#V!9^#V!^#VP! 9  2 * \!L ͙!Z ͙ Block ID = Blks to read/bytes to write = { !!?*M)!9~#fo^#V!ʹ"* M*M)! 9~#fo^#VL**}28'!*M)! 9~#fo^#V!9! !*M)! 9~#fo^#V!"*^z9*L**͞j "6!"2"4*^zʄ*^!:͗ʄ*#"!}*4!}*2!}!͢ DAY=DATE=TIME= >> (24 Hour)9^#V!@0Q!9^#V! ́͌ ! 9^#V!  j |g}o|/g}/o^#V#DM!99`iP|z23:3X }>o&{_ʙ |g}o |g}o~# x& !94~#= !J |ɧ*a W 1 k 1 *4DM*6o&1  !!9s#r`i#DM^! ͈. `i^! ͈1  `i!9s#r`i#DM~s `i^! ͈a `i^! ͈p !`i#DM+ss ; !9^#V!pun:PUN:rdr:RDR:Q! 9^#V!! 9^#V4Q![! 9s#r!!9s#rs! 9~#fos#r!9~#fo#s#r!9^#V! !!!9^#VQ!9^#V!<!9^#V! F!"!!9^#V)))[DM! ^#V! ^#VP!9s#r!! s! * *M)!9~#fo^#V!ʹ"* *M)! 9~#fo^#VL**#";*M!9~#fo *M)! 9~#fo^#VL**M+_*^!:͈ʚ*#"*^z*͞<"4*^z*^!:͗*#"+ü*^!:͈*#"*^z Press any key to set time. , 19 :: Q!"0*0#"0+*0! 9~#fo !*0)! 9~#fo^#V! 9^#V }}’|ʡ!}¡|ʒ!}|}|?>o&zo&|}|>o&|o&z23:3X ||/g}/o#z /W{ o&1 *4*+++*6DM*8!9N#F#^#Vkb6#> 6 #=´ >6#=½  : > A* [ @ a* {* `w# . $ 9~#ʥ !!9^#V!9s#rþ !!9^#V4!9s#r!9^#V!͈ !~ !Ϳ!9^#V!*! !*!ʝ! 9^#V!^#V! ͈§R!"!!DM÷`iDM`i~#!9^#V`i^#V͆ï! ^#V!9s#r!9^#V!@#!9s#r!9s! s`is! ! s#r!9^#VQ!DMò`i&DM`i* !% ^zê!"!! 9^#V͡ !"!! 9^#V!@0 !%)- "&*. #'+/  $(,0 LIST OFF LIST NOCOND FALSE EQU 0 TRUE EQU NOT FALSE INCLUD EQU FALSE LIST ON IF INCLUD EQ TRUE SUBTITLE DCM MODULE  (DCM) resides internal to the ; Jade Double D Disk Controller board. This program provides ; a facility to read/write diskermat. This program ; contains a 6 word timing block which should be patched to ; match the user's disk drives. ; This has no THESE PORTS AND CONTROLS CAN ONLY BE USED BY THE ONBOARD Z80. ; ; CONTROLLER PORT ASSIGNMENTS: ; BLSTS: EQU 0 ;BOARD STATOR TIME EXTEND XPDSH: EQU 80H ;DATA SYNC HOLD ; ; THE FOLLOWING ASSIGNS EACH BIT POSITION & FUNCTION OF THE ; BOARD CONTROL ; ; FUNCTION ASSIGNMENTS ; BCDSN: EQU BCDSA+BCDSB ;DRIVE # MASK BCSDS: EQU 0 ;SINGLE DENSITY BCDDS: EQU BCDDE ;DOUBLE DEN;TEST MODE SWITCH BSINT: EQU 00001000B ;HOST INTERRUPT REQUEST BSEIA: EQU 00010000B ;EIA SIGNAL LEVEL INPUT BSMOF: EQU 001000 FORMAT DCRDA: EQU 11000000B ;READ TRACK ADDRESS DCSTS: EQU 11010000B ;SET TYPE 1 STATUS OR ABORT ; CMD WITHOUT INT. DIII: ; CSTYPE: EQU 00100000B ;RECORD TYPE CSWFLT: EQU 00100000B ;WRITE FAULT CSRNF: EQU 00010000B ;RECORD NOT FOUND CSLDE: OT READY DMLDE: EQU 00000100B ;LOST DATA ERROR ; ; BASE ADDR FOR DCM ; BASE: EQU 1000H ;BASE ADDR ; ; MEMORY BANKS ;O COMMUNICATION ; IOBLK: EQU BANK0+370H ;I/O BLOCK BEGIN TPSTK: EQU IOBLK+0 ;TOP OF STACK CMDBK: EQU IOBLK+0 ;COMMAND BLOCK ****************** ; ; THE FOLLOWING AREA IS THE INITIAL START JUMP TABLE. ; THE 1ST JUMP IS EXECUTED WHEN THE ONBOARD Z80  ELSE TITLE DISK CONTROLLER MODULE ENDIF ;************************************************************* ; ; DISK CONTROtte sectors & format diskette ; tracks (in single & double density). This DCM sets the ; parameters for each drive during thrmally been set for Shugart SA800/801 drives. ; ;************************************************************* ; FORM ;***US PORT BLCTL: EQU 0 ;BOARD CONTROL PORT WDCMD: EQU 4 ;1791 COMMAND REGISTER WDSTS: EQU 4 ;1791 STATUS REGISTER WDTRK: EQU 5PORT (BLCTL). ; ; BIT ASSIGNMENTS ; BCDSA: EQU 00000001B ;DRIVE SELECT A (2*0) BCDSB: EQU 00000010B ;DRIVE SELECT B (2*1)SITY BCPCH: EQU BCPCA ;PRECOMP. - HEAVY BCPCM: EQU BCPCB ;PRECOMP. - MEDIUM BCPCL: EQU BCPCA+BCPCB ;PRECOMP. - LIGHT BCPCZ: 00B ;MOTOR OFF INDICATOR BSTSD: EQU 01000000B ;TWO SIDED DRIVE FLAG BSDCN: EQU 10000000B ;DISK CHANGE INDICATOR ; ; FOLLOWCIFI: EQU 11011000B ;FORCED INTERRUPT (NOT USED) ; ; STATUS BIT DEFINITIONS: ; ; TYPE I: ; CSDNR: EQU 10000000B ;DRIVE NEQU 00000100B ;LOST DATA ERROR CSDRQ: EQU 00000010B ;DATA REQUEST ; ; FOLLOWING CONTAINS ALL THE MASKS USED TO TEST THE 179 BANK0: EQU BASE+0 ;DEFINE BANK 0 BANKL: EQU 400H ;BANK LENGTH BANK1: EQU BANK0+BANKL ; ; RESTART VECTORS ; RST0: EQU B BUFBG: EQU IOBLK+10H ;SECTOR BUFFER FMTBG: EQU BANK1+300H ;FORMAT BUFFER FMTPS: EQU FMTBG+8H ;FORMAT PROGRAM ; ; TIMING CIS RESET. ; THE SECOND JUMP IS THE DCM ENTRY FROM A BOOTSTRAP LOADER. ; THIS ENTRY ASSUMES DCM HAS BEEN LOADED INTO DD BANK LLER MODULE (DCM) ; ; Algorithm property of: Jade Computer Products Inc. ; 4901 W. Rosecrans Blvd. e "LOG-ON" operation. ; The FORMAT program (not in this module) writes an ident- ; ification sector (0,0) which provides the ********************************************************* IF INCLUDE EQ FALSE ENTRY DCMMOD,DBUFR ; ;******************** ;1791 TRACK REGISTER WDSEC: EQU 6 ;1791 SECTOR REGISTER WDDTA: EQU 7 ;1791 DATA REGISTER ; ; CONTROLLER FUNCTION ASSIGNME BCDSE: EQU 00000100B ;DRIVE SELECT ENABLE BCEIA: EQU 00001000B ;EIA SIGNAL LEVEL OUT BCDDE: EQU 00010000B ;DOUBLE DENSITY ENEQU 0 ;PRECOMP. - OFF ; ; THE FOLLOWING DEFINES EACH BIT & FUNCTION OF THE BOARD ; STATUS PORT (BLSTS). ; BSUS0: EQU 000ING IS A LIST OF COMMAND CODES ISSUED TO THE 179X ; DISK CONTROLLER ; DCHDL: EQU 00011000B ;SEEK/LOAD HEAD DCHDU: EQU 00010OT READY CSWRP: EQU 01000000B ;WRITE PROTECTED CSHLD: EQU 00100000B ;HEAD LOADED CSSKE: EQU 00010000B ;SEEK ERROR CSCRC: EQU1 ; STATUS CODE PORT WDSTS ; DMRER: EQU 10011101B ;READ ERROR TEST DMWER: EQU 11111101B ;WRITE ERROR TEST DMFER: EQU 11100ANK0+0 RST1: EQU BANK0+8H RST2: EQU BANK0+10H RST3: EQU BANK0+18H RST4: EQU BANK0+20H RST5: EQU BANK0+28H RST6: EQU BANK0+ONSTANTS ; TMRFC: EQU 19H ;TIMING CONSTANT, 1ST PASS TMRNC: EQU 1CH ;TIMING CONSTANT, NORMAL PASS ; ; RETRY VALUES ; RT1 BY THE ; LOADER ROUTINE. THE LAST 2 BYTES HOLD THE JUMP ADDRESS USED ; BY RESTART INTERRUPT ROUTINE @ BANK 0 + 380H. ; ;; Hawthorne, CA 90250 ; ; Ver. 2.2 for 8" drives by Girvin Herr ; ; The disk controller moduleneeded information. ; If this identity sector is not present on the diskette, it ; is assumed to be a standard 8" IBM 3740 fo**************************************** ENDIF ; ; THE FOLLOWING IS A LIST OF THE INTERNAL I/O ADDRESS ; ASSIGNMENTS. ;NTS ; XPSTP: EQU 8H ;ISSUE STEP PULSE XPMTO: EQU 10H ;MOTOR TURN OFF XPIRR: EQU 20H ;S100 INT-REQ RESET XPMTX: EQU 40H ;MOTABLE BCDAS: EQU 00100000B ;DIRECTION (& SIDE) BCPCA: EQU 01000000B ;PRECOMP SELECT A BCPCB: EQU 10000000B ;PRECOMP SELECT B 00001B ;USER SWITCH 0 = 179X DATA ; INVERT "1" BSUS1: EQU 00000010B ;USER SWITCH 1 (NOT USED YET) BSTST: EQU 00000100B 000B ;SEEK/UNLOAD HEAD DCRDS: EQU 10000000B ;READ SECTOR DCWRS: EQU 10100000B ;WRITE SECTOR DCWRT: EQU 11110000B ;WRITE TRACK 00001000B ;CRC ERROR CSTK0: EQU 00000100B ;TRACK 0 CSINDX: EQU 00000010B ;INDEX CSBSY: EQU 00000001B ;BUSY ; ; TYPE II & 100B ;FORMAT ERROR TEST DMTK0: EQU 00000100B ;TRACK 0 TEST DMHDL: EQU 00100000B ;HEAD LOAD TEST DMDNR: EQU 10000000B ;DRIVE N30H RST7: EQU BANK0+38H ; ; INTERRUPT VECTORS ; HRINT: EQU RST7 ;MASKABLE NMINT: EQU BANK0+66H ;NON-MASKABLE ; ; I/YSK: EQU 5 ;REPOSITION HEAD ON RETRY RTYLS: EQU 9D ;LAST REPEATED RETRY ; FORM ;******************************************* IF INCLUDE EQ FALSE DATA ;PUT IN DATA SEGMENT ELSE ORG BASE ENDIF START: ; JP CLEAR ;RESET & RE-INITIALIZE Z-0 !%)- "&*. #'+/  $(,080 REGS JP INITB+BANKL ;INIT - BOOTSTRAPPED HRVEC: DW XCUTE ;BUS INTERRUPT VECTOR ; ; THIS SUBROUTINE IS THE ENTRY POINTCONTINUE IN A,BLSTS AND BSUS0 JR NZ,STOP LD C,0FFH ;ELSE SET UP INVERT MASK STOP: LD IX,DTDED ;SET DRIVE TABLE PTR EIS TIME, THE HOST SYSTEM ; CAN SWITCH THE CONTROLLER MEMORY INTO THE S100 BUS FOR ; STATUS CHECK, SETTING COMMAND BLOCK, & SMDT ;SET TABLE PTR ADD HL,DE LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) ;GOTO COMMAND ; CMDT: EQU $ ;COMMAND TA & SAVED (SVSTS). IY HAS RETURN ; ADDR. ; DS NMINT-$ ; WDINT: IN A,WDSTS ;GET 1791 STATUS & RESET INT. XOR C LD (SVS CALL SEEK ;SEEK TRACK & SET CTLS CALL RDSEC ;READ A SECTOR JP FETCH ;GET NEXT COMMAND ; ; WRITE SECTOR COMMAND ;  LD (CBSEC),A CALL SEEK JP NZ,FETCH ;IF ERROR THEN EXIT CALL RDSEC ;READ ID SECTOR CALL LOGON ;LOG ON DISK DRIVE JPON, THE DRIVE MOTOR ; STATE IS TESTED AND IF NEEDED, THEY ARE TURNED ON. IX IS SET ; TO POINT TO THE NEW SELECTED DRIVE TABLECALL EXHDU ;ELSE UNLOAD HEAD, LD A,(SVDRV) ;DESELECT CURRENT DRIVE, AND [NOT BCDSE] OUT BLCTL,A LD A,(CBDRV) ;SELECT DEOK: RET ; ; HOMED SUBROUTINE STEPS THE DISK DRIVE HEAD OUTWARD UNTIL ; TRACK 0 FLAG IS TRUE OR 255 STEPS HAVE BEEN ISSUEDUE AND A ;SET RETURN FLAGS RET ; ; TRACK 0 NOT FOUND ; EROR: LD A,0FFH ;SET FAILURE FLAG AND A RET ; ; LOGON JR NZ,I3740 INC HL ;ELSE INC PTRS INC DE DJNZ CKJI ;IF NOT DONE THEN REPEAT LD A,(IDSPT) ;SET TRACK SECTOR COUNT L FOR THE DISK CONTROLLER ; TIMING MODULE. THIS MODULE PROVIDES DELAYS WHICH ARE ; MULTIPLES OF 100 us. THE CONTENTS OF DE DETI HALT ; ; RESTART SPARES ; DS RST7-$ ; ; MASKABLE INTERRUPT ROUTINE - EXECUTED WHEN RESTARTING THE ; Z80 FROM A HECTOR DATA XFERS. ; FETCH: EI ;ENABLE INTERRUPT RESTART HALT ; ; THIS GETS CONTROL AFTER THE DISK CONTROLLER IS INTERRUBLE CM0A: DW LGON ;LOG-ON DRIVE CM1A: DW READ ;READ SECTOR CM2A: DW WRIT ;WRITE SECTOR CM3A: DW FORM ;FORMAT TRACK CM4A: DWTS),A EX (SP),IY ;PUT RETURN ADDR ON STACK RETN ; ; REMAINDER OF TIMING SECTION FROM RESTART 1 ; TICKR: LD B,TMRNC ;WRIT: CALL SELECT JP NZ,FETCH CALL SEEK CALL WRSEC JP FETCH ; ; FORMAT TRACK COMMAND ; FORM: CALL SELECT JP NZ,F FETCH ; ; READ ADDRESS COMMAND ; ADDR: JP FETCH ;NOT IMPLEMENTED ; ; SPARE COMMAND ; SPAR: JP FETCH ; ; IDLE CO. ; SELECT: IN A,BLSTS ;GET BOARD LEVEL STATUS AND BSMOF ;IF MOTOR ON THEN CHECK DRIVE JR Z,CKDV IN A,XPMTX ;ELSE ISSSIRED DRIVE, AND BCDSN OUT BLCTL,A OR BCDSE OUT BLCTL,A LD (SVDRV),A AND BCDSN ;SELECT DRIVE TABLE FOR DRIVE LD I ; HOMED: LD L,255D ;SET MAX COUNT STEP: CALL EXSTS ;IF ON TRACK 0 THEN EXIT AND DMTK0 JR NZ,EXIT DEC L ;IF STEPS =  SUBROUTINE READS THE IDENTITY SECTOR FROM THE ; DISKETTE AND MAKES THE NEEDED ENTRYS INTO THE DRIVE TABLE. ; THE SECTOR DATD (IX+DVSPT),A LD A,(IDSTG) ;SET STAGGER # LD (IX+DVSTG),A LD A,(IDFLG) ;SET SIDES & DENSITIES LD (IX+DVFLG),A JP FETCERMINES THE TOTAL ; PERIOD. (DELAY=(DE)*100 us). ; LD B,TMRFC ;SET CONSTANT DJNZ $ JP TICKE ;GOTO TICK ENTRY ; ; IALT. THE FUNCTIONS ARE; RESET THE DD INT REQ ; FLOP, PUT THE INTERRUPTED ADDR IN DE & JUMP ADDR @ HRVEC. ; IN A,XPIRR ;RESPTED ; FROM THE HALT CONDITION. IT BRANCHES TO THE INDIVIDUAL ; COMMAND ROUTINES. ; XCUTE: CALL EXSTS ;GET 179X'S ATTENTIO ADDR ;READ ADDRESS CM5A: DW SPAR ;SPARES CM6A: DW SPAR CM7A: DW IDLE ;BACKGROUND MASK: EQU 7 ;COMMAND MASK ; ; THIS IS SET NORMAL CONSTANT DJNZ $ TICKE: DEC DE ;COUNT -1 LD A,D OR E ;IF COUNT NOT 0 THEN REPEAT NOP NOP JR NZ,TICKR ETCH LD A,(CBSEC) ;GET FORMAT FLAGS LD (IX+DVFLG),A ;RESET DRIVE FLAGS CALL SEEK CALL WRTRK ;WRITE DISK TRACK JP FETCMMAND ; IDLE: IN A,BLSTS ;IF NO HOST INTERRUPT THEN WAIT AND BSINT JR Z,IDLE IN A,XPIRR ;ELSE RESET INTERRUPT REQUESUE MOTOR START LD DE,(TMMTO) RST 8H CKDV: IN A,XPMTX ;EXTEND MOTOR TIME LD A,(SVDRV) ;INSURE 179X INTRQ ENABLED FOR ; X,DVTBL LD DE,DVDES ;DRIVE TABLE ARRAY SIZE NEXT: DEC A ;IF DRIVE = 0 THEN EXIT WITH POINTER SET JP M,SLED ADD IX,DE 255 THEN ERROR JR Z,EROR IN A,XPSTP ;ISSUE STEP PULSE LD DE,(TMSTP) ;SET DELAY RST 8H JR STEP ; ; DRIVE IS RESA IS ALSO LEFT IN THE SECTOR BUFFER FOR BIOS ; TO FINISH THE LOG-ON OPERATION. ; LOGON: LD DE,JADEID ;SET STRING PTR LD HLH ; ; ASSUME 3740 FORMAT ; I3740: LD A,26D ;SECTORS/TRK=26D LD (IX+DVSPT),A LD A,1 ;STAGGER=1 LD (IX+DVSTG),A NITIALIZE Z-80 REGS AFTER RESET & HALT FOR CMD ; CLEAR: LD SP,TPSTK IM 1 LD C,0 ;IF NOT INVERTED DATA SELECT THEN ; ET INT REQ POP DE ;PURGE INTERRUPTED ADDR LD HL,(HRVEC) ;GET RETURN ADDR JP (HL) ; ; END OF SEQUENCE HALT - DURING THN FOR CMDS LD A,(CBCMD) ;GET HOST CMD AND MASK ;LIMIT OPTIONS ADD A ;2*VALUE LD D,0 LD E,A ;SET UP OFFSET LD HL,CTHE NON-MASKABLE INTERRUPT ROUTINE ; UPON 1791 COMMAND TERMINATION, THE Z80 RECEIVES A NMI. THE ; STATUS PORT IS INTERROGATEDRET ;ELSE RETURN ; ; READ SECTOR COMMAND ; READ: CALL SELECT ;SELECT DRIVE JP NZ,FETCH ;IF DRIVE NOT READY THEN EXIT H ; ; DRIVE LOG-ON COMMAND ; LGON: CALL SELECT JP NZ,FETCH XOR A ;SET TRACK=0 LD (CBTRK),A INC A ;SET SECTOR =1 T & EXIT JP FETCH ; ; THIS SUBROUTINE IS RESPONSIBLE FOR SELECTING THE COMMAND ; REQUESTED DRIVE #. BEFORE DRIVE SELECTI LATER OR BCDSE ;CMDS OUT BLCTL,A LD A,(CBDRV) ;IF THIS DRIVE = OLD DRIVE THEN ; OK CP (IX+DVNBR) JR Z,DVOK  ;ELSE POINT TO NEXT ARRAY & REPEAT JR NEXT ; SLED: CALL EXSTS ;SET FLAGS PER DRIVE READY AND DMDNR LD (CBSTS),A DVTORED ; EXIT: LD DE,(TMALS) ;WAIT A BIT AFTER LAST STEP RST 8H LD A,0 ;SET COMPLETE FLAG LD (IX+DVTRK),A ;SET TRACK VAL,IDLB ;SET SECTOR BUFFER PTR TO COMPARE LD B,IDSZE ;SET ID LENGTH CKJI: LD A,(DE) ;IF ID NOT=JADE THEN 3740 CP (HL)  LD A,IDFLD ;SIDE & DENSITIES FLAGS=0 LD (IX+DVFLG),A JP FETCH ; ; TRACK SEEK SUBROUTINE ; EXIT - DENSITY & PRE-COMP0 !%)- "&*. #'+/  $(,0 CONTROLS SET ; SEEK: CALL EXSTS ;IF HEAD ALREADY LOADED THE BYPASS AND DMHDL JR NZ,HLDD CALL EXHDL ;ELSE LOAD HEAD OUT BLCTL,A JR STEPS ; SOUT: NEG ;COMPLEMENT OFFSET JP M,HOME LD L,A LD A,(SVDRV) OUT BLCTL,A STEPS: IN A,XPSTPn:CA 6Ng@h(O9L'A@d4Z2̀ :@,*ˠ,*`,:̠ qa'c60B5Y2-Vh@YPzo6`QHa2FCe#X|s23 LCJ(:&㙰t2AHt2FC@@:bcf㠀Ta2B(4L'L r l2&(E,ADF5*Y P(i9Sr D#)r7Le%KX:fޠQXl `i1e 4` qzGYdP o+ͦ`f@VXfpVmZ4Cā؊#9a@3h 2ݒ%pil f vC=e7d osof@e&P@Z8 &(o:! ;DRIVE 1 DB 2,255D,0,0,0,DFDFL,0C6H ;DRIVE 2 DB 3,255D,0,0,0,DFDFL,0C7H ;DRIVE 3 DTDED: DB 4,255D,0,0,0,0,0 ;DUMMY DVDES: CBSPR: DB 0 ;UNASSIGNED CBMOD: DB 0 ;MODE SELECTS CBSTS: DB 0 ;CONTROLLER STATUS CWLAD: DW 0 ;LOAD ADDR CWLNG: DW 0 ;A,2 ;LOAD IN BIOS LOADER SECTOR LD (CBSEC),A IN A,XPMTX LD HL,BUFBG ;SET RETURN TO EXECUT BLT PUSH HL JP RDSEC ; ;D9N#F!h !!% s!Q!9^#V!B!9^#V! L!"!!9^#V)))[DM! 9^#V! 9^#V! ^#V! ^)*!"!!!j)*|)!! 9^#V! 9^#V!$ ^!J!"h "|a!!$ ^! 9~#fo@!$ sz!9^#V! @ `i#DM+^!9s#r!9~#A!9^#VX I!9^#V! 9F+N+V+^+~+ngxhw# [!9^#V#N#F#nxʄs#!9~a{ o&!9~A([( o&!: UV#AUP!b: PU#@ MQN; TTcMQ5Z;Nxc@D6xAT378"ˠ! H y 3NG3@l0΂s:ADbI 3NG3@l0΂t0ADBIl0D1s:atAE2t4C(d2)`tC :3e6AHhіY'@Vu6X,f }e{6Ё 8Fͽ@P o+ͦ`ηiO- 8Tͽ@]l `h3@.iO. 8Jͽ@6A #MQr7h(e<fqr9Mr7h(o6L& a6Ly 7#yd9Ah(o:yh 'CVm[D4pA EQU DTDE1-DTDE0 ;ENTRY SIZE ; ;FLAG BIT DEFINITIONS ; DFT1D: EQU 1 ;TRK 1 DENSITY (1=DBL) DFDTD: EQU 2 ;DATA TRKS DENSILOAD LENGTH CMNRT: EQU 10000000B ;NO RETRYS (=1) ; ; INITIALIZATION RTN ; DS BUFBG-$ INITB: LD BC,BANKL ;SET BYTE COUNTBUFR EQU $ ; END ^#VPQ!DM!9^#V!9s#r!9^#V!$~!9^#V!$^!͜ DM!9~#fo !9^#VBK!9^#V! 9^#V`i!~#fo#s#r!Q!9N#F!!9s#r!9~#fo#s#r!9^#V!9~#fo`i#DM+^!9s#r!9^#V! ͈! !9^#V y!9^#V#~#foxʪ¯ʪ# Ö!ڹ!}!}!9^#V#~#fox~# !9~#fo#}!` ~Pg, ( :ݥ<!DF_0F^aͽ@,tYҥ ;*#?D`io"͠:Z @  &9s(I7&I@c7MqB  FQit2R(&XI `"!&eZ& E`@"JE,U  X#=!  dˀ RKedk+jm * ګ,* ګ,*` ګ,U`ͯ@ (33o +j843o +jH4mUVK6m*  Aa  h XB04XEX}AF??c͢,!AV #fPV@9X,( " 4` pzY6md 0 !%)- "&*. #'+/  $(,0 TITLE PROM BURNING UTILITY ;******************************************************** ; ; Hard Disk Monitor Program ; ; he following commands: ; ;*HElp ; Displays the command summary list. ;*REad addr filename ; Reads file 'filename' witds are checked. ;*MOve first, last, dest ; Moves code from buffer relative position 'first' through 'last' ; into new buffer lay first <,last> ; Display buffer data from buffer relative location 'first' through ; buffer relative location 'last'. If 'lthe 2 Hex digits are loaded into ; the 'addr' location then 'addr' is incremented by 1 & the process ; is repeated. If a RETURISION STATUS: ; X.0 - 6 Jul 83 GRH ; Test release ; REVSN: EQU 'X0' ; ;********************************************* ; ; ASCII CHARACTERS ; LF EQU 0AH CR EQU 0DH ; ; CONSTANTS ; STKSIZ: EQU 64 ;STACK SIZE SECSIZ: EQU 128 ;DISK ' DB LOW REVSN DB CR,LF,'Copyright (c) 1983' DB ' GRH Enterprises Cupertino, CA' DB CR,LF,'$' ; ; MAIN PROGRAM 1 LD (CMDPTR),HL ;UPDATE PTR EX DE,HL ;DE := COMMAND PTR LD HL,CMDTBL NXTCMD: LD B,(HL) ;B := CMD CHAR CNT  LD C,' ' CALL SEARCH CALL SKIP ;ALSO PASS IN ZF IF NO FIELDS LD (CMDPTR),HL LD HL,CONT1 ;SET UP RETURN ADDR EX (BRS LD DE,SYNERM CALL EDITOR JR CONT1 SUBTTL COMMANDS ;********************************** ; ; READ FILE INTO  (CMDPTR),HL LD HL,(CMDPTR) ;SEEK FILENAME LD C,' ' CALL SEARCH LD (CMDPTR),HL ; ; WE SHOULD NOW BE AT THE FILENAME  Copyright (c) 1983 GRH Enterprisess, Cupertino, CA ; by Girvin Herr ; ;*************************************************h optional 'HEX' format starting at buffer ; relative location 'addr'. Buffer bounds are checked. ;*SAve first, last HEX filenrelative location starting at 'dest'. Buffer ; bounds for 'dest' are checked. ;*COpy count <,dest <,skip>> ; Copy 'count' bytast' is not specified then ; 256 bytes are displayed. If 'first' is not specified, then the ; previous 'last' is used for 'firN is entered (nul line) the data value is ; left as is & 'addr' is incremented by 1 & the process is repeated. ; If a period '************ SUBTTL DECLARATIONS FALSE EQU 0 TRUE EQU NOT FALSE LISTINC EQU FALSE ; ; SYSTEM PARAMS ; SYSTEM EQU 00SECTOR SIZE TYPE: EQU 8 ;OFFSET LOCATION OF TYPE EXTENSION OF FILENMAE SUBTTL PROGRAM AREA ORG TPA ; ; ENTRY VECTOR ;; PROM: LD SP,STACK ;INITIALIZE LD HL,(BDOS+1) ;GET LAST MEMORY LOC. DEC HL LD (MEMTOP),HL LD DE,SIGNON ;OUTPUT SIG LD A,B ;IF COUNT == 0 THEN DONE OR A JR Z,CMDERR CMDCHK: INC HL ;IF CHARS NOT MATCH THEN EXIT LD A,(DE) CP (HL) SP),HL ;EXECUTE COMMAND JP (HL) ; NOT1ST: INC HL ;WASTE ENTRY DJNZ NOT1ST INC HL ;SKIP ADDRESS INC HL LD DE,(BUFFER COMMAND ; READ ADDR FILENAME ; ;********************************** READC: JP Z,SYNERR ;IF NO OPERAND THEN ER ; RC1: LD HL,FCB ;FORMAT FCB CALL FORMAT JP C,SYNERR JP NZ,SYNERR ;IF WILDCARDS USED THEN ERR ; ; FORMAT OK, SO OPEN ******* ; ; 1- Implements the loading of object files ; in the Intel HEX format into the memory buffer. ; 3- Exteame ; Saves the buffer image starting at buffer relative location 'first' ; through 'last' in Hex file format as file 'filenames from prom starting at buffer relative location ; ',dest' (if 'dest' is not specified then a default of 0 is used). ; If 'dest'. ;*Substitute addr ; Allows changing byte values starting at buffer relative location ; 'addr' one at a time. Upon execut.' is entered as the 1st character, the command is ; terminated. Note, the Hex values entered must have 0 in the high ; byte. 00H DFLTDK: EQU 0004H ;DEFAULT DISK STORAGE LOC BDOS: EQU 0005H ;CP/M ENTRY POINT DEFBFR: EQU 0080H ;DEFAULT BUFFER LOC T JP PROM ;ENTRY VECTOR FROM SYSTEM ; ; PTR TO END OF PROGRAM (START OF PROM OVERLAY) ; $MEMRY DW PGMEND ; ; SIGN-ON MSG CALL EDITOR ; ; COMMAND INPUT ENTRY. ALL COMMANDS RETURN HERE IF OK. ; CONT1: CALL CRLF ;NEW LINE LD C,'*' JR NZ,NOT1ST INC DE ;NEXT CHAR DJNZ CMDCHK ;IF COUNT EXHAUSTED THEN MUST BE COMMAND INC HL ;FETCH SERVICE ADDR CMDPTR) ;RESTORE CMD PTR TO START OF CMD JR NXTCMD ;IF NOT LAST ENTRY THEN LOOP ; COMMAND NOT FOUND IN TABLE CMDERR: R LD HL,(CMDPTR) ;GET ADDR CALL GETNUM JP C,SYNERR ;IF ILLEGAL NUMBER THEN ERR CALL CPBNDS ;IF READ AREA INTO RESERFILE ; LD DE,FCB CALL OPEN INC A ;IF NOT THERE THEN JR NZ,RDC1 LD DE,FNFM ; OUTPUT 'FILE NOT FOUND' JP EDITOR nsive error checking against memory buffer bounds, will not allow ; operating system or code to be compromised. ; ; Uses te' ;*FIll first, last, value ; Fills buffer relative locations from 'first' to 'last' (inclusive) ; with 'value'. Buffer bounst' is specified, then the optional skip count specifies the ; number of buffer bytes to skip between each buffer load. ;*DIspion, this command outputs: ; 'addr' & the current data value then waits for the user response. ; If the user enters hex data, I.E. 00xx or just plain xx or even yy00xx will be ok. ; ;********************************************************* ; ; REVPA EQU 0100H ;START OF PROGRAM ; CPMEOF: EQU 1AH ;CP/M END OF FILE CHAR (CTRL-Z) RDCF: EQU 10 OPENF: EQU 15 RDF: EQU 20 N ON MESSAGE HERE TO GIVE COPYRIGHT VISIBILITY ; SIGNON: DB CR,LF,'Hard Disk Monitor Utility Ver ' DB HIGH REVSN DB '. ;OUTPUT PROMPT CALL CONOUT CALL RDCON ;GET USER INPUT LD HL,(CMDPTR) CALL SKIP ;IF NO INPUT THEN ERR JR Z,CONT LD E,(HL) INC HL LD D,(HL) PUSH DE ;SET UP FOR COMMAND SCANNING LD HL,(CMDPTR) ;SET UP OPERANDS FOR SOME COMMANDSLD DE,CMDERM ;ELSE OUTPUT ERROR MESSAGE CALL EDITOR JR CONT1 ;TRY NEXT COMMAND SYNERR: POP DE ;WASTE RETURN ADDR FOR SUVED AREA THEN JP C,BNDSM ;ABORT LD (PARAM1),HL LD HL,(CMDPTR) ;GET FILENAME LD C,' ' CALL SEARCH CALL SKIP LD ; ; OUTPUT BOUNDS ERROR MESSAGE ; BNDSM: LD DE,BOUNDM ;THEN OUTPUT ERROR MESSAGE JP EDITOR MEMER1: LD DE,MEMERM CAL 0 !%)- "&*. #'+/  $(,0͢,:fdKt2?- @ F{'@ vH5!Z3@ ,d5 (p k ?l E"J 9 )nk PhE$&&O*"Jlel)o2* "Bd"$)*FH2"J*r$(argv[++cnt]); /*** get date ***/ if ((temp < 1) || (temp > 31)){ put_err(argv[cnt]); break;} time else if (strncmp("TIME=", argv[cnt], 5) == 0){ tptr = argv[cnt] + 5; if (*tptr == 0){ pR><< MOSHSHAN O XO LG ENLG8O(0GO OPTIONS: Prints this list FOrmat a disk REad :drive @trk >sec #cnt *addr %(translate) WRite :drv @trk >sec #cnt:[( #/}2[O> *@:\( #/}2\OH *>:]( #/}2]ON *#( #/S^**[`( Hex Conversion Error Command Value out of Bounds! Not Enough Data! !8!     !"i"l"#6 #~?  x!0 !5 (#=_.:;,<>/*!$'-2u Cm " *l" ~* " [RK*  q~#oOl 8} "  q* ~0 0>.Oq#[ { z l * Ry Count***/ putchar(c) char c;{ bdos(2, c); } /********************************* put number function *************; FUN1: LD A,(DDFLG) ;SET FORMAT FLAGS LD (FFLAG),A LD HL,MSGFD ;SELECT DRIVE CALL SELDR JR C,FUNBG ;ERR- RESELECT L!J># 0Üͪո]VAp]s c xAY`P0p-1Z { bAFhL0( ?‛@8a0ɬ@#OР else time_array.week = temp & 0x7; } else if (strncmp("DATE=", argv[cnt], 5) == 0){ tem_array.day = (temp % 10) | ((temp / 10) << 8); tptr = argv[cnt]; /* find any ',' */ while ((*tptrut_err(tptr); break; } temp = atoi(tptr) % 24; time_array.hours = (temp % 10) | 0<~ 7#" ͙!(Ox"O!(CO!(:AK|!"'~#fo>2zI":zIO2!O!( A7######-#:#D *addr % LOad addr filename.HEX MOve first, last, dest FIll first, last, data DIsplay <,last> SUbstitute addr E#[S`*%#~02hvLL*jT"j*lT"l*nT"n TvLL*jT"j*lT"ln+"j*7"~,( "j!i4*,#""l!i4*,#""n:i<2i[~ȹ(#~ # !So i _>{(: / , _/ , g/ , o"s *m "q K Ko B >i _>{(: / 8O_/ 8Gg/ 8AoKs B Km "q KProgram *j"u [RK qoO qw w#~#o>g6[u (~.|}[u  l * Ry Count*********************/ putd(numb) int numb;{ putchar((numb >> 8) + '0'); putchar((numb & 0xf) + '0'); } D A,TRK0 ;SET TRACK # LD (TRKNO),A CALL FMTSD ;FORMAT TRACK SDENS JR C,FUN1 ;ERR LD A,TRK1 ;SET NEXT TRACK # LD (Tp p B( ¡l? 0HAa#0 .lB( ¡l? 0HAa#0TF6n( = w F%p = get_offset(argv[cnt] + 5, month_table, nmonths); if (temp > 256){ put_err(argv[cnt]); break;}  != 0) && (*tptr != ',')) tptr++; if ((*tptr == 0) || (*(tptr + 1) == 0)) tptr = argv[++cnt]; else (((temp / 10) | time_format) << 8); while ((*tptr != 0) && (*tptr != ':')) tptr++; i#?#K#U#_#@#o#p#z## s1!*}( }o>g"" " "`C>R*qw!~#o>g6(@S!9N#F# %#^#VXit return to system Invalid command! - Re-enter. MOFIDISU?LOYREWRFOl EXpHEw?w{!ɯͣ TvLO*j#}+(* "j*l}(*j"l vLL*jT"jÉ *L""j* L"*j^˻~#! 0 8  ?))))o! 0 ?)))o>g|P}U 80OqY   Ko B0/ 8>*q / 8w# / 8 >i 0 D  ?''''Gi 0 b  ?؀GWx:u  ͑p͊*************************************/ puts(ptr) char *ptr;{ while (*ptr != 0){ if (*ptr == '\n') putchar('\r' '5' ;ELSE IF 5 THEN READ SYSTEM TRACKS JP Z,FUN5 CP '6' ;ELSE IF 6 THEN WRITE SYSTEM TRACKS JP Z,FUN6 LD HL,MSGSE ;ELSERKNO),A REPT: CALL FMTDD ;FORMAT TRACK IN DDENS JR C,FUN1 ;ERR LD A,(TRKNO) ;IF LAST TRACK THEN DONE CP TRK76 JR Z,ID{%D4|(#áذx>˙FG@*b"\d)*)%V@**f !)"&l@"*f )S2zjft ))'Fvjz*ldtime_array.month = (temp & 0xf) + 1; if (cnt >= argc){ put_err(argv[cnt]); break;} temp = atoi tptr++; temp = atoi(tptr) % 100; time_array.year = (temp % 10) | ((temp / 10) << 8); }f (*tptr == ':') ++tptr; temp = atoi(tptr) % 60; time_array.minutes = (temp % 10) | ((temp / 10) <<  *"Aé## [ !A Diagnostic Disk Utility Ver 2.0 (c) 1981 GRH Electronics >2g:]2d*`"b*^"e:h:dO( 0 \f MN KbT :g Z ` (!*b"b!d4#5 Disk Error *:T"j*p͘>2!y6H#6E#6Xp̓< !Kj[x ='!o>g~#fo File Not Found! Hex File Error /( 8 @G:(:wxp (#* 6?w (#6 .  (#* 6?w (#6 7 !"v >2u *v ~#"v !u 5[j*l:nRy7:n*jw[j*lR[nR8 *jy7*n *ly7*j); putchar(*ptr++); } } /****************************** put char function **************************** OUTPUT ERROR MSG LD (LTRSE),A ;STORE BAD SYMBOL CALL MSGOT JR FUNBG ;REPEAT ; ; FUNCTION 1 - DOUBLE DENSITY FORMAT  INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT ; ID: LD HL,IDSDD ;WRITE DDENS ID SECTOR CALL WRTID JR FUN1 ;READY 0 !%)- "&*. #'+/  $(,0L EDITOR JP CONT1 ; ; HEX FILE READ ROUTINE ; RDC1: RDC2: XOR A ;SET UP BUFFER FOR 1ST READ LD (BFRCNT),A LD H ADDRESS OF 1ST RECORD & USE AS BASE JP C,HXERR LD H,A ;HIGH BYTE OF ADDR CALL BYTE JP C,HXERR LD L,A ;LOW BYTE E JR NZ,HEXRD LD D,0 ;CHECKSUM = 0 CALL BYTE JR C,HXERR ;FILE EMPTY AND A ;IF RECORD LENGTH = 0 THEN DONE JA SBC HL,BC JP NC,MEMER1 ; GETREC: CALL BYTE ;GET RECORD TYPE JR C,HXERR ;FILE EMPTY OR A ;IF RECORD TYPE <> 0 TH JP EDITOR HXTYPER: LD DE,HXTYPM ;OUTPUT ILLEGAL HEX RECORD TYPE JP EDITOR HXEMPT: LD DE,HXEMTM ;OUTPUT FILE EMPTY RR INC HL LD (PARAM3),HL ;SAVE COUNT IN P3 EX DE,HL ;OFFSET FIRST FOR PTR CALL CPBNDS LD (PARAM1),HL LD HL,(CMD;ELSE RETURN TO COMMAND MODE WRC2: LD DE,FCB ;DELETE FILE 1ST LD C,19 CALL BDOS WRC1: LD DE,FCB ;MAKE NEW FILE LD BC LD B,C ; REC_COUNT = 16 LD (PARAM3),HL ; COUNT -= 16 JR NC,WR2 ; ELSE REC_COUNT = COUNT LD B,A LD HL,0 RRP LD A,L CALL PBYTE POP HL ;PTR JR C,WERR XOR A ;OUTPUT 0 RECORD TYPE CALL PBYTE JR C,WERR WR3: LD A,(HUT END OF FILE RECORD CALL PCHAR JR C,WERR WR5: LD B,5 ;OUTPUT 5 00 BYTES WR4: XOR A CALL PBYTE JR C,WERR DJNZ D HL,(PARAM2) ;LAST SBC HL,DE ;IF FIRST > LAST THEN ERR JP C,SYNERR PUSH HL ;ELSE COUNT = LAST - FIRST POP BC LD A OF BOUNDS THEN ERR CALL CPBNDS JP C,BNDSM LD (PARAM3),HL LD HL,(PARAM1) ;ADD BUFFER BIAS TO VALUES CALL CPBNDS LDL,(PARAM1) ;SET PTR TO LOAD ADDR LD (BFRPTR),HL HEXRD1: CALL GETCH ;FETCH CHARACTER OF FILE JP C,HXEMPT ;IF FILE EMPTY TOF ADDR LD (HEXBASE),HL ;SAVE BASE ADDRESS LD HL,(BFRPTR) ;SET LOAD PTR TO START OF BUFFER LD (HEXPTR),HL LD C,E ;IP Z,CONT1 LD E,A ;RECORD COUNT = BYTE CALL BYTE ;GET LOAD ADDRESS JR C,HXERR LD H,A CALL BYTE JR C,HXERR LEN ERROR JR NZ,HXTYPER LD HL,(HEXPTR) ;RESTORE PTR LOOP: CALL BYTE ;INPUT DATA JR C,HXERR LD (HL),A INC HL DECJP EDITOR ;******************************* ; ; SAVE FILE COMMAND ; SAVE FIRST, LAST HEX FILENAME ; ;********************PTR) LD C,' ' ;POINT TO FILENAME CALL SEARCH CALL SKIP LD (CMDPTR),HL JP Z,SYNERR LD HL,FCB ;FORMAT FCB CALL FC,22 CALL BDOS ; ; MAIN LOOP OF HEX OUTPUT ROUTINE ; LD A,0 ;CLEAR WRITE BUFFER LD (BFRCNT),A LD HL,DEFBFR LD (D; COUNT = 0 FOR LAST RECORD LD (PARAM3),HL WR2: POP HL ;RESTORE START PTR LD D,0 ;CHECKSUM = 0 LD A,B ;OUTPUT RECOL) ;OUTPUT BYTE FROM MEMORY CALL PBYTE JR C,WERR INC HL ;PTR += 1 DJNZ WR3 ;NEXT BYTE XOR A ;OUTPUT -CHECKSUM WR4 CALL CLOSE JR C,WERR RET ;NORMAL EXIT WERRP: POP HL ;BALANCE STACK WERR: LD DE,WRERRM ;OUTPUT WRITE ERROR J,C ;IF CNT = 0 THEN ERR OR B JP Z,SYNERR LD A,(PARAM3) ;GET VALUE LD HL,(PARAM1) LD (HL),A ;SET FIRST LOCATION P (PARAM1),HL LD HL,(PARAM2) CALL CPBNDS LD (PARAM2),HL LD DE,(PARAM1) ;IF FIRST > LAST THEN ERR OR A SBC HL,DE JP HEN ERR CP ':' ;IF CHAR <> COLON THEN IGNORE JR NZ,HEXRD1 LD D,0 ;CHECKSUM = 0 CALL BYTE ;IF FILE EMPTY THEN ERF LOAD_PTR + COUNT <= LAST THEN GET DATA LD B,0 ADD HL,BC LD BC,(MEMTOP) INC BC OR A SBC HL,BC JR C,GETREC JR D L,A LD BC,(HEXBASE) ;IF NEW ADDR < BASE ADDR THEN ERR SBC HL,BC JR C,HXADERR LD BC,(BFRPTR) ;ELSE COMPUTE NEW PTR  E ;IF (COUNT = COUNT -1) =<> 0 THEN LOOP JR NZ,LOOP CALL BYTE ;CHECK CHECKSUM JR C,HXERR XOR A ADD D JP Z,HE*********** SAVEC: JP Z,SYNERR ;IF NO OPERANDS THEN ERR LD DE,PARAM1 ;GET 1ST & LAST LD HL,(CMDPTR) CALL GET2PAR JPORMAT JP C,SYNERR JP NZ,SYNERR LD DE,FCB ;OPEN FILE, IF EXISTING THEN PROMPT FOR DELETE CALL OPEN INC A JR Z,WRC1BPTR),HL LD HL,(PARAM1) ;INIT START ADDR WR0: LD C,':' ;OUTPUT START OF RECORD SYMBOL CALL PCHAR JP C,WERR LD BC,1RD LENGTH OR A ;IF COUNT = 0 THEN SKIP TO EOF JR Z,WR5 CALL PBYTE JR C,WERR PUSH HL ;SAVE PTR PUSH DE ;SAVE C SUB A,D CALL PBYTE JR C,WERR LD C,CR ;OUTPUT CR-LF CALL PCHAR JR C,WERR LD C,LF CALL PCHAR JR C,WERR P EDITOR ;************************* ; ; FILL COMMAND ; FILL FIRST, LAST, VALUE ; ;************************* FILLCUSH HL ;DESTINATION = SOURCE + 1 POP DE INC DE LDIR ;FILL RET ;************************ ; ; MOVE COMMAND ; C,SYNERR PUSH HL ;ELSE CNT = # OF BYTES POP BC EX DE,HL ;IF DEST > FIRST THEN LD DE,(PARAM3) SBC HL,DE JR C,SPLIR JP C,HXERR AND A ;IF RECORD LENTH == 0 THEN DONE JP Z,CONT1 LD E,A ;RECORD COUNT = BYTE CALL BYTE ;GET LOADMEMER1 ;ELSE OUTPUT MEMORY ERROR ; HEXRD: CALL GETCH ;GET CHAR OF FILE JR C,HXERR CP ':' ;IF CHAR <> COLON THEN IGNOR ADD HL,BC LD (HEXPTR),HL LD C,E ;IF PTR + COUNT > BFR_TOP THEN ERR LD B,0 ADD HL,BC LD BC,(MEMTOP) INC BC OR XRD HXERR: LD DE,HXERM ;IF ERROR THEN TELL SO JP EDITOR HXADERR: LD DE,HXADRM ;OUTPUT ILLEGAL LOAD ADDRESS REGRESSION  C,SYNERR LD HL,(PARAM2) ;COUNT = LAST - FIRST + 1 LD DE,(PARAM1) OR A SBC HL,DE JP C,SYNERR ;IF FIRST > LAST THEN E LD DE,DELMSG CALL EDITOR CALL CONIN ;IF 'Y' OR 'y' THEN DELETE AND 5FH ;CONVERT TO LOWER CASE CP 'Y' RET NZ 6 PUSH HL ;SAVE START ADDR WR1: LD HL,(PARAM3) ;IF COUNT - 16 >= 0 THEN OR A LD A,L ;SAVE COUNT FOR RESTORING SBC HL,S LD DE,($MEMRY) ;REMOVE OFFSET FOR OUTPUT OR A SBC HL,DE POP DE ;CS LD A,H ;OUTPUT LOAD ADDR CALL PBYTE JR C,WEPUSH HL LD HL,(PARAM3) ;IF COUNT = 0 THEN DONE LD A,L OR H POP HL JP NZ,WR0 ;ELSE DO ANOTHER LINE LD C,':' ;OUTP: JP Z,SYNERR ;IF NO OPERANDS THEN ERR CALL GET3PAR JP C,SYNERR CALL CKBNDS JP C,BNDSM LD DE,(PARAM1) ;FIRST LMOVE FIRST, LAST, DEST ; ;************************ MOVEC: CALL GET3PAR JP C,SYNERR LD HL,(PARAM3) ;IF DESTINATION OUTT ;TOP DOWN INC BC ;ELSE BOTTOM UP LD HL,(PARAM1) LD A,C ;IF COUNT = 0 THEN ERR OR B JP Z,SYNERR LDIR RET  0 !%)- "&*. #'+/  $(,0; SPLIT: LD HL,(PARAM3) ;DEST = DEST + CNT ADD HL,BC EX DE,HL LD HL,(PARAM2) INC BC ;INCLUSIVE LD A,C OR B JP Z,N USE DEFAULT CP ',' JR Z,DISP1 CALL GETNUM ;ELSE GET PARAMETER 1 JP C,SYNERR CALL CPBNDS ;ADD OFFSET LD (DIST ;ADD OFFSET TOWARD BUFFER DISP3: LD (DISEND),HL DISP4: CALL CRLF ;NEW LINE CALL CSTS ;IF KEY PRESSED THEN ABORT RERT CALL SPACE LD HL,(DISTMP) ;START OVER DISP7: LD A,(HL) ;IF CHAR = PRINTING THEN OK AS IS CP 7FH JR NC,OUTDEC MEMORY COMMAND ;SUBSTITUTE ADDR ; ;****************************** SUBSC: JP Z,SYNERR ;IF NO OPERANDS THEN ERR LD HL,(CALL RDCON ;GET USER INPUT LD HL,(CMDPTR) ;IF NULL LINE THEN SKIP LOCATION CALL SKIP LD DE,(DISTMP) JR Z,SUBS1 LD TURN TO SYSTEM ; EXIT - FLAGS SAVED FOR CALLER'S CONDITIONAL ; ;******************************************************* MEMETO CONVERT BUT IF DIGIT NOT HEX THEN ERR JR C,CVERR SLA A ;MOVE OVER 1 NIBBLE SLA A SLA A SLA A LD B,A CALL GETO BINARY SUBR ; ENTRY- A= CHAR ; EXIT - A= BINARY VALUE ; CF= ERROR ; ;************************************************ A- CHAR FROM FILE IN A ; CF = EOF ; ;*************************************************************************** GETL) INC HL LD (DBPTR),HL LD HL,BFRCNT ;COUNT = COUNT - 1 DEC (HL) POP HL OR A ;INSURE NC RET ; FEMPTY: POP BC ;********* PCHAR: PUSH HL ;SAVE REGS PUSH DE PUSH BC LD HL,(DBPTR) ;GET BUFFER PTR LD (HL),C ;ADD CHAR TO BUFFER INCSYNERR LDDR RET ;************************ ; ; HELP COMMAND ; HELP ; ;************************ HELPC: LD DE,RT),HL DISP1: LD HL,(CMDPTR) ;IF NO ,NNNN THEN END= START + 12 LINES LD A,',' CP (HL) JR Z,DISP2 LD C,A CALL SEART NZ LD HL,(DISTRT) ;TEMP = START LD (DISTMP),HL LD DE,($MEMRY) ;OUTPUT OFFSET ADDR SBC HL,DE CALL PRT2H LD HL,(DICP ' ' JR NC,DISPOK OUTDEC: LD A,'.' ;ELSE OUTPUT '.' DISPOK: PUSH HL LD C,A CALL CONOUT POP HL INC HL ;PTR = MDPTR) CALL GETNUM JP C,SYNERR CALL CPBNDS ;IF ADDR OUT OF BOUNDS THEN ERR JP C,BNDSM SUBS2: LD (DISTMP),HL ;SAVE A,(HL) ;IF CHAR = '.' THEN ABORT CP '.' RET Z CALL GETNUM ;ELSE CONVERT TO NUMBER LD A,H ;IF NUMBER > 255 THEN ERR R: PUSH AF LD DE,MEMERM CALL EDITOR POP AF RET ;****************************************************** ; ; BYTECH ;GET 2ND DIGIT RET C CALL ASC2HX ;CONVERT 2ND NIBBLE JR C,CVERR ADD B ;ADD 2ND TO 1ST LD B,A ;COMPUTE CHECKSC2HX: SUB '0' ;REMOVE ASCII BIAS RET C CP 10 ;IF 0..9 THEN OK CCF RET NC SUB 7 ;CONVERT 'A'..'F' TO 10..15 CCH: PUSH HL LD A,(BFRCNT) ;IF BUFFER EMPTY THEN READ OR A JP NZ,GC1 PUSH DE ;READ SECTOR INTO DEFAULT BUFFER PUSH BRESTORE STACK POP DE POP HL RET ;*************************************************************************** ; ; PU HL ;PTR += 1 LD (DBPTR),HL LD A,(BFRCNT) ;IF BUFFER FULL THEN WRITE IT INC A LD (BFRCNT),A CP SECSIZ CCF ;SWAP FHELPM JP EDITOR ;***************************** ; ; DISPLAY MEMORY COMMAND ; DISPLAY <,LAST> ; ;************CH JR NZ,DISP2 LD HL,(DISTRT) ;ELSE END = START MOD 16 + 255 LD A,L AND 0F0H LD L,A LD DE,255 ADD HL,DE JR DISSTRT) ;RESTORE PTR DISP5: PUSH HL CALL SPACE POP HL LD A,(HL) ;PRINT DATA INC HL PUSH HL CALL PRTHEX POP HL PTR + 1 LD DE,(DISTRT) ;IF PTR = NEXT START THEN DONE LD A,E SUB L JR NZ,DISP7 LD A,D SUB H JR NZ,DISP7 EX DADDR PUSH HL ;OUTPUT ADDR CALL CRLF POP HL PUSH HL OR A ;ADD OFFSET LD DE,($MEMRY) SBC HL,DE CALL PRT2H  OR A JP NZ,SYNERR LD A,L ;LOAD DATA INTO LOCATION LD DE,(DISTMP) LD (DE),A SUBS1: INC DE ;NEXT LOCATION EX DE SUBR CONVERTS 2 ASCII-HEX CHARS TO BINARY ; ENTRY- D= CHECKSUM ; EXIT - A= BYTE FROM ASCII-HEX ; D= NEW CHECKSUM ; CF= ERSUM ADD D LD D,A LD A,B OR A ;CLEAR FLAG RET ; HEX CONVERSION ERROR MESSAGE OUTPUT CVERR: LD DE,CVERM CALL EDP 10 RET C CP 16 CCF RET ;*************************************************************************** ; ; GETC LD DE,DEFBFR CALL SETDMA LD DE,FCB CALL RDSEC OR A ;IF FILE EMPTY THEN RETURN CF SCF JR NZ,FEMPTY LD HL,DEFT CHAR ROUTINE OUTPUTS CHAR TO OUTPUT BUFFER & WRITES TO OUTPUT ; FILE WHEN FULL. BUFFER IS DEFAULT BUFFER AT 80H ; ENTRY- C=LAG SENSE TO RETURN NC JP NC,NOWRT CLOS1: LD DE,DEFBFR ;SET WRITE PTR LD (DBPTR),DE CALL SETDMA LD DE,FCB ;WRITE IT ***************** DISPC: LD HL,(CMDPTR) JR Z,DISP1 ;IF NO OPERANDS THEN USE DEFAULTS LD A,(HL) ;IF 1ST CHAR = ',' THEP3 ; DISP2: INC HL ;GET VALUE OF END CALL SKIP JP Z,SYNERR LD (CMDPTR),HL CALL GETNUM JP C,SYNERR CALL CPBNDSCALL CKDONE ;IF PTR = END THEN DONE JR C,DISP6 LD A,L AND 0FH JR NZ,DISP5 DISP6: LD (DISTRT),HL ;UPDATE TO NEW STAE,HL CALL CKDONE ;IF NOT DONE THEN DO NEXT LINE RET C JR DISP4 ;****************************** ; ; SUBSTITUTE CALL SPACE ;OUTPUT SPACE POP DE LD A,(DE) ;OUTPUT CURRENT DATA CALL PRTHEX CALL SPACE ;OUTPUT ANOTHER SPACE C,HL JR SUBS2 SUBTTL SUBROUTINES ;******************************************************* ; ; OUTPUT MEMORY ERROR & REROR ; ;****************************************************** BYTE: CALL GETCH ;GET 1ST DIGIT RET C CALL ASC2HX ;TRY ITOR SCF ;ALSO RETURN ERROR FLAG RET ;************************************************ ; ; CONVERT ASCII-HEX CHAR T CHARACTER SUBR RETURNS NEXT CHAR OF INPUT FILE ; ENTRY- FCB FORMATTED & FILE OPENED, (BFRCNT INIT'D FOR NEW FILE) ; EXIT BFR LD (DBPTR),HL ;SET VARS LD A,SECSIZ LD (BFRCNT),A POP BC POP DE GC1: LD HL,(DBPTR) ;GET CHAR FROM BFR LD A,(H CHAR TO OUTPUT ; FCB= OPENED FILE ; EXIT - CF= ERROR ; ;****************************************************************** LD C,21 CALL BDOS OR A ;IF WRITE ERR THEN RETURN CF JR NZ,WRERR LD (BFRCNT),A ;ELSE BUFFER COUNT = 0 NOWRT: POP 0 !%)- "&*. #'+/  $(,0BC POP DE POP HL RET WRERR: SCF JR NOWRT ;************************************ ; ; CLOSE OUTPUT BUFFER SUBR ;ET: RET C ;IF WRITE ERROR THEN RETURN CF LD DE,FCB ;THEN CLOSE FILE LD C,16 CALL BDOS OR A ;CLEAR POSSIBLE CARRY  ;SAVE BYTE IN B ADD D ;ADD TO CHECKSUM LD D,A LD A,B ;RESTORE BYTE SRL A ;DO HIGH NIBBLE 1ST SRL A SRL A SRL ********************************** ; ; CONSOLE OUTPUT SUBR ; ENTRY- C= CHAR TO OUTPUT ; EXIT - ALL REGS ? ; ;*************HAR READY ; ZF = REFLECTS CONDITION OF A ; ;************************************************************ CSTS: LD C,11 CA****** SEARCH: LD A,(HL) ;IF CHAR = NUL THEN RETURN Z OR A RET Z CP C ;ELSE IF CHAR=C THEN RETURN NZ JR Z,FOUND  SKIP: LD A,(HL) CP ' ' ;IF CHAR <> ' ' THEN RETURN JR NZ,FOUND INC HL JR SKIP ;*******************************R: LD C,9 JP BDOS ;*************************************************** ; ; CP/M FILE CONTROL BLOCK FORMATTER ; ENT TITLE PHIMON DIRECTORY CONVERTER 3 MAY 81 12:15 ;************************************************************* ; ; (c) e number (0 - 3) ; ;************************************************************* FORM ;***********************************Y SET ; SYSERR: EQU $ PUSH BC CALL CRLF POP BC DEC C LD A,C LD HL,ERRTBL ;IF ENTRY COUNT < ERROR# THEN ; JUSMM ; CRCM: DB 'CRC',0 NTFM: DB 'Block not found',0 JAMM: DB 'Tape',0 PROTM: DB 'Write Protect',0 SYNM: DB 'Syntax',0 FNTF EXIT - CF= ERROR ; ;************************************ CLOSE: LD C,CPMEOF ;OUTPUT EOF CHAR CALL PCHAR RET C LD A,( INC A ;IF NO ERROR THEN RETURN NC RET NZ SCF ;ELSE RETURN CF RET ;********************************************A CALL HX2ASC ;CONVERT IT TO ASCII LD C,A ;THEN OUTPUT IT CALL PCHAR JR C,PBYT1 LD A,B ;THEN DO LO NIBBLE CALL ******************************* CONOUT: LD E,C ;SETUP LD C,2 JP BDOS ;************************************* ; ; CONLL BDOS OR A RET ;********************************************************************* ; ; SEARCH SUBR SEARCHES A  INC HL ;ELSE TRY NEXT CHAR JR SEARCH FOUND: OR A RET ;****************************************************************** ; ; CARRIAGE RETURN/LINE FEED SUBR ; EXIT - ALL REGS ? ; ;************************************* CRLF: LD C,CR CRY- (CMDPTR) = ASCII STRING PTR OF FILE ; HL = FCB TO FORMAT ; EXIT - ZF = NO WILDCARDS USED ; NZ = WILDC1981 GRH Electronics CUPERTINO, CA ; ;************************************************************* ; ; PCONV is a PHIMO************************** ; ; DECLARATIONS: ; TPA: EQU 100H DEFBFR: EQU 0080H BDOS: EQU 5 STACK: EQU TPA ; LF: EQU 0AHT ERROR CP (HL) JR NC,NOPRFX INC HL ;POINT TO 1ST ENTRY ADD A ;COMPUTE TABLE PTR LD E,A LD D,0 ADD HL,DE LD C,M: DB 'File not found',0 TYPEM: DB 'File type',0 DIRM: DB 'Directory',0 NORMM: DB 'No room',0 ; NUMENT: EQU 9D ; ; ; PBFRCNT) ;IF BUFFER EMPTY THEN NO NEED TO WRITE OR A JR Z,CLOSRET PUSH HL ;PUT NEW RETURN ADDRESS ON STACK LD HL,CLOSR******************************* ; ; PUT BYTE SUBR CONVERTS BYTE TO ASCII-HEX & OUTPUTS IT TO FILE BUFFER ; ENTRY- A= BYTE ; HX2ASC LD C,A ;& OUTPUT IT CALL PCHAR PBYT1: POP BC RET ;******************************************** ; ; OUTPUT SOLE INPUT SUBR ; EXIT - A= CHAR ; ALL OTHER REGS ? ; ;************************************ CONIN: LD C,1 JP BDOS ;NUL TERMINATED STRING FOR A CHAR THE SAME ; AS CONTENTS OF C. ; ENTRY- HL= STRING PTR ; C= CHAR TO SEARCH FOR ; *********** ; ; SKIP BYPASSES TRAILING SPACES UNTIL NON-SPACE CHAR IS FOUND ; ENTRY- HL= STRING PTR ; EXIT - HL= 1ST NON-SPAALL CONOUT LD C,LF JP CONOUT ;******************************************************* ; ; MESSAGE EDITOR SUBR OUTPUTSARD(S) USED, A REG. = NUMBER OF ; WILDCARDS ; ;********************************************************* ; ;N directory converter to allow access ; to PHIMON generated files through DCOS rutines. Specifically, ; it clears all attribut CR: EQU 0DH ; FORM ;************************************************************* ; ; ASSEMBLER DIRECTIVES: ; ORG TPA(HL) ;GET MESSAGE PTR INC HL LD B,(HL) CALL EDITOR NOPRFX: LD BC,ERRMSG CALL EDITOR SCF JP 0 ; ERRMSG: DB ' ErroHI PROM VECTORS ; SETMAP: EQU 0F403H SETBID: EQU 0F406H SETCNT: EQU 0F409H SETDRV: EQU 0F40FH READF: EQU 0F412H WRITF: EQET EX (SP),HL PUSH HL ;THEN SAVE REGS FOR STACK BALANCE PUSH DE PUSH BC JR CLOS1 ;WRITE REMAINDER OF BUFFER CLOSREXIT - CF= WRITE ERROR ; ;*************************************************************************** PBYTE: PUSH BC LD B,AA SPACE TO CONSOLE SUBR ; EXIT - ALL REGS ? ; ;******************************************** SPACE: LD C,' ' ;********************************************************************** ; ; CONSOLE STATUS SUBR ; EXIT - A= 0 : NONE READY, A= NOT 0 : C EXIT - HL= CHAR PTR ; Z= NOT FOUND (END OF TEXT) ; ;***************************************************************CE CHAR PTR ; A= NON-SPACE CHAR ; ZF= NOT FOUND ; ;*********************************************************************** TEXT STRING ; ; ENTRY- DE= STRING PTR ; EXIT - ALL REGS ? ; ;****************************************************** EDITO CONSTANTS ; ZROSIZ: EQU 22 NAMCNT: EQU 8 ;FILENAME CHAR CNT TYPCNT: EQU 3 ;FILE EXTENSION CHAR CNT ; FORMAT: PUSH HL es but the delete attribute except ; if the PHIMON file is deleted. ; ; SYNTAX: ; PCONV D: ; ; WHERE: ; D: = Driv ; ENTRY: JP START ; ; ; SYSTEM ERROR SUBR - PRINTS ERROR MESSAGES ; ENTRY- ERROR NUMBER (1 THRU n) IN C ; EXIT - Cr!',CR,LF,0 ; ERRTBL: DB NUMENT ; DW CRCM DW NTFM DW JAMM DW PROTM DW SYNM DW FNTFM DW TYPEM DW DIRM DW NORU 0F415H ; ; READ DIRECTORY SUBR ; ENTRY- IY= FPB PTR (DRIVE PRESET) ; (DIRBUF)= 1K DIRECTORY BUFFER AREA ; D0 !%)- "&*. #'+/  $(,0IRRD: EQU $ READIR: LD A,(IY+[-1]) LD C,A CALL SETDRV LD BC,(DIRBUF) ;SET READ PTR CALL SETMAP LD BC,0 ;SET BLOCK IDID LD B,4 ;WRITE COUNT := 400H CALL SETCNT JP WRITF ; ; ASCII TEXT PROCEDURES ; ;**********************************OR A STRING CHAR THE SAME AS CONTENTS ; OF C. IT WILL NOT GO BEYOND A SEMICOLON ';'. ; ENTRY- DE= STRING PTR ; C= E ; CHAR IS FOUND ; ENTRY- BC= STRING PTR ; EXIT - HL=1ST NON-SPACE CHAR ; Z=NOT FOUND ; SKIPON: PUSH BCCHAR >= 80H THEN SPACES CALL M,MLTSPC JR Z,EDITLP CP 0DH ;IF RETURN THEN DO CR-LF PUSH AF CALL Z,CRLF POP AF JR ZES 7,A CP 80H ;IF TOO BIG THEN ERR JR C,CONT0 SYNERR: LD C,5 JP SYSERR ; CONT0: INC HL PUSH HL ADD L ;PUT 0 IN ENELETED THEN SKIP LD A,(HL) OR A JR Z,DELTD SET 7,(HL) ;ELSE SET NOT DELETED ATTRIBUTE DELTD: LD C,7 ;C := CHAR COUNT ',0 ; ; FPB ; DRIVE: DB 0 FPB: EQU $ NAME: DW 0,0,0,0 LENGTH: DW 0 EXTRAS: DW 0,0,0,0,0,0,0 ; DIRBUF: DW BUFFER ;  TITLE PHIMON DIRECTORY READ UTILITY 1 MAY 81 13:00 ;************************************************************* ; ; (without the use of ; a STAT command. Total blocks used is also displayed. ; wildcards are allowed to enable culling of fil************************************************** ; ; LINKS ; BDOS: EQU 0005H TPA: EQU 100H STACK: EQU TPA ; DEFBFR: DELATT: EQU 0 PROATT: EQU 1 INVATT: EQU 2 SYSATT: EQU 3 TITLAT: EQU 7 ; DELATC: EQU 'D' PROATC: EQU 'W' INVATC: EQU 'I'  CALL SETBID LD C,4 ;SET BLK COUNT CALL SETCNT JP READF ; ; WRITE DIRECTORY IN MEMORY TO DRIVE IN FPB ; ENTRY- (********************** ; ; EXTRN BDOS ; ;******************************************************** ; CONOUT: EQU $ LDCHAR TO SEARCH FOR ; EXIT - HL= CHAR PTR ; Z=NOT FOUND ; SERCH: PUSH DE POP HL SERCH1: LD A,(HL) ;IF CHAR = N POP HL SKIPO1: LD A,(HL) CP 20H ;IF CHAR <> ' ' THEN RETURN JR NZ,FOUND INC HL JR SKIPO1 ; ; CARRIAGE RETURN/LI,EDITLP CALL CONOUT JR EDITLP ; ; MULTI SPACE SUBR OUTPUTS <= 127D SPACES ; ENTRY- C= # SPACES ; EXIT - ZF SET ; D OF LINE LD L,A JR NC,HOK INC H HOK: LD (HL),0 POP HL LD C,':' CALL SERCH1 JR Z,SYNERR DEC HL ;BACKUP & GET D NAMLP: INC HL RES 7,(HL) ;CLEAR ATTRIBUTE DEC C JR NZ,NAMLP INC HL ;SKIP OVER LENGTH INC HL DJNZ ENTLP ;DO WHILEBUFFER: EQU $ ; END c) 1981 GRH Electronics CUPERTINO, CA ; ;************************************************************* ; ; PHI-MON Direes to be ; displayed. ; ; SYNTAX: ; PDIR D: ; ; WHERE: ; /I = Optional display of invisibleEQU 0080H ; SETMAP: EQU 0F403H SETBID: EQU 0F406H SETCNT: EQU 0F409H SETDRV: EQU 0F40FH READF: EQU 0F412H ; ; ; CONST SYSATC: EQU 'S' ; INVSW: EQU 'I' DELSW: EQU 'D' ; OVBUF1: EQU 01000000B DIROV2: EQU OVBUF1+14D ; MAXBLK: EQU 896D BASEDIRBUF)= 1K DIRECTORY BUFFER AREA ; (CURDRV)= DRIVE # OF DIRECTORY IMAGE AT (DIRBUF) ; ;**************************** E,C ;SETUP LD A,C ;IF CHAR = CTRL-P THEN ONLY TOGGLE FLAG CP 10H JR Z,TGLLPT LD A,(TOGGLE) AND 7 ;LIMIT 0-7 LD C,UL THEN RETURN Z OR A RET Z CP C ;ELSE IF CHAR=C THEN RETURN NZ JR Z,FOUND CP ';' ;IF CHAR = ';' THEN RETURN Z RETNE FEED SUBR ; CRLF: EQU $ LD C,0DH CALL CONOUT LD C,0AH JP CONOUT ; ; MESSAGE EDITOR SUBR ; ENTRY- BC = STRING MLTSPC: EQU $ LD B,C RES 7,B LD C,20H SPLP: PUSH BC ;SAVE CNT CALL CONOUT POP BC DJNZ SPLP XOR A RET ; ; MRIVE SPEC LD A,(HL) SUB '0' ;IF NOT 0 TO 3 THEN ERR JR C,SYNERR CP 4 JR NC,SYNERR LD IY,FPB LD (IY+[-1]),A ;SET D ENTRIES > 0 CALL WRTDIR ;REWRITE CONVERTED DIRECTORY LD C,A JP NZ,SYSERR ;IF WRITE ERROR THEN ERR JP 0 ;RETURN TO CP/ctory display utility for use under CP/M. ; This utility displays directory information much the ; same way as the CP/M di files. ; /D = Optional display of deleted files. ; D: = PHI Drive # ('0' - '3') ; FILENAME = Optional PHIMON type fileANTS ; ZERO: EQU 0 ONE: EQU 1 TWO: EQU 2 THREE: EQU 3 FOUR: EQU 4 FIVE: EQU 5 SIX: EQU 6 ; DRIVEO: EQU -1 NAMEO: EQU 10: EQU 10D DIVIDR: EQU 6 NOFILM: EQU 01111111B ; ; ASCII CHARS ; LF: EQU 0AH CR: EQU 0DH ASPACE: EQU 20H ASLASH: EQU**************************** ; WRTDIR: EQU $ LD BC,(DIRBUF) ;SET WRITE PTR CALL SETMAP LD BC,0 ;BLK ID := 0 CALL SETBA JP BDOS ; TGLLPT: EQU $ LD A,(TOGGLE) ;2 <-> 5 XOR 7 AND 7 LD (TOGGLE),A RET ; ; ; ; SERCH SUBR SEARCHES F Z INC HL ;ELSE TRY NEXT CHAR JR SERCH1 ; FOUND: OR A RET ; ; SPACEL BYPASSES TRAILING SPACES UNTIL NUL OR NON-SPAC PTR ; EDITOR: EQU $ PUSH BC EDITLP: EQU $ POP HL LD A,(HL) ;GET CHAR INC HL OR A RET Z PUSH HL LD C,A ;IF AIN START ; START: LD SP,STACK LD BC,SIGNON ;OUTPUT SIGN-ON MSG CALL EDITOR LD HL,DEFBFR ;GO GET DRIVE # LD A,(HL) RRIVE # CALL READIR LD C,A JP NZ,SYSERR LD HL,(DIRBUF) INC HL ;B := ENTRY COUNT LD B,(HL) ENTLP: INC HL ;IF FILE DM ; TOGGLE: DB 2 ; SIGNON: DB CR,LF,'PHIMON Directory Converter Ver 1.0',CR DB '(c) 1981 GRH Electronics Cupertino, CArectory utility does, with the ; exception of the file status information. The file ; length and attributes are displayed name of 6 characters ; + a 2 character extension. Wildcards of '*' or ; '?' are allowed. ; ;***********0 EXO: EQU NAMEO+6 LENGO: EQU EXO+2 BLOCKO: EQU LENGO+2 MAPO: EQU BLOCKO+2 ALTNMO: EQU MAPO+2 NAMCNT: EQU LENGO-NAMEO ;  2FH AZERO: EQU '0' AQUEST: EQU '?' ; FORM ;************************************************************* ; ; ASSEMBLE0 !%)- "&*. #'+/  $(,0R DIRECTIVES ; ORG TPA ; ENTRY: JP START ; ; LOCAL PROCEDURES ; ; ; ASCII TEXT PROCEDURES ; CONOUT: EQU $ LD E= STRING PTR ; C= CHAR TO SEARCH FOR ; EXIT - HL= CHAR PTR ; Z=NOT FOUND ; SERCH: PUSH DE POP HL SEROT FOUND ; SKIPON: PUSH BC POP HL SKIPO1: LD A,(HL) CP 20H ;IF CHAR <> ' ' THEN RETURN JR NZ,FOUND INC HL JR SKIPO CALL Z,CRLF POP AF JR Z,EDITLP CALL CONOUT JR EDITLP ; ; MULTI SPACE SUBR OUTPUTS <= 127D SPACES ; ENTRY- C= # S;PTR -> DE CP B JR NZ,SWNTFD OR A RET ; ; SYSTEM ERROR SUBR - PRINTS ERROR MESSAGES ; ENTRY- ERROR NUMBER (1 THRU ERRMSG: DB ' Error!',CR,LF,0 ; ERRTBL: DB NUMENT ; DW CRCM DW NTFM DW JAMM DW PROTM DW SYNM DW FNTFM DW TYPEM ; CHARACTERS & ALPHA 1ST CHARACTER ARE PERFORMED. ; WILDCARDS ARE FORMATTED. '*' FILLS REMAINDER OF FPB ; WIT0H ;PHI PROM ADDR ; ; DONAME: PUSH BC POP HL DONAM1: PUSH IY ;SETUP POP DE PUSH DE XOR A LD (WILDFL),A ;CLEAR WIMBIGUOUS THEN SET FLAG JR NZ,DONOQU LD (WILDFL),A DONOQU: LD (DE),A ;ELSE PUT CHAR INTO FPB INC DE DJNZ DONEXT DOMORE PUSH IY POP DE EXTLP: INC DE DJNZ EXTLP LD B,LENGO-EXO JR DONEXT ; DOCOLN: EQU $ CP ':' ;IF NOT COLON THEN DONE AG WILDLP: LD (DE),A INC DE DJNZ WILDLP JR DOMORE ; ; RESERVED CHARACTER LOOKUP SUBR ; ENTRY- CHAR TO LOOKUP IN C  20H,'=',2DH,2EH,':',';','<','>' RSVPL: EQU $ ; ; ALPHA CHAR TEST ; ENTRY- C= CHAR ; EXIT - CF= NOT ALPHA, NC= ALPHA ,C ;SETUP LD A,C ;IF CHAR = CTRL-P THEN ONLY TOGGLE FLAG CP 10H JR Z,TGLLPT LD A,(TOGGLE) AND 7 ;LIMIT 0-7 LD C,A CH1: LD A,(HL) ;IF CHAR = NUL THEN RETURN Z OR A RET Z CP C ;ELSE IF CHAR=C THEN RETURN NZ JR Z,FOUND CP ';' ;IF CH1 ; ; CARRIAGE RETURN/LINE FEED SUBR ; CRLF: EQU $ LD C,0DH CALL CONOUT LD C,0AH JP CONOUT ; ; MESSAGE EDITOR PACES ; EXIT - ZF SET ; MLTSPC: EQU $ LD B,C RES 7,B LD C,20H SPLP: PUSH BC ;SAVE CNT CALL CONOUT POP BC DJNZ n) IN C ; EXIT - CY SET ; SYSERR: EQU $ PUSH BC CALL CRLF POP BC DEC C LD A,C LD HL,ERRTBL ;IF ENTRY COUNT < E DW DIRM DW NORMM ; CRCM: DB 'CRC',0 NTFM: DB 'Block not found',0 JAMM: DB 'Tape',0 PROTM: DB 'Write Protect',0 SYNM: H '?'s, '?'s ARE INSERTED AS ENCOUNTERED. ; ; ENTRY- BC= STRING PTR TO 1ST NON-SPACE CHAR. ; IY= FPB PTR ; EXITLDCARD FLAG LD B,EXO ;ZERO FPB FILENAME DOLP: LD (DE),A INC DE DJNZ DOLP POP DE LD B,NAMEO DONEXT: LD A,(HL) ;GET : LD A,(HL) ;IF NEXT CHAR= PERIOD THEN SET EXTEN. RES 7,A NAMEDN: CP 2EH JR Z,EXTNTN LD A,(IY+0) ;ELSE SET NOT DELETED A JR NZ,NAMEDN PUSH HL DEC HL ;IF LAST CHAR NOT VALID DRIVE# THEN ERR EX DE,HL PUSH BC CALL DCKSL1 POP BC POP HL  ; EXIT - Z= FOUND ; RSVP: LD A,C RSVP1: PUSH BC ;SAVE REGS PUSH HL CP 21H ;IF CTRL CHAR THEN RESERVED JR NC,RSVPT  ; ALPHAT: LD A,C ALPHA1: EQU $ CP ':' ;IF > '9' THEN OK RET NC CP '0' ;ELSE IF < '0' THEN OK CCF RET ; ; SELE JP BDOS ; TGLLPT: EQU $ LD A,(TOGGLE) ;2 <-> 5 XOR 7 AND 7 LD (TOGGLE),A RET ; CONIN: EQU $ LD C,1 JP BDOS AR = ';' THEN RETURN Z RET Z INC HL ;ELSE TRY NEXT CHAR JR SERCH1 ; FOUND: OR A RET ; ; SPACEL BYPASSES TRAILING SUBR ; ENTRY- BC = STRING PTR ; EDITOR: EQU $ PUSH BC EDITLP: EQU $ POP HL LD A,(HL) ;GET CHAR INC HL OR A RE SPLP XOR A RET ; ; SEARCH FOR SWITCH SUBR ; ENTRY- C= CHAR TO SEARCH FOR ; DE= STRING PTR ; EXIT - Z= NOT RROR# THEN ; JUST ERROR CP (HL) JR NC,NOPRFX INC HL ;POINT TO 1ST ENTRY ADD A ;COMPUTE TABLE PTR LD E,A LD DDB 'Syntax',0 FNTFM: DB 'File not found',0 TYPEM: DB 'File type',0 DIRM: DB 'Directory',0 NORMM: DB 'No room',0 ; NUMENT:  - IY= FPB PTR TO NAME FIELD ; HL= STRING PTR TO LAST CHAR +2 ; CF= ERROR [ERR CODE IN A] ; A= '?'STRING CHAR RES 7,A ;CLEAR ATTRIBUTE INC HL PUSH BC CALL RSVP1 ;IF RESERVED CHAR THEN EXIT POP BC JR Z,DOCOLN CPTTRIB & SET 7,(IY+0) CALL ALPHA1 ;IF 1ST CHAR <> ALPHA THEN ERR JR C,DOERR CALL RDDRV ;SET SPEC'D DRIVE INTO FPB LD ;RESTORE PTR JR C,DOERR JR Z,NODRV1 LD C,A CALL SETDRV NODRV1: CALL SKIPO1 JR DONAM1 ; DOERR: EQU $ LD A,5 ;SET  CP A ;SET Z JR RSVPF ; RSVPT: LD HL,RSVPTB ;SET TABLE PTR LD B,(HL) ;GET # ELEMENTS RSVPLP: INC HL CP (HL) JR Z,RCT DRIVE SUBR ; DCKSL1: EQU $ LD C,':' ;FIND DRIVE SPEC CALL SERCH RET Z DEC HL CALL SKIPBK LD A,(HL) SUB '0' ; ; SERCH SUBR SEARCHES FOR A STRING CHAR THE SAME AS CONTENTS ; OF C. IT WILL NOT GO BEYOND A SEMICOLON ';'. ; ENTRY- DESPACES UNTIL NUL OR NON-SPACE ; CHAR IS FOUND ; ENTRY- BC= STRING PTR ; EXIT - HL=1ST NON-SPACE CHAR ; Z=NT Z PUSH HL LD C,A ;IF CHAR >= 80H THEN SPACES CALL M,MLTSPC JR Z,EDITLP CP 0DH ;IF RETURN THEN DO CR-LF PUSH AF FOUND, NZ= FOUND ; SRCHSW: LD B,C LD C,2FH ;'/' SWNTFD: CALL SERCH RET Z ;NO SWITCHES INC HL LD A,(HL) EX DE,HL ,ZERO ADD HL,DE LD C,(HL) ;GET MESSAGE PTR INC HL LD B,(HL) CALL EDITOR NOPRFX: LD BC,ERRMSG CALL EDITOR JP 0 ;EQU 9D ; ; ; DONAME SUBR SETS FILE PARAMETER BLOCK PER INPUTTED ; STRING. DRIVE IS SET IF SPECIFIED. CHECKS FOR VALID IF AMBIGUOUS FILENAME USED, 0 IF SPECIFIC ; ;********************************************************* ; ; RDDRV: EQU 0F43 '[' ;IF OUT OF RANGE THEN ERR CCF JR C,DOERR CP 2AH ;IF CHAR = '*' THEN DO WILDCARD FORMAT JR Z,DOWILD CP '?' ;IF A(IY+DRIVEO),A OR A ;CLEAR CF LD A,(WILDFL) ;RETURN WILDCARD FLAG RET ; EXTNTN: EQU $ LD B,EXO ;SET PTR TO EXTENSION UP SYNTAX ERROR SCF RET ; DOWILD: EQU $ LD A,'?' ;FILL REMAINING FPB FIELD WITH ?s LD (WILDFL),A ;SET WILDCARD FLSVPF ;IF CHAR IN TABLE THEN RESERVED DJNZ RSVPLP INC B ;SET NZ RSVPF: POP HL POP BC RET ; RSVPTB: DB RSVPL-$-1 DB RET C CP 4 CCF RET ; ; SKIP BACKWARD ; SKIPBK: EQU $ LD A,(HL) CP 20H RET NZ DEC HL JR SKIPBK ; ; ; 0 !%)- "&*. #'+/  $(,0DIRECTORY SEARCH FOR FILE REFERENCED IN FPB ; NOTE: IF WILDCARDS USED, THESE ROUTINES RETURN FIRST MATCH. ; ENTRY- IY= FPBL ;SET DIR ENTRY COUNT LD C,(HL) DEC C ;IF NO ENTRIES THEN RETURN ERR JR Z,NOENT NXTFIL: PUSH IY ;FPB PTR -> HL POP R),HL ;SAVE VARS FOR SEARCH NEXT ENTRY LD (DIRVAR),BC LD DE,-NAMCNT ;BACK UP DIR PTR TO BEGINNING ; OF ENTRY ADD HENTRY POINT ; ENTRY & EXIT PARAMS SAME AS DIRECTORY SEARCH ; DIRSNX: LD HL,(DIRPTR) ;RESTORE SEARCH VARIABLES LD BC,(DIRVILE TO TOTAL SUBR ; ENTRY- (DE)= LO BYTE OF FILE LENGTH ; (BLKTOT)= TOTAL TO BE ADDED TO ; EXIT - DE= NEXT DIR EINC HL RES 7,A OR A ;IF CHAR = 0 THEN CHAR := SPACE LD C,A JR NZ,PRNT LD C,20H ;' ' PRNT: EQU $ PUSH HL CALL CO(HL) = MSD LD BC,-10000D ;TEN THOUSANDS DIGIT CALL DECDIG LD BC,-1000D ;THOUSANDS DIGIT CALL DECDIG LD BC,-100D ;HUNDRTPUT DEC A JR Z,OUTNUM LD C,ASPACE ;ELSE CHAR = ' ' JR OUTNUM ; FIRST: INC E ;FLAG := FLAG +1 OUTNUM: PUSH HL PUSH,B CPL LD D,A INC DE ADD HL,DE ;NUMBER := NUMBER BEFORE LAST SUBTRACT EX DE,HL ;NUMBER -> DE POP HL ;PTR := NEXT D0 AT LAST CHAR OF CMD LINE LD HL,SWBYTE LD (HL),A LD (SECND),A PUSH HL LD DE,CMDBFR LD (CMDPTR),DE LD C,INVSW ;IF EQU $ LD A,(HL) ;IF SWITCH THEN BYPASS CP ASLASH JR Z,SKIPSW LD IY,FPB ;SET UP CALL DONAM1 JR NC,CONT2 JR SYNERR CALL EDITOR LD HL,(DIRBUF) ;IF 1ST FILE = TITLE THEN ; OUTPUT IT INC HL INC HL PUSH HL POP IY BIT 7,(IY+TI PTR (DRIVE, NAME PRESET) ; EXIT - NC AND Z= NORMAL, CF OR NZ= ERROR [A= ERR CODE] ; HL= BLOCK ID OF FILE ; DE INC HL BIT 7,(HL) ;IF DELETED THEN SKIP LD B,NAMCNT ;SET ENTRY CHAR COUNT JR Z,NOGOOD NXCHAR: LD A,(DE) RES 7,A L,DE EX DE,HL LD HL,(BLKTOT) ;RETURN START BLOCK ID OF FILE XOR A ;CLEAR ERR RET ; NOGOOD: INC HL ;WASTE ENTRY DJNAR) JR NXTENT ; ; READ DIRECTORY SUBR ; ENTRY- IY= FPB PTR (DRIVE PRESET) ; (DIRBUF)= 1K DIRECTORY BUFFER ARENTRY(NAME) -1 ; ADDBLK: PUSH BC ;SAVE VARS LD A,(DE) ;GET THIS FILE'S LENGTH & ADD TO TOTAL LD C,A INC DE LD A,(DE) NOUT POP HL POP BC DEC C ;COUNT -1 RET Z PUSH BC LD A,C ;IF COUNT = 2 THEN OUTPUT '.' CP 2 LD C,2EH PUSH HL EDS DIGIT CALL DECDIG LD BC,-10D ;TENS DIGIT CALL DECDIG LD (HL),E ;UNITS DIGIT LD HL,TTHOU ;HL := PTR LD DE,0500H DE CALL CONOUT POP DE POP HL DEC HL ;NEXT DIGIT DEC D JR NZ,NXTDEC ;DO UNTIL DONE RET ; ; DIVIDE DE BY BC SUIGIT DEC HL RET ; ; ; DIRECTORY COMMAND ; START: EQU $ LD SP,STACK LD BC,SIGNON CALL EDITOR LD HL,DEFBFR ;MOV '/I' THEN SET BIT 0 OF ; SWITCH BYTE CALL SRCHSW JR Z,NOINV POP HL SET 0,(HL) PUSH HL NOINV: LD DE,(CMDPTR) ;RR ; CONT2: EQU $ LD A,(IY+NAMEO) ;IF NO NAME SPEC'D THEN USE ALL AND NOFILM JR NZ,SPECIF PUSH IY POP HL LD B,NAMCNTLAT) CALL NZ,PRNAME LD BC,HDR2M ;OUTPUT HEADER MSG CALL EDITOR LD IY,FPB CALL DIRSRH ENTLP: LD C,A JP NZ,SYSERR  DE= DIRECTORY PTR (NOT NEEDED FOR RE-ENTRY) ; C= ENTRIES REMAINING ; (BLKTOT)= FILE START BLOCK ID ; DI;CLEAR ATTRIB. CP '?' ;IF WILDCARD THEN OK AS IS JR Z,GOOD CP (HL) ;ELSE IF (FPB) = (DIR) THEN MATCH JR Z,GOOD SEZ NOGOOD NXTENT: DEC C ;IF NOT LAST ENTRY THEN ADD ; FILE LENGTH TO TOTAL & LOOP PUSH AF EX DE,HL CALL ADDBLK EXA ; DIRRD: EQU $ READIR: LD A,(IY+DRIVEO) ;SET CURRENT DIR := FPB(DRIVE) LD C,A CALL SETDRV LD BC,(DIRBUF) ;SET READ PT LD B,A LD HL,(BLKTOT) ADD HL,BC LD (BLKTOT),HL POP BC RET ; ; ; PRINT FILENAME FROM FPB SUBR ; ENTRY- IY= FPB CALL Z,CONOUT POP HL JR PRNXTC ; ; OUTPUT DECIMAL WORD SUBR ; ENTRY- BC = WORD VALUE OF NUMBER TO OUTPUT ; PUT2D: ;D := COUNT, E := FLAG NXTDEC: LD A,(HL) ;CHAR := NUMBER + '0' ADD '0' LD C,A ;PASS CHAR IN C FOR OUTPUT CP '0' ;IF CBR ; DECDIG: EQU $ PUSH HL ;PTR EX DE,HL ADD HL,BC ;HL := HL + (- NUMBER) JR NC,ADDIT ;IF NO BORROW THEN DIG :=E COMMAND LINE TO BUFFER LD DE,CMDBFR LD C,(HL) ;GET COUNT RES 7,C ;INSURE ONLY 128D BYTES LD A,C ;IF CNT = 0 THEN ABESTORE PTR LD C,DELSW ;IF '/D' THEN SET BIT 1 CALL SRCHSW POP HL JR Z,NODELS SET 1,(HL) NODELS: LD HL,(CMDPTR) ;GO FT ALLP: LD (HL),AQUEST INC HL DJNZ ALLP SPECIF: CALL READIR JR Z,CONT3 ;IF DIRECTORY READ ERROR THEN EXIT LD C,A JR C,DIRDON PUSH DE ;IF INVISIBLE THEN CHECK SWITCH POP IY BIT 7,(IY+INVATT) JR Z,INVBYP ;IF SWITCH NOT SET THEN SKIP RSRH: EQU $ LD HL,(DIRBUF) ;SET PTR LD (DIRPTR),HL LD C,(HL) ;BLOCK TOTAL:= START BLOCK LD B,0 LD (BLKTOT),BC INC HT 7,A ;ELSE TRY WITH ATTRIB. SET CP (HL) JR NZ,NOGOOD GOOD: INC DE ;LOOP IF COUNT <> 0 INC HL DJNZ NXCHAR LD (DIRPT DE,HL POP AF JR NZ,NXTFIL NOENT: LD A,6 ;RETURN NOT FOUND ERROR CP A ;SET Z SCF RET ; ; DIRECTORY SEARCH NEXT R CALL SETMAP LD BC,0 ;SET BLOCK ID CALL SETBID LD C,4 ;SET BLK COUNT CALL SETCNT JP READF ; ; ADD LENGTH OF F PTR (NAME PRESET) ; ; PRNAME: EQU $ PUSH IY POP HL LD C,8D ;SET CHAR COUNT PUSH BC PRNXTC: LD A,(HL) ;GET CHAR  EQU $ PUSH BC ;BC -> DE POP DE LD HL,UNIT ;ZERO DIGITS LD B,FIVE SET0: LD (HL),ZERO INC HL DJNZ SET0 DEC HL ;HAR <> '0' THEN SET FLAG JR NZ,FIRST INC E ;IF FLAG <> 0 THEN OUTPUT DEC E JR NZ,OUTNUM LD A,D ;IF COUNT = 1 THEN OU DIG +1 EX DE,HL ;ELSE DIG := DIG +1 POP HL ;PTR INC (HL) JR DECDIG ; ADDIT: LD A,C ;BC := +BC CPL LD E,A LD AORT OR A JR Z,SYNERR LD B,ZERO INC HL ;DON'T MOVE CHAR COUNT LDIR XOR A ;CLEAR & INIT VARIABLES LD (DE),A ;PUT IND FILE SPEC SKIPSW: LD C,ASPACE CALL SERCH1 CALL SKIPO1 JR NZ,CONT1 SYNERR: LD C,5 ;SYNTAX ERR JP SYSERR ; CONT1: JP SYSERR ; CONT3: EQU $ LD A,(IY+DRIVEO) ;PUT DRIVE # INTO HEADER ADD AZERO LD (MSGDRV),A LD BC,DIRHDR ;OUTPUT HEADE LD A,(SWBYTE) BIT 0,A JR Z,INVBYP INVBYP: EX DE,HL CALL PRNAME LD C,THREE ;OUTPUT 3 SPACES CALL MLTSPC LD C,(IY+L0 !%)- "&*. #'+/  $(,0ENGO) ;OUTPUT FILE LENGTH LD B,(IY+LENGO+1) CALL PUT2D LD C,FOUR CALL MLTSPC LD C,DELATC ;IF DELETED THEN OUTPUT 'D' ECND),A CALL Z,CRLF NEXT: LD IY,FPB CALL DIRSNX JR ENTLP ; DIRDON: CALL CRLF LD BC,(BLKTOT) ;OUTPUT # USED BLOCKS PCUPERTINO, CA',0 DIRHDR: DB CR,LF,'Directory for ' MSGDRV: DB '0: ',0 HDR2M: DB CR,LF,'Name',88H,'Length',83H,'Attrib.',83H  ; DIRBUF: DW BUFFER ; CMDBFR: DS 129D BUFFER: EQU $ ; END  ;SAVE FPB PTR IN IY POP IY LD HL,(CMDPTR) CALL SKIP ;SKIP LEADING SPACES LD (CMDPTR),HL ;SAVE NEW PTR EX DE,HL PUSDE ;SKIP OVER ':' L96: LD B,NAMCNT ;B := MAX CHARS L98: CALL RSVP JR Z,LB9 INC HL ;PTR := PTR +1 CP '*' ;IF WIL CP '.' ;IF RESERVED CHAR NOT '.' THEN FILL ; WITH SPACES JR NZ,LE9 INC DE ;GET NEXT CHAR AFTER '.' LC8: CALLEXTENT, S1, S2, RECORD COUNT LF2: INC HL LD (HL),0 DJNZ LF2 LD (CMDPTR),DE PUSH IY POP HL ;COUNT WILDCARDS LD  RET RSVP1: PUSH BC PUSH HL LD B,TABCNT ;B := ENTRY COUNT LD HL,RSVPT RSVPL: CP (HL) JR Z,RSVPX ;IF FOUND THEN EUBR ; ENTRY- DE= FCB PTR ; EXIT - A= 0 IF OK ; ;************************************** RDSEC: LD C,RDF JP BDOS ;**** LD (DE),A PUSH DE ;BUFFER PTR LD C,RDCF ;GET INPUT FROM USER CALL BDOS POP HL ;BUFFER PTR INC HL ;COUNT = CMDBFR[ NZ = READ ERROR ; ;********************************************************** RDFILE: LD (RDPTR),BC ;SAVE ACTUAL READ PTR  BIT 7,(IY+DELATT) CALL PUTSW1 LD C,PROATC ;IF WRITE PROTECTED THEN OUTPUT 'W' BIT 7,(IY+PROATT) CALL PUTSW LD C,INUSH BC CALL PUT2D LD BC,USDMSG CALL EDITOR POP BC LD HL,MAXBLK OR A SBC HL,BC PUSH HL POP BC CALL PUT2D LD DB 'Name',88H,'Length',83H,'Attrib.',CR,0 FREMSG: DB ' Free',CR,0 USDMSG: DB ' Used',85H,0 ; SWBYTE: DB 0 SECND: DB 0 ; H IY POP HL ;FPB PTR LD A,(DE) ;IF CHAR = 0 THEN DONE OR A JR Z,L89 SBC 'A' - 1 ;MAKE 'A'-'P' = 1-15 FOR DRIVE # DCARD THEN ENTER '?' JR NZ,LA9 LD (HL),'?' JR LAB LA9: LD (HL),A ;ADD CHAR TO FCB FILENAME INC DE LAB: DJNZ L98 RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LE9 INC HL ;IF CHAR <> '*' THEN EXIT CP '*' JR NZ,LD9 LD (HL),'?' JR LDBC,NAMCNT + TYPCNT L01: INC HL LD A,(HL) CP '?' JR NZ,L09 INC B L09: DEC C JR NZ,L01 LD A,B OR A RET XIT INC HL DJNZ RSVPL INC B ;RETURN NZ RSVPX: POP HL POP BC RET RSVPT: DB '=_.:;,<>' TABCNT: EQU $ - RSVPT********************************** ; ; SET DISK READ ADDRESS SUBR ; ENTRY- DE= ADDRESS ; ;*********************************1] AND 7FH LD C,(HL) LD B,0 RES 7,C ;MAKE SURE < 128 INC HL ;CMDPTR = .CMDBFR[2] LD (CMDPTR),HL ADD HL,BC ;CMDBFR LD DE,DEFBFR ;READ 1ST SECTOR INTO DEFAULT BUFFER FOR NOW CALL SETDMA LD DE,FCB CALL RDSEC OR A ;IF BAD READ THEN RETVATC ;IF INVISIBLE THEN OUTPUT 'I' BIT 7,(IY+INVATT) CALL PUTSW LD C,SYSATC ;IF SYSTEM FILE THEN OUTPUT 'S' BIT 7,(IY+SY BC,FREMSG CALL EDITOR XOR A JP ZERO ; PUTSW1: JP Z,CONOUT JR OUTSP ; PUTSW: JP NZ,CONOUT OUTSP: LD C,ASPACE JP CTOGGLE: DB 02H WILDFL: DB 0 DIRPTR: DW BUFFER DIRVAR: DW 0 BLKTOT: DW 0 CMDPTR: DW CMDBFR FPB: EQU $ DRIVE: DB 0 NAME: D LD B,A INC DE ;IF NEXT CHAR = ':' THEN MUST BE DRIVE LD A,(DE) CP ':' JR Z,L90 DEC DE ;ELSE BACK UP & USE DEFAUL ;IF NOT DONE THEN LOOP LAF: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LC0 INC DE ;SKIP OVER EXTRA CHARS TO '.' JB LD9: LD (HL),A ;ADD CHAR TO FCB INC DE LDB: DJNZ LC8 LDF: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LF0 IN ;************************************ ; ; RESERVED CHAR TEST SUBR ; ENTRY- (DE) = CHAR TO TEST ; EXIT - ZF = FOUND ;************************************** ; ; OPEN FILE SUBR ; ENTRY- DE= FCB PTR ; EXIT - A= -1 IF NOT ON DISK ; ;******** SETDMA: LD C,26D JP BDOS ;************************************** ; ; READ CONSOLE BUFFER SUBR ; EXIT - CMDBFR =[COUNT + 2] = 0 /* END OF LINE = NUL */ LD (HL),0 RET ;********************************************************** ; ;URN ERR RET NZ ; IF FILE STARTS WITH JP 0000H THEN ASSUME IT IS A HEADER BLOCK LD A,(DEFBFR) CP 0C3H JR NZ,RESCAN SATT) CALL PUTSW LD C,DIVIDR ;OUTPUT # SPACES CALL MLTSPC LD A,(SECND) ;IF 2ND COLUMN THEN OUTPUT CRLF XOR ONE LD (SONOUT ; ; MESSAGES ; SIGNON: DB CR,'PHIMON Directory display Utility Ver 1.0' DB CR DB '(c) 1981 GRH Electronics W 0,0,0 EX: DW 0 LENG: DW 0 BLOCK: DW 0 MAP: DW 0 ALTNAM: DW 0,0,0,0 UNIT: DW 0,0 ;PUT DECIMAL ACCUMULATORS TTHOU: DB 0 T DRIVE L89: LD A,(DFLTDK) LD (HL),A ;FCB(DISK) := DRIVE # JR L96 L90: LD A,B ;USE SPECIFIED DISK LD (HL),B INC R LAF LB9: INC HL ;FILL REMAINDER OF FCB WITH SPACES LD (HL),' ' DJNZ LB9 LC0: LD B,TYPCNT ;COUNT := TYPE CHAR COUNT C DE ;WASTE CHARS JR LDF LE9: INC HL ;FILL REMAINING TYPE WITH SPACES LD (HL),' ' DJNZ LE9 LF0: LD B,ZROSIZ ;ZERO  ; ;************************************ RSVP: LD A,(DE) ;IF CHAR <= ' ' THEN RETURN Z CP ' ' + 1 JR NC,RSVP1 XOR A *********************************** OPEN: LD C,OPENF JP BDOS ;************************************** ; ; READ SECTOR S CONSOLE INPUT ; ;************************************** RDCON: LD DE,CMDBFR ;INIT BUFFER LD A,CBFRSZ ;CMDBFR[0] = CBFRSZ  READ FILE SKIPS ANY HEADER BLOCK & ONLY LOADS CODE ; ENTRY- BC = LOAD BUFFER PTR ; EXIT - Z = SUCCESSFUL READ ; ;ELSE ASSUME THE 1ST SECTOR IS GOOD & LOAD IT LD HL,(DEFBFR+1) LD A,H OR L JR Z,READ1 ; NOT HEADER IF HERE, MOVE INTO0 !%)- "&*. #'+/  $(,0 LOAD AREA & CONTINUE WITH NEXT SECTOR RESCAN: LD HL,DEFBFR LD DE,(RDPTR) LD BC,SECSIZ LDIR LD (RDPTR),DE ;UPDATE REAO RSVP SO ABORT BY RETURNING CF CP H RET C JP READ1 ; RDDONE: XOR A ;RETURN Z RET ;*****************************O PARAM STORAGE CALL LOAD16 LD HL,(CMDPTR) ;SEARCH FOR 2ND PARAMETER (AFTER ',') LD C,',' CALL SEARCH SCF ;IF NO 2INE THEN RETURN CF RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET 2ND PARAM. RET C CALL LOAD16 ;*****L SKIP ;SKIP ANY SPACES SCF RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET PARAMETER RET C CALL LOAD16 ************************************************** ; ; CHECK BOUNDS SUBR TESTS PARAM 1 & 2 FOR OUT OF BOUNDS VALUES & IF OK,TORE IT & RETURN RESULT RET ;*************************************************************************** ; ; COMPARE  MEMTOP PAGE -1 DEC A LD DE,($MEMRY) ;ADD VALUE TO BUFFER START (FROM OVERLAY) ADD HL,DE RET C ;IF OVERFLOW THEN RETURN= NUMBER ; CF= NON HEX CHAR (BUT NOT SPACE OR COMMA) ; BC= PTR TO NON-HEX CHAR ; A= NON-HEX CHAR ; ;******************* L,A INC BC ;PTR = PTR + 1 LD A,(GETFLG) ;BUMP FLAG TO NOT 0 INC A LD (GETFLG),A JR GETLP GETCHK: LD A,(GETFLG) ;ILL PRTHEX LD A,L ;************************************************ ; ; PRINT BYTE HEX VALUE TO CONSOLE SUBR ; ENTRY- AII-HEX ; ENTRY- A= BINARY NIBBLE ; EXIT - A= ASCII REPRESENTATION OF THE NIBBLE ; ;*****************************************D PTR ; IF HERE, EITHER WE ARE DISCARDING THE 1ST SECTOR OR READING THE 2ND READ1: LD DE,(RDPTR) ;READ INTO LOAD AREA DIRE***************************** ; ; FETCH PARAMETERS SUBR ; ENTRY- CMDPTR= PTR TO 1ST NUMERICAL PARAMETER ; EXIT - CF= ERR ND PARAMETER THEN RETURN CF RET Z INC HL ;PASS OVER ',' ;******************************************************************************************* ; ; THIS ENTRY IS SAME AS ABOVE ; EXCEPT DOES SEARCH FOR COMMA. ; ;**********************OR A ;RETURN NO ERR RET ;********************************************************** ; ; LOAD WORD SUBR ; ENTRY- DE= W ; STORES THE OFFSETTED VALUES BACK INTO THE RESPECTIVE LOCATIONS. ; EXIT - CF= OUT OF BOUNDS ; ;**************************BOUNDS SUBR ADDS VALUE TO THE BASE OF THE BUFFER & CHECKS FOR ; OVERFLOW. THEN CHECKS NEW VALUE'S PAGE AGAINST THE TOP OF AVAI CF CP H ;ELSE COMPARE PAGE VALUE TO MEMTOP PAGE -1 RET ;RETURN CF IF PAGE > MEMTOP PAGE -1 ;***************************************************************************** GETNUM: PUSH HL ;HL -> BC POP BC LD A,0 ;FLAG = 0 LD (GETFLG),F FLAG = 0 THEN RETURN CF SUB 1 RET C LD A,(BC) ;GE-GET CHAR CP ' ' ;IF SPACE THEN RETURN NC RET Z CP ',' ;IF= VALUE ; ;************************************************ PRTHEX: OR A RLA CALL PRHXDG PRHXDG: RLA RLA RLA RLA********************************** HX2ASC: AND 0FH ;ONLY NIBBLE PLEASE CP 10 ;IF 0..9 THEN OK JR C,NTALPH ADD 7 ;ELSCTLY CALL SETDMA LD DE,FCB CALL RDSEC OR A ;IF END OF FILE THEN DONE JR NZ,RDDONE LD DE,SECSIZ ;PTR = PTR + SECTOR$; ;********************************************************** GET3PAR: LD HL,(CMDPTR) ;IF NO PARAMETERS THEN RETURN CF CA ; ; GET 2 PARAMETERS SUBR. SAME AS ABOVE EXCEPT: ; ENTRY- DE= PARAMETER STORAGE PTR ; HL= CMDPTR ; EXIT - CF= ERR ; ;****************** GET1PC: LD HL,(CMDPTR) LD C,',' CALL SEARCH SCF RET Z INC HL ;*******************************ORD PTR ; HL= VALUE ; EXIT - DE= WORD PTR + 2 (NEXT WORD IN SEQUENCE) ; ;*************************************************************************************************** CKBNDS: LD HL,(PARAM1) ;START WITH PARAM 1 CALL CPBNDS ;IF OUT THEN RETULABLE ; MEMORY'S PAGE & RETURNS CARRY IF EITHER IS OUT. ; ENTRY- HL = VALUE TO COMPARE ; EXIT - HL = CORRECTED VALUE ; CF ******************************************************* ; ; GET NUMBER SUBR CONVERTS ASCII-HEX CHARS IN STRING TO BINARY WORA LD HL,0 ;ACCUM = 0 GETLP: LD A,(BC) ;CHAR = (PTR) CALL ASC2HX ;ATTEMPT TO CONVERT CHAR JR C,GETCHK ;IF ILLEGAL THE COMMA THEN RETURN NC RET Z OR A ;IF END OF LINE THEN RETURN NC RET Z SCF ;ELSE RETURN CF RET ;*********** PUSH AF CALL HX2ASC ;CONVERT NIBBLE TO ASCII-HEX PUSH HL LD C,A CALL CONOUT POP HL POP AF RET ;**********E OFFSET 10..15 TO 'A'..'F' NTALPH: ADD '0' ;CONVERT TO ASCII RET ;**************************** ; ; CHECK FOR DONSIZE LD HL,(RDPTR) ADD HL,DE LD (RDPTR),HL LD A,(MEMTOP+1) ;IF NEW PAGE > RESERVED_PAGE - 1 THEN DEC A ; GOING INTLL SKIP SCF RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET 1ST PARAMETER RET C LD DE,PARAM1 ;INIT PTR T******************************************************** GET2PAR: CALL SKIP ;SKIP ANY TRAILING SPACES SCF ;IF END OF L***************** ; ; GET 1 PARAMETER SUBR SAME AS ABOVE ; ;************************************************ GET1PAR: CAL******** LOAD16: EX DE,HL ;STORE IT LD (HL),E INC HL LD (HL),D INC HL EX DE,HL RET ;*************************RN CF RET C LD (PARAM1),HL ;ELSE STORE NEW VALUE LD HL,(PARAM2) ;THEN CHECK PARAM 2 CALL CPBNDS LD (PARAM2),HL ;S= BOUNDS ERROR ; ;*************************************************************************** CPBNDS: LD A,(MEMTOP+1) ;SET UPDS UNTIL ; A NON- HEX CHAR IS ENCOUNTERED. IF NOT SPACE OR COMMA THEN RETURNS CARRY. ; ENTRY- HL = TEXT POINTER ; EXIT - HL N CHECK FOR DELIMITER ADD HL,HL ;ACCUM = ACCUM * 16 ADD HL,HL ADD HL,HL ADD HL,HL ADD L ;ACCUM = ACCUM + DATA LD********************** ; ; PRINT HEX VALUE SUBR ; ENTRY- HL = VALUE ; ;******************************** PRT2H: LD A,H CA***************************************************************** ; ; HEX TO ASCII-HEX CONVERTER CONVERTS BINARY NIBBLE TO ASCE SUBR ; ;**************************** CKDONE: EX DE,HL LD HL,(DISEND) OR A SBC HL,DE EX DE,HL RET SUBTTL MES0 !%)- "&*. #'+/  $(,0 TITLE PHIMON FILE TRANSFER UTILITY FOR CP/M ;********************************************************* ; ; PHIMON File Tra.yy will result in a CP/M filename of ; "xxxxxx .yy ". ; At this time, only transfers from PHIMON will be ; implemented. ards. ; ; Drive (d:) specifications: ; 0 thru 3 = PHI drives ; A thru P = Disk drives ; ;*************************** 0 ; ; ASCII CONSTANTS ; LF: EQU 0AH CR: EQU 0DH ASPACE: EQU 20H ; ; ASSEMBLER DIRECTIVES ; ORG TPA ; PGMST: JEMICOLON ';'. ; ENTRY- DE= STRING PTR ; C= CHAR TO SEARCH FOR ; EXIT - HL= CHAR PTR ; Z=NOT FOUND ; ACE CHAR ; Z=NOT FOUND ; SKIPON: PUSH BC POP HL SKIPO1: LD A,(HL) CP 20H ;IF CHAR <> ' ' THEN RETURN JR NZ,FO PUSH AF CALL Z,CRLF POP AF JR Z,EDITLP CALL CONOUT JR EDITLP ; ; MULTI SPACE SUBR OUTPUTS <= 127D SPACES ; E JUST ERROR CP (HL) JR NC,NOPRFX INC HL ;POINT TO 1ST ENTRY ADD A ;COMPUTE TABLE PTR LD E,A LD D,ZERO ADD HL,DEFM: DB 'File not found',0 TYPEM: DB 'File type',0 DIRM: DB 'Directory',0 NORMM: DB 'No room',0 ; NUMENT: EQU 9D ; ; ; RETURN CF SUB '0' RET C CP 4 ;IF > MAXIMUM DRIVE # THEN RETURN CY CCF RET ; ; SKIP BACK SUBR SKIPS PRECEDING SPACESD. ; ; ENTRY- BC= STRING PTR TO 1ST NON-SPACE CHAR. ; IY= FPB PTR ; EXIT - IY= FPB PTR TO NAME FIELD ; 0H ;PHI PROM ADDR ;********************************************************* ; DONAME: PUSH BC POP HL DONAM1: PUSH IY ;SETnsfer Utility for CP/M ; ; (c) 1981 GRH Electronics, CUPERTINO, CA ; ;***************************************************; ; SYNTAX: ; PXFER d: = d:filename.ex <,d:file2.ex,...filen.ex> ; ; Where: ; d: = REQUIRED drive ID which will ul****************************** FORM ;************************************************************* ; *INCLUDE HERRMAC.Z80 P PSTART ; ; ; ASCII TEXT PROCEDURES ; CONOUT: EQU $ LD E,C ;SETUP LD A,C ;IF CHAR = CTRL-P THEN ONLY TOGGLE FLAG CSERCH: PUSH DE POP HL SERCH1: LD A,(HL) ;IF CHAR = NUL THEN RETURN Z OR A RET Z CP C ;ELSE IF CHAR=C THEN RETURN NZ JUND INC HL JR SKIPO1 ; ; CARRIAGE RETURN/LINE FEED SUBR ; CRLF: EQU $ LD C,0DH CALL CONOUT LD C,0AH JP CONOUT NTRY- C= # SPACES ; EXIT - ZF SET ; MLTSPC: EQU $ LD B,C RES 7,B LD C,20H SPLP: PUSH BC ;SAVE CNT CALL CONOUT PO LD C,(HL) ;GET MESSAGE PTR INC HL LD B,(HL) CALL EDITOR NOPRFX: LD BC,ERRMSG CALL EDITOR JP 0 ; ERRMSG: DB ' ErrSELECT DRIVE SUBR - RETURNS DRIVE # ; ENTRY- DECKSL : POINTER IN BC ; DCKSL1 : POINTER IN DE ; EXIT - A= DRIVE # ; SKIPBK: EQU $ LD A,(HL) CP 20H ;IF NOT SPACE THEN RETURN RET NZ DEC HL JR SKIPBK ; ; ; DONAME SUBR SETS FILE HL= STRING PTR TO LAST CHAR +2 ; CF= ERROR [ERR CODE IN A] ; A= '?' IF AMBIGUOUS FILENAME USED, 0 IF SPECIUP POP DE PUSH DE XOR A LD (WILDFL),A ;CLEAR WILDCARD FLAG LD B,EXO ;ZERO FPB FILENAME DOLP: LD (DE),A INC DE DJN****** ; ; This program allows transfer of PHIMON files on tape ; to CP/M files on disk for subsequent use under CP/M. ; Ttimately determine ; direction of transfer. ; filename.ex = filename to be transferred in correct ; ; FORM ;************************************************************* ; ; SYSTEM LINKS ; BDOS: EQU 0005H DEFFCB: EQU 0P 10H JR Z,TGLLPT LD A,(TOGGLE) AND 7 ;LIMIT 0-7 LD C,A JP BDOS ; TGLLPT: EQU $ LD A,(TOGGLE) ;2 <-> 5 XOR 7 AR Z,FOUND CP ';' ;IF CHAR = ';' THEN RETURN Z RET Z INC HL ;ELSE TRY NEXT CHAR JR SERCH1 ; FOUND: OR A RET ; ; S ; ; MESSAGE EDITOR SUBR ; ENTRY- BC = STRING PTR ; EDITOR: EQU $ PUSH BC EDITLP: POP HL LD A,(HL) ;GET CHAR INC P BC DJNZ SPLP XOR A RET ; ; SYSTEM ERROR SUBR - PRINTS ERROR MESSAGES ; ENTRY- ERROR NUMBER (1 THRU n) IN C ; Eor!',CR,LF,0 ; ERRTBL: DB NUMENT ; DW CRCM DW NTFM DW JAMM DW PROTM DW SYNM DW FNTFM DW TYPEM DW DIRM DW NO ; Z= NO DRIVE SPEC'D ; CF= INVALID DRIVE # ; DECKSL: PUSH BC POP DE DCKSL1: LD C,':' ;FIND DRIVE SPEC  PARAMETER BLOCK PER INPUTTED ; STRING. DRIVE IS SET IF SPECIFIED. CHECKS FOR VALID ; CHARACTERS & ALPHA 1ST CHARACTFIC ; ;********************************************************* ; ; DEFINE THE FOLLOWING SOMEWHERE: ; DRIVEO: EQU -1 NZ DOLP POP DE LD B,EXO-NAMEO DONEXT: LD A,(HL) ;GET STRING CHAR RES 7,A ;CLEAR ATTRIBUTE INC HL PUSH BC CALL RSVP1 he CP/M filename will be the same as the PHIMON file- ; name with extra blanks added as needed. I.E., the PHI ; name of xxxxxxformat according to d:. ; file2,...filen = optional files to be transferred. ; ; Note, source filenames may include wildc05CH DEFBFR: EQU 0080H TPA: EQU 0100H ; SECSIZ: EQU 128D STKSIZ: EQU 64D DIRSIZ: EQU 1024D ; ; CONSTANTS ; ZERO: EQUND 7 LD (TOGGLE),A RET ; ; SERCH SUBR SEARCHES FOR A STRING CHAR THE SAME AS CONTENTS ; OF C. IT WILL NOT GO BEYOND A SPACEL BYPASSES TRAILING SPACES UNTIL NUL OR NON-SPACE ; CHAR IS FOUND ; ENTRY- BC= STRING PTR ; EXIT - HL=1ST NON-SPHL OR A RET Z PUSH HL LD C,A ;IF CHAR >= 80H THEN SPACES CALL M,MLTSPC JR Z,EDITLP CP 0DH ;IF RETURN THEN DO CR-LFXIT - CY SET ; SYSERR: EQU $ PUSH BC CALL CRLF POP BC DEC C LD A,C LD HL,ERRTBL ;IF ENTRY COUNT < ERROR# THEN ; RMM ; CRCM: DB 'CRC',0 NTFM: DB 'Block not found',0 JAMM: DB 'Tape',0 PROTM: DB 'Write Protect',0 SYNM: DB 'Syntax',0 FNT CALL SERCH RET Z ;IF NON SPEC'D THEN USE LAST SELECTED DEC HL CALL SKIPBK ;SKIP PREVIOUS SPACES LD A,(HL) ;IF <0 THEN ER ARE PERFORMED. ; WILDCARDS ARE FORMATTED. '*' FILLS REMAINDER OF FPB ; WITH '?'s, '?'s ARE INSERTED AS ENCOUNTEREAMEO: EQU 0 EXO: EQU NAMEO+6 LENGO: EQU EXO+2 BLOCKO: EQU LENGO+2 MAPO: EQU BLOCKO+2 ALTNMO: EQU MAPO+2 ; RDDRV: EQU 0F43;IF RESERVED CHAR THEN EXIT POP BC JR Z,DOCOLN CP '[' ;IF OUT OF RANGE THEN ERR CCF JR C,DOERR CP 2AH ;IF CHAR = '*'0 !%)- "&*. #'+/  $(,0 THEN DO WILDCARD FORMAT JR Z,DOWILD CP '?' ;IF AMBIGUOUS THEN SET FLAG JR NZ,DONOQU LD (WILDFL),A DONOQU: LD (DE),A ;EEXTNTN: EQU $ LD B,EXO ;SET PTR TO EXTENSION PUSH IY POP DE EXTLP: INC DE DJNZ EXTLP LD B,LENGO-EXO JR DONEXT ; DITH ?s LD (WILDFL),A ;SET WILDCARD FLAG WILDLP: LD (DE),A INC DE DJNZ WILDLP JR DOMORE ; ; ALPHA CHAR TEST ; ENT FPB(LENG, BLOCK):= DIR(LENG, 1ST BLK) ; SETBID:= BLOCK, SETCNT:= LENG ; ;*************************************AME) PTR LD HL,NAMCNT ;FETCH FILE LENGTH FROM DIRECTORY ADD HL,DE LD C,(HL) INC HL LD B,(HL) LD (IY+LENGO),C LDD OF FILE ; DE= DIRECTORY PTR (NOT NEEDED FOR RE-ENTRY) ; C= ENTRIES REMAINING ; (BLKTOT)= FILE STTHEN SKIP LD B,NAMCNT ;SET ENTRY CHAR COUNT JR Z,NOGOOD NXCHAR: LD A,(DE) RES 7,A ;CLEAR ATTRIB. CP '?' ;IF WILDCARD THSTART BLOCK ID OF FILE XOR A ;CLEAR ERR RET ; NOGOOD: INC HL ;WASTE ENTRY DJNZ NOGOOD NXTENT: DEC C ;IF NOT LAST ENTRY Y- IY= FPB PTR (DRIVE PRESET) ; (DIRBUF)= 1K DIRECTORY BUFFER AREA ; DIRRD: EQU $ READIR: EQU $ LD C,(IY+DRIVEO)  DE= NEXT DIR ENTRY(NAME) -1 ; ADDBLK: PUSH BC ;SAVE VARS LD A,(DE) ;GET THIS FILE'S LENGTH & ADD TO TOTAL LD C,A INC DE := 0 CALL SETBID LD B,4 ;WRITE COUNT := 400H CALL SETCNT JP WRITF ; ; DELETE FILE(S) REFERENCED BY FPB FROM CURRENTND THEN GO DELETE RET NZ DELNXT: JR C,DELLST ;IF NOT FOUND THEN EXIT DEL1: PUSH IY ;SAVE FPB PTR PUSH DE ;DIR PTR(NAME) ->LSE PUT CHAR INTO FPB INC DE DJNZ DONEXT DOMORE: LD A,(HL) ;IF NEXT CHAR= PERIOD THEN SET EXTEN. RES 7,A NAMEDN: CP 2EH OCOLN: EQU $ CP ':' ;IF NOT COLON THEN DONE JR NZ,NAMEDN PUSH HL DEC HL ;IF LAST CHAR NOT VALID DRIVE# THEN ERR EX DE,RY- C= CHAR ; EXIT - CF= NOT ALPHA, NC= ALPHA ; ALPHAT: LD A,C ALPHA1: EQU $ CP ':' ;IF > '9' THEN OK RET NC CP '0' ******************* ; ; PHI PROM VECTORS ; SETMAP: EQU 0F403H SETBID: EQU 0F406H SETCNT: EQU 0F409H SETDRV: EQU 0F40FH  (IY+LENGO+1),B CALL SETCNT POP HL ;DIR(NAME) PTR PUSH IY ;IY -> DE (DEST) POP DE LD BC,NAMCNT LDIR XOR A ;CLEAR ART BLOCK ID ; DIRSRH: CALL DIRRD ;IF NOT IN DIRBUF THEN READ CURRENT DIR RET NZ ;IF ERR THEN RETURN LD HL,(DIRBUF) ;SET PEN OK AS IS JR Z,GOOD CP (HL) ;ELSE IF (FPB) = (DIR) THEN MATCH JR Z,GOOD SET 7,A ;ELSE TRY WITH ATTRIB. SET CP (THEN ADD FILE LENGTH PUSH AF ;TO TOTAL & LOOP EX DE,HL CALL ADDBLK EX DE,HL POP AF JR NZ,NXTFIL NOENT: LD A,6 ;RETU;IF DIRECTORY IN THEN RETURN LD A,(DIRIN) CP C RET Z LD A,C ;DIR IN := NEW DIR LD (DIRIN),A CALL SETDRV LD BC,(DIR LD A,(DE) LD B,A LD HL,(BLKTOT) ADD HL,BC LD (BLKTOT),HL POP BC RET ; ; WRITE DIRECTORY IN MEMORY TO DRIVE IN DIRECTORY ; ENTRY- IY= FPB PTR (DRIVE, NAME PRESET) ; C(BIT 0)= 1= VERIFY {PRINT EACH FILENAME AS DELETED ;  IY POP IY BIT 7,(IY+NAMEO) ;IF ALREADY DELETED THEN IGNORE JR Z,DELED BIT 7,(IY+NAMEO+1) ;IF PROTECTED THEN ERR JR NZ JR Z,EXTNTN LD A,(IY+0) ;ELSE SET NOT DELETED ATTRIB & SET 7,(IY+0) CALL ALPHA1 ;IF 1ST CHAR <> ALPHA THEN ERR JR C,DOHL PUSH BC CALL DCKSL1 POP BC POP HL ;RESTORE PTR JR C,DOERR JR Z,NODRV1 LD C,A CALL SETDRV NODRV1: CALL SKIPO1;ELSE IF < '0' THEN OK CCF RET ; ; LOOKUP SEARCHES DIRECTORY FOR FILE REFERENCED BY FPB ; ENTRY- IY= FPB PTR (DRIVE,  READF: EQU 0F412H WRITF: EQU 0F415H RDBID: EQU 0F42DH ; ; LOOKUP: CALL DIRSRH ;SEARCH DIRECTORY FOR FILE LOOK1: RET NZ ERRS RET ; ; DIRECTORY SEARCH FOR FILE REFERENCED IN FPB ; NOTE: IF WILDCARDS USED, THESE ROUTINES RETURN FIRST MATCH. TR LD (DIRPTR),HL LD C,(HL) ;BLOCK TOTAL:= START BLOCK LD B,0 LD (BLKTOT),BC INC HL ;SET DIR ENTRY COUNT LD C,(HL) HL) JR NZ,NOGOOD GOOD: INC DE ;LOOP IF COUNT <> 0 INC HL DJNZ NXCHAR LD (DIRPTR),HL ;SAVE VARS FOR SEARCH NEXT ENTRY RN NOT FOUND ERROR CP A ;SET Z SCF RET ; ; DIRECTORY SEARCH NEXT ENTRY POINT ; ENTRY & EXIT PARAMS SAME AS DIRECTORBUF) ;SET READ PTR CALL SETMAP LD BC,0 ;SET BLOCK ID CALL SETBID LD C,4 ;SET BLK COUNT CALL SETCNT JP READF ; ;  FPB ; ENTRY- (DIRBUF)= 1K DIRECTORY BUFFER AREA ; (CURDRV)= DRIVE # OF DIRECTORY IMAGE AT (DIRBUF) ; ;********** 0= NO VERIFY ; C(BIT7)= RESERVED FOR USE ; EXIT - CF OR NZ= ERROR [A= ERR CODE] ; MF= DELET,DELPRT RES 7,(IY+NAMEO) ;ELSE DELETE FILE AND LD A,(DELCTL) ;SET DIR WRITE FLAG SET 7,A LD (DELCTL),A BIT 0,A ;IF VERERR CALL RDDRV ;SET SPEC'D DRIVE INTO FPB LD (IY+DRIVEO),A OR A ;CLEAR CF LD A,(WILDFL) ;RETURN WILDCARD FLAG RET ;  JR DONAM1 ; DOERR: EQU $ LD A,5 ;SET UP SYNTAX ERROR SCF RET ; DOWILD: EQU $ LD A,'?' ;FILL REMAINING FPB FIELD WNAME PRESET) ; EXIT - Z,NC= OK, NZ OR CF= ERROR [A= ERR CODE] ; FPB(NAME):= DIR(NAME) [INCLUDING ATTRIBUTES] ; RET C ;ERR RETURN LD BC,(BLKTOT) ;SET FILE START PARAMS LD (IY+BLOCKO),C LD (IY+BLOCKO+1),B CALL SETBID PUSH DE ;DIR(N ; ENTRY- IY= FPB PTR (DRIVE, NAME PRESET) ; EXIT - NC AND Z= NORMAL, CF OR NZ= ERROR [A= ERR CODE] ; HL= BLOCK I DEC C ;IF NO ENTRIES THEN RETURN ERR JR Z,NOENT NXTFIL: PUSH IY ;FPB PTR -> HL POP DE INC HL BIT 7,(HL) ;IF DELETED  LD (DIRVAR),BC LD DE,-NAMCNT ;BACK UP DIR PTR TO BEGINNING ; OF ENTRY ADD HL,DE EX DE,HL LD HL,(BLKTOT) ;RETURN Y SEARCH ; DIRSNX: LD HL,(DIRPTR) ;RESTORE SEARCH VARIABLES LD BC,(DIRVAR) JR NXTENT ; ; READ DIRECTORY SUBR ; ENTRADD LENGTH OF FILE TO TOTAL SUBR ; ENTRY- (DE)= LO BYTE OF FILE LENGTH ; (BLKTOT)= TOTAL TO BE ADDED TO ; EXIT -********************************************** ; WRTDIR: EQU $ LD BC,(DIRBUF) ;SET WRITE PTR CALL SETMAP LD BC,0 ;BLK IDION OCCURRED, DIRECTORY WRITE REQ'D ; DELETE: LD A,C RES 7,A ;CLEAR NO WRITE FLAG LD (DELCTL),A CALL DIRSRH ;IF FILE FOUIFY FLAG SET THEN PRINT FILENAME JR Z,DELED EX DE,HL CALL PRNAM1 LD BC,DELTDM CALL EDITOR DELED: POP IY ;RESTORE FPB 0 !%)- "&*. #'+/  $(,0PTR CALL DIRSNX ;CONTINUE SEARCH JR DELNXT ; DELLST: LD A,(DELCTL) ;IF >0 FILES DELETED THEN WRITE DIR OR A ;IF BIT 7 SEABLE BLOCK ; ENTRY: CALL DIRRD ;READ DIR IF NOT CURRENT RET NZ LD HL,(DIRBUF) ;SET PTR LD C,(HL) ;BLOCK TOTAL := START CALL SETBID LD E,(HL) ;IF LENG > AVAIL BLKS THEN ERR INC HL LD D,(HL) EX DE,HL PUSH HL LD E,(IY+LENGO) ;FETCH REQ'D LD C,20H ;' ' PRNT: CALL CONOUT POP HL POP BC DEC C ;COUNT -1 RET Z PUSH BC LD A,C ;IF COUNT = 2 THEN OUTPUT '.'ALL C,SQUISH POP HL LD A,8D ;IF STILL FULL THEN RETURN DIRECTORY ; ERR RET C LD A,(HL) ;ELSE RESTORE ENTRY COUNT > LENGTH LD (HL),C INC HL LD D,(HL) LD (HL),B PUSH BC ;LENGTH LD B,8D ;NULL LAST ENTRY XOR A CLSNUL: INC HL LDELETED THEN GO COUNT JR Z,ADDEMP PUSH BC ;ELSE SET UP FOR MOVE LD BC,10D LDIR POP BC DEC C ;ENT COUNT := ENT COUNT SP),HL PUSH BC LD B,8D CONSLP: LD (HL),0 INC HL DJNZ CONSLP POP BC LD (HL),E INC HL LD (HL),D INC HL POP DEARD(S) USED, A REG. = NUMBER OF ; WILDCARDS ; ;********************************************************* ; ; LD (CMDPTR),HL ;SAVE NEW PTR EX DE,HL PUSH IY POP HL ;FPB PTR LD A,(DE) ;IF CHAR = 0 THEN DONE OR A JR Z,L89 SBC R +1 CP ASTRSK ;IF WILDCARD THEN ENTER '?' JR NZ,LA9 LD (HL),'?' JR LAB ; LA9: LD (HL),A ;ADD CHAR TO FCB FILENAME I '.' LC8: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LE9 INC HL ;IF CHAR <> '*' THEN EXIT CP ASTRSK JR NZ,LD9 LD (HL)T THEN FOUND RET M DELNF: LD A,6 ;RETURN NOT FOUND ERR SCF RET ; DELPRT: POP IY ;RESTORE FPB PTR LD A,4 ;RETURN WRITEBLOCK ID LD B,0 LD (BLKTOT),BC INC HL ;GET ENTRY COUNT LD C,(HL) ENTLP1: INC HL LD B,NAMCNT ;SET ENTRY CHAR COUNT EN BLKS LD D,(IY+LENGO+1) XOR A SBC HL,DE POP HL ;AVAIL. BLKS INC A ;SET Z DEC A LD A,9D RET ; ; ; PRINT FILE CP 2 LD C,2EH PUSH HL CALL Z,CONOUT POP HL JR PRNXTC ; ; ADD FILE TO DIRECTORY SUBR ; ENTRY- IY= FPB PTR (DR INC (HL) ;ADD THIS FILE TO ENTRY COUNT LD BC,10D ;BC := ENTRY SIZE ADLOOP: DEC A ;ENTRIES -1 JR Z,CLOSE2 ;IF NO MORE ENTRD (HL),A DJNZ CLSNUL INC HL ;AVAIL - LENG = NEW AVAIL. EX DE,HL POP BC OR A SBC HL,BC EX DE,HL LD (HL),E INC H-1 INC B ;COUNT := COUNT +1 JR SQNEXT ; ADDEMP: PUSH DE ;DEST PTR LD DE,0 PUSH DE EMLOOP: BIT 7,(HL) ;IF NOT DELETED  EX DE,HL INC B ;COUNT := COUNT -1 INC C ;IF ENT COUNT > 0 THEN LOOP DEC C JR NZ,SQNEXT POP HL ;ELSE SET NEW ENTRY C TEMPORARY CONSTANTS, REASSIGN WHEN LINKED TO MAIN PGM ; DFLTDK: EQU 0004H ;DEFAULT DISK LOCATION ; ; CONSTANTS ; ZROS'@' ;MAKE 'A'-'P' = 1-15 FOR DRIVE # LD B,A INC DE ;IF NEXT CHAR = ':' THEN MUST BE DRIVE LD A,(DE) CP ':' JR Z,L90 NC DE LAB: DJNZ L98 ;IF NOT DONE THEN LOOP LAF: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LC0 INC DE ;SKIP OVER EXTRA CHA,'?' JR LDB ; LD9: LD (HL),A ;ADD CHAR TO FCB INC DE LDB: DJNZ LC8 LDF: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LF0 PROTECT ERR SCF RET ; ; ENTRY COMPUTES AVAILABLE SPACE ON CURRENT DRIVE TAPE ; ENTRY- IY= FPB PTR (DRIVE, LENG PRESETLP: INC HL DJNZ ENTLP ;SKIP NAME DEC C JR Z,ENTDN ;IF LAST ENTRY THEN DONE EX DE,HL CALL ADDBLK ;ADD THIS FILE LENGTHNAME FROM FPB SUBR ; ENTRY- IY= FPB PTR (NAME PRESET) ; PRNAME: EQU $ PUSH IY POP HL PRNAM1: LD C,8D ;SET CHAR COUNT IVE, NAME, LENG PRESET) ; EXIT - CF OR NZ= ERROR [A= ERR CODE] ; CLOSE: CALL DELETE ;DELETE POSSIBLE EXISTING FILE RET NZIES THEN EXIT ADD HL,BC ;NEXT ENTRY JR ADLOOP ; CLOSE2: INC HL ;POINT TO 1ST AVAIL ENTRY PUSH IY ;DIR(NAME) := FPB(NAME)L LD (HL),D JP WRTDIR ; ; SQUISH DIRECTORY SUBR PACKS DIRECTORY ; SQUISH: EQU $ LD HL,(DIRBUF) ;FETCH ENTRY COUNT THEN FINISH JR NZ,FINISH LD DE,8D ;ADD THIS FILE LENGTH TO TOTAL ADD HL,DE LD E,(HL) INC HL LD D,(HL) INC HL EX OUNT LD A,B LD (HL),A CP 102D ;IF STILL FULL THEN RETURN CF CCF RET ; ; CP/M FILE CONTROL BLOCK FORMATTER ; ENTIZ: EQU 4 ASTRSK: EQU 2AH ;'*' ACOMMA: EQU 2CH ;',' APEROD: EQU 2EH ;'.' ; NAMCNT: EQU 8D ;FILENAME CHAR CNT TYPCNT: EQU 3DEC DE ;ELSE BACK UP & USE DEFAULT DRIVE L89: LD A,(DFLTDK) LD (HL),A ;FCB(DISK) := DRIVE # JR L96 ; L90: LD A,B ;USE SPERS TO '.' JR LAF ; LB9: INC HL ;FILL REMAINDER OF FCB WITH SPACES LD (HL),ASPACE DJNZ LB9 LC0: LD B,TYPCNT ;COUNT := TY INC DE ;WASTE CHARS JR LDF ; LE9: INC HL ;FILL REMAINING TYPE WITH SPACES LD (HL),ASPACE DJNZ LE9 LF0: LD B,ZROSIZ T) ; EXIT - NZ OR CF= ERROR [A= ERR CODE] ; HL= BLOCKS AVAILABLE ON TAPE ; FPB(BLOCK):=SETBID:= 1ST AVAIL TO TOTAL EX DE,HL JR ENTLP1 ; ENTDN: LD BC,(BLKTOT) ;SET FPB(BLOCK) & BLOCK ID LD (IY+BLOCKO),C LD (IY+BLOCKO+1),B  PUSH BC PRNXTC: LD A,(HL) ;GET CHAR INC HL PUSH HL RES 7,A OR A ;IF CHAR = 0 THEN CHAR := SPACE LD C,A JR NZ,PRNT CLOS1: LD HL,(DIRBUF) ;ELSE SET PTR INC HL ;IF ENTRIES >= MAX THEN TRY PACKING DIR LD A,(HL) CP 102D CCF PUSH HL C POP DE EX DE,HL LD BC,8D LDIR LD C,(IY+8D) ;SET FILE LENGTH LD B,(IY+9D) EX DE,HL LD E,(HL) ;REMAINING BLKS <-INC HL PUSH HL LD C,(HL) INC HL ;SET DESTINATION FOR PACK PUSH HL POP DE LD B,0 ;COUNT := 0 SQNEXT: BIT 7,(HL) ;IF (SP),HL ADD HL,DE EX (SP),HL DEC C ;IF ENT COUNT -1 > 0 THEN REPEAT JR NZ,EMLOOP FINISH: POP DE ;BUILD NEW ENTRY EX (RY- (CMDPTR) = ASCII STRING PTR OF FILE ; HL = FCB TO FORMAT ; EXIT - ZF = NO WILDCARDS USED ; NZ = WILDC ;FILE EXTENSION CHAR CNT ; FORMAT: PUSH HL ;SAVE FPB PTR IN IY POP IY LD HL,(CMDPTR) CALL SKIPO1 ;SKIP LEADING SPACES CIFIED DISK LD (HL),B INC DE ;SKIP OVER ':' L96: LD B,NAMCNT ;B := MAX CHARS L98: CALL RSVP JR Z,LB9 INC HL ;PTR := PTPE CHAR COUNT CP APEROD ;IF RESERVED CHAR NOT '.' THEN FILL ; WITH SPACES JR NZ,LE9 INC DE ;GET NEXT CHAR AFTER ;ZERO EXTENT, S1, S2, RECORD COUNT LF2: INC HL LD (HL),ZERO DJNZ LF2 LD (CMDPTR),DE PUSH IY POP HL ;COUNT WILDCARDS0 !%)- "&*. #'+/  $(,0 LD BC,NAMCNT+TYPCNT L01: INC HL LD A,(HL) CP '?' JR NZ,L09 INC B L09: DEC C JR NZ,L01 LD A,B OR A RET ; ;: DB '=',5FH,APEROD,':',';',ACOMMA,'<','>' TABCNT: EQU $-RSVPT ; ; CP/M SYSTEM CALLS ; SETDMA: LD C,26D JP BDOS ; WRTN MSG CALL EDITOR LD HL,DEFBFR ;IF COMMAND COUNT = 0 THEN ERR LD A,(HL) RES 7,A ;INSURE <= 128D BYTES OR A JR Z,SYNED DRIVE THEN DEST = DISK JR C,SYNERR CP 16D JR NC,SYNERR INC A ;NOT DEFAULT LD (OUTFCB),A SRCSEL: LD C,'=' ;SEARCH FO UP PTRS LD HL,NAMCNT ADD HL,DE LD A,(HL) LD (INFPB+LENGO+1),A INC HL LD A,(HL) LD (INFPB+LENGO+2),A EX DE,HL ;OKP1: INC HL INC DE DJNZ MOVLP LD B,2 ;NOW MOVE EXTENSION LD DE,OUTFCB+9D MOVLP1: LD A,(HL) RES 7,A OR A JR Z,SKP2R A SBC HL,DE JR NC,CONT2 ; OVER: LD DE,(BFRSIZ) LD E,D LD D,0 DEC A ;FINISHED FLAG := FALSE CONT2: LD (FINIS),A ,DSKFUL ;IF ERR THEN EXIT LD DE,SECSIZ ;WRTPTR := WRTPTR + SECTOR SIZE LD HL,(WRTPTR) ADD HL,DE LD (WRTPTR),HL LD HL,(: LD DE,OUTFCB CALL CLOS INC A JR NZ,CONT3 LD BC,CLOSEM ;OUTPUT CAN'T CLOSE MSG CALL EDITOR JP 0 ; CONT3: LD IY,IN,CR,0 DSKFM: DB 'Disk Full!',CR,0 NOSPCM: DB ' Directory Full!',CR,0 DELTDM: DB ' Deleted',CR,0 ; ; PHI FILE PARAMETER BLZ DF 0,STKSIZ ; STACK: EQU $ BFR1K: EQU $ ; BUFFER: EQU BFR1K+DIRSIZ ; END  RESERVED CHAR TEST SUBR ; ENTRY- (DE) = CHAR TO TEST ; EXIT - ZF = FOUND ; RSVP: LD A,(DE) ;IF CHAR <= ' ' THEN RETURSEC: LD C,21D JP BDOS ; RDSEC: LD C,20D JP BDOS ; OPEN: LD C,15D JP BDOS ; DELET: LD C,19D JP BDOS ; MAKE: LD C,RR LD C,A ;MOVE CMD LINE TO CMD BUFFER LD B,0 LD DE,CMDBFR INC HL ;SKIP COUNT LDIR XOR A ;LAST CHAR := 0 LD (DE),AR SOURCE CALL SERCH1 JR Z,SYNERR INC HL ;BYPASS '=' NXTSRC: CALL SKIPO1 JR Z,SYNERR LD A,(HL) ;IF DRIVE NOT '0' THRU UTPUT FILENAME PUSH HL CALL CRLF POP HL PUSH HL CALL PRNAM1 LD B,11D ;FILL OUTPUT FCB WITH ' ' LD HL,OUTFCB+1 LD LD (DE),A SKP2: INC HL INC DE DJNZ MOVLP1 LD DE,OUTFCB ;DELETE ANY EXISTING FILE CALL DELET LD DE,OUTFCB ;NOW MAKELD (BFRCNT),DE PUSH DE ;SET UP FOR READ POP BC CALL SETCNT LD BC,(INFPB+BLOCKO+1) CALL SETBID LD BC,BUFFER CALL SEWRTCNT) ;WRTCNT := WRTCNT - 1 DEC HL LD (WRTCNT),HL LD A,L OR H JR Z,DONE1 JR NXTSEC ; DONE1: LD A,(FINIS) ;IF FINFPB+1 ;SET UP FOR NEXT FILE CALL DIRSNX JP NC,NXFILE LD HL,(CMDPTR) ;IF NO ',' THEN EXIT LD C,ACOMMA CALL SERCH1 JP OCKS ; INFPB: DF 0,32D OUTFPB: DF 0,32D ; ; CP/M FILE CONTROL BLOCKS ; INFCB: DF 0,32D OUTFCB: DF 0,32D ; ; VARIABN Z RSVP1: CP ASPACE+1 JR NC,RSVP2 XOR A RET ; RSVP2: PUSH BC PUSH HL LD B,TABCNT ;B := ENTRY COUNT LD HL,RSVPT 22D JP BDOS ; CLOS: LD C,16D JP BDOS ; ; START OF MAIN PGM ; PSTART: LD HL,(BDOS+1) ;GET TOP OF BUFFER DEC HL LD LD HL,CMDBFR ;INITIALIZE CALL SKIPO1 ;SKIP LEADING SPACES JR Z,SYNERR LD (CMDPTR),HL LD A,(HL) ;SELECT FORMATTER BY D'3' THEN ERR SUB '0' JR C,SYNERR CP 4 JR NC,SYNERR LD (CMDPTR),HL LD IY,INFPB+1 CALL DONAM1 LD C,A JP C,SYSERR A,ASPACE INITFC: LD (HL),A INC HL DJNZ INITFC LD B,17H ;RE-INITIALIZE FCB ZFCB: LD (HL),0 INC HL DJNZ ZFCB POP HL NEW FILE CALL MAKE INC A JR NZ,CONT1 LD BC,NOSPCM ;IF ERR THEN DIR FULL CALL EDITOR JP 0 ; CONT1: EQU $ NXTSEG: TMAP CALL READF LD C,A ;IF ERR THEN ERR JP NZ,SYSERR LD HL,BUFFER ;SET WRITE PTRS LD (WRTPTR),HL LD HL,(BFRCNT) ADISHED THEN GO CLOSE OR A JR Z,CLOSE1 LD HL,(INFPB+LENGO+1) ;ELSE ; LENGTH := LENGTH - BUFFER SIZE LD DE,(BFRSIZ) Z,0 JP NXTSRC ; DSKFUL: LD BC,DSKFM ;OUTPUT DISK FULL MSG CALL EDITOR JP 0 ; ; MESSAGES ; SIGNON: DB CR,'PHIMON FiLES ; DIRIN: DB -1 DELCTL: DB 0 DIRBUF: DW BFR1K DIRPTR: DW BFR1K BLKTOT: DW 0 DIRVAR: DW 0 WILDFL: DB 0 TOGGLE: DB 2 RSVPL: CP (HL) JR Z,RSVPX ;IF FOUND THEN EXIT INC HL DJNZ RSVPL INC B ;RETURN NZ RSVPX: POP HL POP BC RET ; RSVPT (MEMTOP),HL LD DE,BUFFER ;COMPUTE BUFFER SIZE OR A SBC HL,DE LD (BFRSIZ),HL LD SP,STACK LD BC,SIGNON ;OUTPUT SIGN-ORIVE # SUB '0' JR C,SYNERR CP 4 JR NC,DSK SYNERR: LD C,5 ;OUTPUT SYNTAX ERROR JP SYSERR ; DSK: SUB 'A'-'0' ;IF VALI CALL DIRSRH ;LOOK UP IN DIRECTORY LD C,A ;IF ERR THEN ERR JP C,SYSERR JP NZ,SYSERR NXFILE: LD (INFPB+BLOCKO+1),HL ;SET LD DE,OUTFCB+1 LD B,6 MOVLP: LD A,(HL) ;IF CHAR = 0 THEN NO LOAD RES 7,A ;CLEAR ATTRIB OR A JR Z,SKP1 LD (DE),A SLD HL,(BFRSIZ) ;IF LENGTH > BUFFER SIZE THEN ; SEGMENTIZE LD L,H ;CONVERT TO PAGES LD H,0 LD DE,(INFPB+LENGO+1) XOD HL,HL ;SECTORS := PAGES * 2 LD (WRTCNT),HL NXTSEC: LD DE,(WRTPTR) CALL SETDMA LD DE,OUTFCB CALL WRTSEC OR A JR NZLD E,D LD D,0 SBC HL,DE LD (INFPB+LENGO+1),HL ;SET UP FOR BID CALL RDBID LD (INFPB+BLOCKO+1),HL JP NXTSEG ; CLOSE1le Transfer Utility',83H DB 'Ver 1.0',CR DB '(c) 1981 GRH Electronics, Cupertino, CA',CR,0 CLOSEM: DB 'Cannot Close File!'FINIS: DB 0 MEMTOP: DW 0 BFRSIZ: DW 0 WRTPTR: DW BUFFER WRTCNT: DW 0 BFRCNT: DW 0 CMDPTR: DW CMDBFR ; CMDBFR: DF 0,SECSI0 !%)- "&*. #'+/  $(,0 TITLE CP/M SYSTEM GENERATOR UTILITY 28 FEB 81 11:20 ;************************************************************* ; ; C**** ; ; CP/M SYSTEM CONSTANTS ; ;************************ ; BDOS: EQU 0005H TPA: EQU 0100H ; CI: EQU 1 CO: EQU 2 OPU 0DH ASPACE: EQU 20H ; FORM ;************************************************************* ; ORG TPA ; JP START ; RD VALUE ; AX128: LD L,A LD H,ZERO ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL RETL) ;GET CHAR OR A ;IF CHAR = 0 THEN EXIT RET Z PUSH HL CALL CONOUT POP HL INC HL JR EDITOR ; ; SELECT DISK ; D DE,RDSECO ADD HL,DE JP (HL) ; ; WRITE SECTOR ; WRSEC: LD HL,(BIOSNT) LD DE,WRSECO ADD HL,DE JP (HL) ; ; BDOSHL,SECTBL ;SET SECTOR TABLE PTR LD B,(HL) ADD HL,DE LD C,(HL) PUSH BC CALL SECSL POP BC ;COMPUTE DELTA LD A,C SU;RETRIES := RETRIES +1 LD (RETRYS),A LD A,(OPNFLG) ;IF FLAG = 0 THEN READ OR A JR Z,RD1 CALL WRSEC ;ELSE WRITE JR ER;ELSE OUTPUT NO SOURCE MSG CALL ED1 JP EXIT ; OPENOK: XOR A LD (FCBCR),A ;READ FILE RECORD # 0 LD C,16D WSTLP: PUSH BRCE INCOMPLETE MSG CALL ED1 JP EXIT ; GETSRC: LD HL,SRCDKM ;OUTPUT SOURCE DRV MSG CALL ED1 CALL CONIN CP CR ;IF RETULECT READ OPERATION CALL DOIT LD HL,FNCCM ;OUTPUT FUNCTION COMPLETE MSG CALL EDITOR ; GETDST: LD HL,DSTDKM ;OUTPUT DEST LD HL,OPNFLG ;SET WRITE OPERATION LD (HL),1 CALL DOIT LD HL,FNCCM ;OUTPUT FUNCTION COMPLETE MSG CALL EDITOR JR GETDST P/M SYSGEN UTILITY FOR JADE FORMAT DISKS ; (c) 1981 GRH Electronics, Cupertino, CA ; By Girvin Herr ; ;***************EN: EQU 15D READ: EQU 20D ; DEFFCB: EQU 005CH ;DEFAULT FCB ADDR FCBCR: EQU DEFFCB+32D ; DKSELO: EQU 18H TRKSLO: EQU 1BH  DB 'Copyright (c) 1981, GRH Electronics' ; LASTRK: DB 1 LSTSEC: DB 48D ; ; SECTOR TABLE ; SECTBL: EQU $ SECX: DB 1,2,3 ; ; CONSOLE INPUT ; CONIN: LD C,CI ;GET CHAR CALL BDOS CP 'a' ;IF LC THEN MAKE UC RET C CP '{' RET NC AND 5FH DKSEL: LD C,A LD HL,(BIOSNT) ;GET BASE ADDR LD DE,DKSELO ;ADD OFFSET ADD HL,DE JP (HL) ; ; SET TRACK ; TRKSL: LD H READ FILE SECTOR ; READF: LD C,READ JP BDOS ; ; BDOS OPEN FILE ; OPENF: LD C,OPEN JP BDOS ; ; DO SYSTEM TRACK ; B B CALL AX128 EX DE,HL LD HL,(BFRPTR) ;COMPUT PTR ADD HL,DE LD B,H LD C,L CALL ADRSL XOR A LD (RETRYS),A ;CLERCHK ; RD1: CALL RDSEC ERRCHK: OR A ;IF NO ERRORS THEN CONTINUE JR Z,NXTSEC JR RETRY ; ; MAIN PGM ; START: LD SP,STAC LD DE,DEFFCB CALL READF POP BC OR A ;IF EOF THEN INCOMPLETE JR NZ,INCOMP DEC C ;DO UNTIL 16 DONE JR NZ,WSTLP LRN THEN NO READ JR Z,GETDST SUB 'A' ;IF NOT 'A'-'C' THEN RESTART CP 4 JR C,SET1 CALL INVDRV JR GETSRC ; SET1: ADD DRV MSG CALL ED1 CALL CONIN ;IF INPUT = RETURN THEN REBOOT CP CR JR Z,EXIT SUB 'A' ;IF NOT 'A'-'C' THEN RESTART CP 4 ; EXIT: LD A,ZERO CALL DKSEL ;RESELECT DRV A CALL CRLF JP 0 ; INVDRV: LD HL,INVDKM ;OUTPUT INVALID DRV MSG JP ED1 ;********************************************** ; ; This utility generates CP/M system on track 1 in Double ; Density. ; ;SECSLO: EQU 1EH ADRSLO: EQU 21H RDSECO: EQU 24H WRSECO: EQU 27H ; SYBUFR: EQU 0900H ; ZERO: EQU 0 ; BIOSNT: EQU 0001H ;,4,5,6,7,8D,9D,10D,11D,12D,13D,14D,15D,16D DB 17D,18D,19D,20D,21D,22D,23D,24D,25D,26D,27D,28D DB 29D,30D,31D,32D,33D,34D,35D RET ; ; CONSOLE OUT ; CONOUT: LD E,A LD C,CO JP BDOS ; ; CR - LF ; CRLF: LD A,CR CALL CONOUT LD A,LF JR CL,(BIOSNT) LD DE,TRKSLO ADD HL,DE JP (HL) ; ; SET SECTOR ; SECSL: LD HL,(BIOSNT) LD DE,SECSLO ADD HL,DE JP (HL) DOIT: LD HL,SYBUFR ;SET PTR LD (BFRPTR),HL DOTRK: LD C,1 ;SET TRACK CALL TRKSL LD A,-1 ;SET UP SECTOR CNT LD (SECTORAR RETRIES RETRY: LD A,(RETRYS) ;IF RETRIES <10 THEN GO TO IT CP 10D JR C,RETOK LD HL,ERRM ;ELSE OUTPUT ERROR MSG CALL CK LD HL,SGNON ;OUTPUT SIGN-ON MSG CALL EDITOR LD A,(DEFFCB+1) ;IF NO FILENAME SPEC'D THEN NO ; OPEN CP ASPACE JRD HL,SYBUFR ;SET DMA ADDR TO BUFFER RDNXTF: PUSH HL LD B,H LD C,L CALL ADRSL LD DE,DEFFCB ;READ NEXT CALL READF POP'A' ;RESTORE DRIVE & PUT INTO MSG LD (SRCDK),A SUB 'A' ;SELECT DRIVE CALL DKSEL CALL CRLF LD HL,SRCDKP ;OUTPUT SOURCE  JR C,DESTOK CALL INVDRV JR GETDST ; DESTOK: ADD 'A' ;PUT DRV INTO MSG LD (DSTDK),A SUB 'A' ;SET DRIVE CALL DKSEL  ; MESSAGES ; SGNON: DB 'Jade DD SYSGEN Ver 1.0',CR,LF DB '(c) 1981 GRH Electronics, Cupertino, CA',0 ; SRCDKM: DB 'So************************************************************* FORM ;*********************************************************LOCATION OF BIOS START ADDRESS ;********************** ; ; ASCII CONSTANTS ; ;********************* LF: EQU 0AH CR: EQ,36D,37D,38D,39D,40D DB 41D,42D,43D,44D,45D,46D,47D,48D ; DS 0175H-$ ; ; AX128 MULTIPLIES VALUE IN A BY 128D & FORMS WOONOUT ; ; ED1 DOES CR-LF BEFORE EDITOR ; ED1: PUSH HL CALL CRLF POP HL ; ; EDITOR OUTPUTS STRING ; EDITOR: LD A,(H ; ; SET ADDR ; ADRSL: LD HL,(BIOSNT) LD DE,ADRSLO ADD HL,DE JP (HL) ; ; READ SECTOR ; RDSEC: LD HL,(BIOSNT) L),A NXTSEC: LD A,(LSTSEC) ;IF LAST SECTOR THEN RETURN LD HL,SECTOR INC (HL) CP (HL) RET Z LD E,(HL) LD D,ZERO LD EDITOR CALL CONIN ;IF INPUT NOT RETURN THEN EXIT CP CR JP NZ,EXIT CALL CRLF ;ELSE CONTINUE JR NXTSEC ; RETOK: INC A  Z,GETSRC LD DE,DEFFCB ;ELSE OPEN FILE CALL OPENF INC A ;IF NO ERR THEN SKIP 1ST 16 SECTORS JR NZ,OPENOK LD HL,NOSRCM  HL OR A JR NZ,GETDST LD DE,128D ;BUFR PTR := BUFR PTR * 128D ADD HL,DE JR RDNXTF ; INCOMP: LD HL,SCINCM ;OUTPUT SOUDRV MSG CALL EDITOR CALL CONIN ;IF INPUT <> RETURN THEN RE-BOOT CP CR JR NZ,EXIT CALL CRLF XOR A LD (OPNFLG),A ;SE LD HL,DSTDKP ;OUTPUT DEST PROMPT CALL ED1 CALL CONIN CP CR ;IF INPUT NOT RETURN THEN RE-BOOT JR NZ,EXIT CALL CRLF urce drive name (or RETURN to skip)',0 ; SRCDKP: DB 'Source on ' SRCDK: DB 9D DB ' - Then type RETURN',0 ; DSTDKM: DB 'De0 !%)- "&*. #'+/  $(,0stination drive name (or RETURN to reboot)' DB 0 DSTDKP: DB 'Destination on ' DSTDK: DB 9D DB ' - Then type RETURN',0 ;  RETRYS: DB 0 ;RD/WR RETRIES COUNT ; DS 32D STACK: EQU $ ; END SAGES RDERRM: DB CR,LF,'Disk Read Error$' WRERRM: DB CR,LF,'Disk Write Error, Probably Full!$' DELMSG: DB CR,LF,'File Exist Hex Record Type!$' HXEMTM: DB CR,LF,'Hex File Empty!$' HELPM: DB CR,LF,'HElp' DB CR,LF,'REad addr d:file (MUST BE ''HEX''W READC DB 2,'FI' ;FILL DW FILLC DB 2,'MO' ;MOVE DW MOVEC DB 2,'DI' ;DISPLAY DW DISPC DB 2,'SU' ;SUBSTITUTPARAM3: DW 0 ; MEMTOP: DW 0 ;TOP OF AVAILABLE MEMORY PTR RDPTR: DW 0 ;FILE READ PTR DISTRT: DW 0 ;DISPLAY COMMAND LASTORAGE REPT 33 LIST OFF DB 0 LIST ON ENDM DS STKSIZ STACK: EQU $ IF ($ AND 000FH) = 0 PGMEND: EQU $ ELSE PELEASE ; X.1 - ADD LOOK-AHEAD FOR DD,FD OPS AND ED OPS VALIDITY. ; IF INVALID, OUTPUTS DB OP BEFORE ESCAPE. ; X.2 - CORRECTED VERS EQU '10' ; ;************************************************************* ; ; ALTERNATE REGISTER USAGE: ; C = BYTESQU 00100000B ;OUTPUT 'DB's SWITCH MASK LISTSW EQU 10000000B ;LISTING FORM OF OUTPUT MASK STEXTOP EQU 00000001B ;EXTENDED OP ERRM: DB 'PERMANENT ERROR, Type RETURN to ignore',0 ; FNCCM: DB 'Function complete ',0 ; INVDKM: DB 'INVALID DRIVE NAME (Uses, Delete?..(Y/N) - $' CMDERM: SYNERM: DB CR,LF,'*** Syntax Error ***...Type ''HElp'' For List$' FNFM: DB CR,LF,'File Not FouFORMAT)' DB CR,LF,'SAve first, last d:file (WILL BE ''HEX'' FORMAT)' DB CR,LF,'FIll first, last, value' DB CR,LF,'MOve firE DW SUBSC DB 2,'SA' ;SAVE DW SAVEC DB 2,'HE' ;HELP DW HELPC DB 2,'?',0 ; " DW HELPC DB 2,'H',0 ; " DWT START PTR DISEND: DW 0 ;DISPLAY COMMAND LAST END PTR DISTMP: DW 0 ;DISPLAY COMMAND TEMP STORAGE TEMP: DW 0 ;TEMPORARY GMEND EQU ($ AND 0FFF0H) + 0100H ENDIF END  BUG IN CLEAN: WHICH WAS MASKED BEFORE. ; ADD TRAP IN CLEAN WHEN BYTES USED EXCEEDS BYTES FETCHED ; OUTPUTS ERROR MESSAGE & PR USED FROM FILE ; B = STATUS: BIT USE ; 0 EXTENDED OP ; 1 IX OP ; 2 IY OP ; 3 ESCAPE USED FLAG ; 4 JP () OP ; BIT STIXOP EQU 00000010B ;IX OP BIT STIYOP EQU 00000100B ;IY OP BIT STESC EQU 00001000B ;ESCAPE BIT STJPOP EQU 00010000B ;JP A,B,C or D)',0 ; NOSRCM: DB 'No source file on disk',0 ; SCINCM: DB 'Source file incomplete',0 ; ; VARIABLES ; TRACK: nd$' BOUNDM: DB CR,LF,'Value Out of Bounds$' MEMERM: DB CR,LF,'Memory Error$' HXERM: DB CR,LF,'Hex File Error$' CVERM: DB CRst, last, dest' DB CR,LF,'DIsplay <, last>' DB CR,LF,'SUbstitute addr' DB CR,LF,'CTRL-C To Exit to CP/M' DB CR,LF HELPC DB 0 ;TABLE TERMINATOR SUBTTL VARIABLES CMDPTR: DW CMDBFR CMDBFR: EQU $ ;COMMAND INPUT TEXT BUFFER REPTSTORAGE GETFLG: DB 0 ;FLAG FOR GETNUM BFRCNT: DB 0 ;FILE READ COMMAND BUFFER COUNT DBPTR: DW DEFBFR BFRPTR: DW 0 ;HEX F****************************************************** ; ; This subroutine performs a disassembly to an output ; file from aOGRAM COUNTER VALUE AS AN AID ; TO TRACK DOWN WHERE DISZ WAS AT. ; X.3 - ADD ESCAPE FLAG TO CONTROL CLEAN PARAMETER AT DISRTN. 5 LD SP,HL OP ; 6 CLEAN HOLD ; 7 ED OP ; SUBTTL CONSTANT DEFINITIONS BDOS EQU 0005H ;CP/M ENTRY CTRLI EQU 9 LF E () BIT STLDOP EQU 00100000B ;LD SP,HL BIT STCHLD EQU 01000000B ;CLEAN HOLD BIT STEDOP EQU 10000000B ;ED OP BIT EXTMSK EQU SDB 0FFH ;TRACK # SECTOR: DB 0FFH ;SECTOR # OPNFLG: DB 0 ;OPERATION FLAG (0=READ, 1=WRITE) BFRPTR: DW SYBUFR ;RD/WR BUFFER PTR,LF,'Hex Conversion Error$' HXADRM: DB CR,LF,'Hex Load Address Lower Than 1st Record Load Address!$' HXTYPM: DB CR,LF,'Illegal,'$' SUBTTL COMMAND TABLE ;------------------ ; ; COMMAND TABLE ; ;------------------ CMDTBL: DB 2,'RE' ;READ D 130 LIST OFF DB 0 LIST ON ENDM CBFRSZ: EQU $-CMDBFR-2 ; ; INPUT PARAMETER STORAGE ; PARAM1: DW 0 PARAM2: DW 0 ILE READ PTR HEXBASE: DW 0 ;HEX FILE BASE LOAD ADDR HEXPTR: DW 0 ;HEX FILE READ PTR FCB: EQU $ ;FILE CONTROL BLOCK Sn input file of one line of code. ; ;************************************************************ ; REVISIONS: ; X.0 - PRE-R ; NEEDED FOR ED OPS. (NOT ALL USE ESCAPE:). ; 1.0 - 21 FEB 83 ; RELEASE. FIX NOT PRINTING 'H' AFTER DISPLACEMENT VALUE ; ;QU 0AH CR EQU 0DH HEXSW EQU 00000100B ;HEX OUTPUT SWITCH MASK ASCIISW EQU 00010000B ;ASCII EQUIVALENT SWITCH MASK DATASW ETEXTOP OR STIXOP OR STIYOP OR STESC IXMSK EQU STEXTOP OR STIXOP IYMSK EQU STEXTOP OR STIYOP SUBTTL EXTERNALS ;***********0 !%)- "&*. #'+/  $(,0/**************************************************************************** Set time of day command. Supports the QT= day of month {1,2,..31} yy= year {00,01,..99} hh= hours {00,01,..23} mm= minutes {00,01,..59} ss= seconds {00,01,.********************************************************* Revision History: 1.0 - 27 may 83 grh Release 1.1 - 10 jul nitor functions. Use printf() instead of local functions for ease of programming. 2.0 11-20-91 grh Modify for monitor ******************************/ struct { BYTE seconds, /* 0..59 */ minutes, /* 0..59 */ hours; /* 0..23 */ BER", "NOVEMBER","DECEMBER"}; /* Other variables */ BYTE this_bnk; int error; WORD get_offset(), temp, ccpui.AF = MF_GBNK << 8; farcall( (WORD) MR_FUN, 0, &cpui, &cpuo); this_bnk = cpuo.AF >> 8; /* Get current time */  printf("Err: %s", tptr); break; } else time_array.week = temp; } /*******1; /*** set global error flag ***/ printf("Err: %s", tptr); break; } temp = atoi( (tp= 0) ) tptr = argv[++cnt]; else tptr++; time_array.year = atoi(tptr); } /******* P while ( (*tptr != 0) && (*tptr != ':') ) tptr++; if ( *tptr == ':') ++tptr; if ( *tptr != 0) {s("\ >> (24 Hour)"); break; } } /**** If no  Computer Systems Clock - Calendar board. ***************************************************************************** S.59} (optional, allways set to 00) If DAY, DATE and TIME fields are ommitted then only the current time is displayed, els84 grh Fix bug in time array data processing causing 24 hour bit to be cleared. Fix bug in get_txt() which returned garbV2.00 calls. */ #define version "2.0" /****************************************************************************/ #inYTE week; /* 0..6 */ BYTE day, /* 0..31 */ month, /* 1..12 */ year; /* 0..99 */ } time_array; #define nnt; char *get_txt(), *tptr; struct regs cpui, /* CPU input register array */ cpuo; /* CPU output register array  get_clock(); /* If args given then process changes */ if (argc > 1){ error = 0; for (cnt = 1, tptr = ar Process date input */ else if (strncmp("DATE=", tptr, 5) == 0) { temp = get_offset( &tptr[5], month_tabltr = argv[++cnt]) ); /*** get date ***/ if ( (temp < 1) || (temp > 31) ) { error = -1; /*** set global errocess time input */ else if ( strncmp("TIME=", tptr, 5) == 0){ tptr = &tptr[5]; if ( *tptr  time_array.minutes = atoi(tptr); while ( (*tptr != 0) && (*tptr != ':') ) tptr++; errors so far then set the time */ if (error == FALSE){ puts("\nPress any key to set time.\n"); bdos(yntax: TOD (DAY=ddd) (DATE=mmm d,yy) (TIME=hh:mm:ss) where ddd= day {SUNday,MONday,TUEsday,WEDnesday,THUrsday, FRIde the clock information specified by the field is changed. All fields are optional and any unspecified fields are not alteredage when a negative integer was passed as the offset. 1.2 - 28 Oct 84 grh Fix bug that did a modulo 10 on the month vaclude "stdio.h" #include ctype.h #include io.h #include farcall.h #include m5zf200.h /*********************************days 7 char *day_table[ndays] = { "SUNDAY","MONDAY","TUESDAY","WEDNESDAY", "THURSDAY","FRIDAY","SATURDAY"}; #define nmon*/ /**************************************************************************** MAIN Program **********************gv[cnt]; cnt < argc; cnt++) { /******* Process day input */ if (strncmp("DAY=", tptr, 4) == 0) { temp e, nmonths); if (temp > 11) { error = -1; /*** set global error flag ***/ printf("Err: %s", tptrror flag ***/ printf("Err: %s", tptr); break; } time_array.day = temp; /********** f== 0) { error = -1; /*** set global error flag ***/ printf("Err: %s", tptr); break; }  if ( *tptr == ':') ++tptr; if ( *tptr != 0) time_array.seconds = atoi(tptr); } 1,0); /*** wait for char ***/ set_clock(); } } /* In all cases, display the time */ printf("ay,SATurday} mmm= month {JANuary,FEBruary,MARch,APRil,MAY,JUNe,JULy, AUGust,SEPtember,OCTober,NOVember,DECember} d. Spaces and delimiters are only allowed as shown in the example. TOD ? Displays the help prompt. ********************lue. This caused an error when october (0x10 & 15 = 0 [- 1 = -1]) occurred. 1.3 12-7-90 grh Revise code to call the mo********************************* Time array is used to communicate with the primitives *************************************ths 12 char *month_table[nmonths] = {"JANUARY","FEBRUARY","MARCH","APRIL","MAY", "JUNE","JULY","AUGUST","SEPTEMBER","OCTOB******************************************************/ main(argc, argv) int argc; char *argv[];{ /* Get bank data */ = get_offset( &tptr[4], day_table, ndays); if (temp > 6) { error = -1; /*** set global error flag ***/ ); break; } time_array.month = (temp + 1); if (cnt >= argc) { error = -ind any ',' */ while ( (*tptr != 0) && (*tptr != ',') ) tptr++; if ( (*tptr == 0) || (*(tptr + 1) = time_array.hours = atoi(tptr); time_array.minutes = time_array.seconds = 0; /** default **/  } /* If arg error then display format */ else { error = -1; /*** set global error flag ***/ put\n%s %s %2d,19%2d %2d:%2d:%2d\n\n", get_txt(time_array.week & 7, day_table, ndays), get_txt(time_array.month - 1, month0 !%)- "&*. #'+/  $(,0_table, nmonths), time_array.day, time_array.year, time_array.hours, time_array.minutes, time_arra; for (cnt = 0; cnt < size; cnt++){ if (strncmp(sptr, cptr[cnt], 3) == 0) return cnt; } return 300;  } /**************************************************************************** Get clock data *******************AF >> 8; time_array.month = cpuo.BC >> 8; time_array.year = cpuo.BC & 0xff; time_array.week = cpuo.HL & 0xff; O UUL!*p+q*)O2'!,p+q*+O2'O2'O!.p+q*-LRRLR\L!gr+s+p+q!h6>fr*d*f!is*d́"dPY! "f>!h#~Haͫo!h6:i0O͐!mr+s+p+q*l/**************************************************************************** Set time of day command. Supports the QT d= day of month {1,2,..31} xx= year {00,01,..99} hh= hours {00,01,..23} mm= minutes {00,01,..59} ss= seconds {00,************************ Revisions: 1.0 - 27 may 83 grh Release 1.1 - 10 jul 84 grh Fix bug in time array data pr*****************/ /* #include "basedef.h" */ #define FALSE 0 /*********************************************************y.seconds ); exit(0); } /**************************************************************************** com } /**************************************************************************** get text ptr from array function **********************************************************/ get_clock() { cpui.AF = MF_GTIM << 8; farcall( (WORD) MR_} /**************************************************************************** Set clock data ********************R/, Space: Invalid File Indicator** Too Many Files **File Not Found Size Recs Bytes Ext Acc65536 set to R/O InvalidR" O!/q*/& L!1p+q*0#L~*##N!ͽ͞"T!Vq*VMͳ!Xp+q!W* >Wr#MͲ!_TZs#r*lڶ*l+s#r*jN#F+q#pÌ!nq!"o"q}2uo&"s* s:n*sDM2u:uqos Computer Systems Clock - Calendar board. ***************************************************************************** S01,..59} (optional, allways set to 00) If DAY, DATE and TIME fields are ommitted then only the current time is displayed,ocessing causing 24 hour bit to be cleared. Fix bug in get_txt() which returned garbage when a negative integer was pass********* Time array is used to communicate with the primitives *************************************************************pare string to array function exit- < 300= array index 300= string not found *******************************************exit- &text "Error" if out of bounds *****************************************************************************/ char FUN, this_bnk, &cpui, &cpuo); time_array.seconds = cpuo.AF >> 8; time_array.minutes = cpuo.BC >> 8; time_array.hours*********************************************************/ set_clock() { cpui.AF = MF_STIM << 8; cpui.BC = time_array  #,3       Disk AssignmentWrong CP/M Version (Requires 2.0)!9"2!T OË!]6:\:] Hr3 Ë:\ʀËp+q!`6>!`6*`&*^*`&Y />!`4 >*]& ~ O!]49!a6:a*]& ~2bO>z*bM >*s"s*o͊O !v6>!vQ*v&w 6`i+46)A*:'ʓ:'O!) ~2vʍ:yntax: D>TOD (DAY=ddd) (DATE=mmm d,19xx) (TIME=hh:mm:ss) where ddd= day {SUNday,MONday,TUEsday,WEDnesday,THUrsday,  else the clock information specified by the field is changed. All fields are optional and any unspecified fields are not alted as the offset. 1.2 - 28 Oct 84 grh Fix bug that did a modulo 10 on the month value. This caused an error when octob******/ #define _24_hour_format 8 /* time format declarations */ #define _12_hour_format 0 #define time_format _24_hour_fo**********************************/ WORD get_offset( sptr, cptr, size) char *sptr, *cptr[]; int size; { static WORD cnt*get_txt( offs, txtptr, size) unsigned offs, size; char *txtptr[]; { return (offs >= size) ? "Error" : txtptr[offs];  = cpuo.BC & 0xff; cpui.AF = MF_GCAL << 8; farcall( (WORD) MR_FUN, this_bnk, &cpui, &cpuo); time_array.day = cpuo..seconds << 8; cpui.DE = (time_array.minutes << 8) + (time_array.hours & 0xff); farcall( (WORD) MR_FUN, this_bnk, &cpui,  <DMSY]bgnx   O O O OO͇ /ҋͺ *2!"q*"&L ͐ ͐ ͐!$p+q*#~*#N͐*##"#÷!&p+q͠*%DMͱ O O!(q*(&!b/~,H~:H~*H~.H~>H~<H~=H*]& 6!]4T!]4!cq*a&Y :cw!a4vO!w 6,]!v6>!v*v&w ~һ*vM !v4˜8AO͐:͐ͱ*##N!ͽ"* N#F*͠"FRIday,SATurday} mmm= month {JANuary,FEBruary,MARch,APRil,MAY,JUNe,JULy, AUGust,SEPtember,OCTober,NOVember,DECember} ered. Spaces and delimiters are only allowed as shown in the example. *****************************************************er (0x10 & 15 = 0 [- 1 = -1]) occurred. */ #define version "1.2" /***********************************************************rmat struct { unsigned seconds, /* 0..59 */ minutes, /* 0..59 */ hours; /* 0..23 */ char week; /* 0..6 0 !%)- "&*. #'+/  $(,0 */ unsigned day, /* 0..31 */ month, /* 1..12 */ year; /* 0..99 */ } time_array; char *day_table[7] = {"in(argc, argv) int argc; char *argv[];{ bdos(0x93, &time_array); /*** fill array with current time ***/ if (argc >(argv[cnt] + 5, month_table, nmonths); if (temp > 11){ put_err(argv[cnt]); break;} time_array.mont+; if ((*tptr == 0) || (*(tptr + 1) == 0)) tptr = argv[++cnt]; else tptr++; time_arra2*">!b!ͯ >!`0ͯ !q:E:24J!46*}a!44EJ *KM^'́:‚:H:H"!6!4:_jYO jM*"S*" 3@bl*M1͓!""DM!  ::=H-\:N2O_og_{ozg^#V))) _{ozg^#V) d^#V|g}o n_{o (asciiswitch | dataswitch))); lcount ++; } *tptr != 0) && (*tptr != ':')) tptr++; if (*tptr == ':') ++tptr; if (*tptr != 0) { Hour)"); break; } } if (error == FALSE){ puts("\nPress any key to set time.ts(", 19"); putd(time_array.year); puts(" "); putd(time_array.hours & 0x30f); puts(":"); putd(time_array.minutesnt = 0; cnt < size; cnt++){ if (strncmp(sptr, cptr[cnt], 3) == 0) return cnt; } return 300; } /****SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY", "FRIDAY","SATURDAY"}; #define ndays 7 char *month_ 1){ error = 0; for (cnt = 1; cnt < argc; cnt++){ if (strncmp("DAY=", argv[cnt], 4) == 0){ h = bin2bcd(temp + 1); if (cnt >= argc){ put_err(argv[cnt]); break;} temp = atoi(argv[++cnt]);y.year = bin2bcd(atoi(tptr) % 100); } else if (strncmp("TIME=", argv[cnt], 5) == 0){ tptr  !36'n::0:f9OY#9.3'ͳ.:020' 'ͳ'7 6'7 *M^͆ \͔!":͎H*#"ͧÝ/ :>͛9ͯ .*#":_!zgO{ozgi`N#Fogo&og H ©=¨ } /* set end of controls flag */ if (lcount == 0) lcount = 1; ctrllow[ lcount] = 0; ctrlhigh[ lcount] =  time_array.minutes = bin2bcd(atoi(tptr) % 60); while ((*tptr != 0) && (*tptr != ':')) tptr++; \n"); bdos(1,0); /*** wait for char ***/ bdos(0x91, &time_array); } } puts("\n"); p); puts(":"); putd(time_array.seconds); puts("\n\n"); exit(0); } /*************************************************************************** get text ptr from array function exit- &text "Error" if out of bounds *****table[12] = {"JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE", "JULY","AUGUST","SEPTEMBER","OCTOBERtemp = get_offset(argv[cnt] + 4, day_table, ndays); if (temp > 6){ put_err(argv[cnt]); break;} els /*** get date ***/ if ((temp < 1) || (temp > 31)){ put_err(argv[cnt]); break;} time_array.day = b= argv[cnt] + 5; if (*tptr == 0){ put_err(tptr); break; } time_array.hours = bin2bcd(atoi(tptr) !j>A+!s!"@͓1!"<**"͓n "Dn"":!Q2҂' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M cmdptr)); ctrlswitch[ lcount ] = (( switches & ( (asciiswitch ^ 0xffff) & 0; /* init disassembly variables */ segment = 0; pass = 1; endoffile = false; done = false; status = n if (*tptr == ':') ++tptr; if (*tptr != 0) time_array.seconds = bin2bcd(atoi(tptr) % 60);uts(get_txt(time_array.week & 7, day_table, ndays)); temp = time_array.month; temp = (temp & 0xf) + (((temp & 0x100) >> ************ compare string to array function exit- < 300= array index 300= string not found ***************************************************************/ char *get_txt(offs, txtptr, size) unsigned offs, size; char *txtptr[];{ retur","NOVEMBER", "DECEMBER"}; #define nmonths 12 int error; unsigned temp, cnt; char *tptr; mae time_array.week = temp; } else if (strncmp("DATE=", argv[cnt], 5) == 0){ temp = get_offsetin2bcd(temp); tptr = argv[cnt]; /* find any ',' */ while ((*tptr != 0) && (*tptr != ',')) tptr+% 24) | time_format << 8; time_array.minutes = time_array.seconds = 0; /** default **/ while ((:X!Wғä:ڤ*MEÓ:ұ@@:O2Mc;!6#6>!)*&P ~"::H:H!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈* (dataswitch ^ 0xffff))) | (getswitches( cmdptr) & oerrors; pgmcounter = offset; skipcnt = skipcount; codecount = 0; /* set to 0 to force initial read */ /* set  } } else { put_err( " >> (24 8) * 10); puts(" "); puts(get_txt(temp - 1, month_table, nmonths)); puts(" "); putd(time_array.day & 0x30f); pu*************************/ unsigned get_offset(sptr, cptr, size) char *sptr, *cptr[]; int size;{ static cnt; for (cn (offs >= size) ? "Error" : txtptr[offs]; } /****************************** put error function ****************0 !%)- "&*. #'+/  $(,0***************/ put_err(txtptr) char *txtptr;{ error = -1; /*** set global error flag ***/ puts("\nCommand Error:put char function *******************************/ putchar(c) char c;{ bdos(2, c); } /********************* 8); }  if (status >= 0){ *codeptr++ = status; codecount++; } } if (codecount = TITLE DIAGNOSTIC DISK UTILITY LIST NOCOND ;************************************************************* ; ; Diagnostic Diformatting a new disk to JADE formats. ; DIsplay: Displays buffer data in CP/M DDT format. ; SUbstitute: Allows altera**************************** ; revisions: ; 1.0 - Release ; ; 1.1 - Add DDT type buffer modification comands, ; Add Hex ***************************************** ; ; NOTE: THE FOLLOWING MODULES MUST BE LINKED TOGETHER ; WITH THIS ONE IN THIS ORD WINDOW: EQU 0CC00H DFDRV: EQU 0 ;INITIAL DEFAULT DRIVE FMTSZ: EQU 100H ;FORMAT BUFFER SIZE NDRVS: EQU 2 ; ; CONSTANTS SED BY EXTERNAL ROUTINES: ENTRY INFCB,DEFBFR,$MEMRY ENTRY NUMPARS,PARAM1,PARAM2,PARAM3,OFFSET SUBTTL MAIN PROGRAM $ THERE THEN OK AS IS JR Z,PTROK LD A,L ;MOD 16 AND 0F0H ADD 10H ;BUMP FOR > 0 LD L,A LD A,0 ADC A,H LD H,A AVE FOR LATER ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD (HL),0 POP HL ;CMD PTR CALL SKIPOH ;IGNORE SPACES JR "); puts(txtptr); } /*********************************************************** put string function overrides************ put number function **********************************/ putd(numb) unsigned numb;{ putchar((numb >>reak; } temp = ptr; if (*ptr == null) endofline = true; else endofline = false; return switches; } = 0) endoffile = true; else endoffile = false; codeptr = codebufr; } codecount--; return *codeptr++sk Utility ; allows xfer of data to & from a disk. ; ; Copyright 1981 GRH Electronics, CUPERTINO, CA ; ;*****************tion of buffer data. ; FIll: Allows filling buffer with data ; MOve: Allows moving buffer data to new buffer location.file read, limit commands to 2 chars, ; Modify source for ASMB, ; remove unused code. ; ; 1.2 - Try rel file linking agaiER: ; ; DDISK - MAIN MODULE (THIS MODULE) ; DDISKF - DISK I/O ROUTINES & FORMAT COMMAND ; UTIL - UTILITIES LIBRARY ; ;****; L1K: EQU 1024D BUFSZ: EQU 82 MAXSEC: EQU 48 SECSZ: EQU 128 ; ; ASCII CONSTANTS ; LF: EQU 0AH CR: EQU 0DH SUBMEMRY: DW 0 ;LOCATION FOR FREE MEMORY PTR ;------------------------------------------------ ; ; THIS IS THE ENTRY POINT  LD ($MEMRY),HL PTROK: LD (DISTRT),HL ;INIT BUFFER DISPLAY PTRS LD (DISEND),HL LD (DBUFRP),HL ;INIT R/W BUFFER PTR MAI Z,CMDERR ;OOPS - NO COMMAND EX DE,HL LD (CMDPTR),DE LD HL,CMDTBL ;SET UP FOR COMMAND TABLE SEARCH LD C,(HL) ;GET E library function. ************************************************************/ puts(ptr) char *ptr;{ while (*ptr ! 8) + '0'); putchar((numb & 0xf) + '0'); } /************************************* convert binary to bcd functi /* fetch a byte from input file function */ fetch(){ if (codecount == 0){ codeptr = codebufr; status = ; } /* output file handler */ output(chr) char chr;{ if (pass > 1){ /* if not 1st pass then output */ /* if bu******************************************** ; ; Except for the CP/M version relying upon the BIOS routines, DDISK is a ; s ; LOad: Allows loading a HEX format file into buffer. (Requires CP/M) ; REad: reads specified number of sectors inton. ; ; 2.0 - Clean up for Disk version only. Removed most cond- ; itionals & superfluous source code. PS. Rel worked! ; ;******************************************************** SUBTTL DECLARATIONS FALSE EQU 0 TRUE EQU NOT FALSE CPMVERS EQUTTL ASSEMBLER DIRECTIVES ; DDISKF.REL RTNS: EXTRN BSELDK, SETTRK, SETSEC, BSTDMA, RDSEC, WRSEC, FORMTC EXTRN SECTRN ; FROM THE SYSTEM: ; ;------------------------------------------------ DDISK: LD (SYSSTK),SP ;SAVE STACK LD SP,STACK LD HNLP: LD BC,INBUFR ;SET UP FOR COMMAND LD (CMDPTR),BC LD A,BUFSZ LD (BC),A PUSH BC ;OUTPUT PROMPT LD C,'*' CALL NTRY COUNT NXTCMD: INC HL LD B,(HL) CMDLP: INC HL LD A,(DE) ;IF COMMAND <> TABLE THEN MOVE ON CP (HL) JR NZ,N= 0){ if (*ptr == '\n') putchar('\r'); putchar(*ptr++); } } /****************************** on ***************************************/ unsigned bin2bcd(val) unsigned val; { return (val % 10) | ((val / 10) <<noerrors; while ((codecount < codebfrsz) & (status >= noerrors)){ status = cget(inkey); ffer full then write to disk */ if (outbfrcnt >= outbfrsz){ outbfrcnt = outbfrsz; outptr = outbufr; tand-alone disk access program for the JADE DD Disk controller card. It ; allows the following commands: ; FOrmat: allows  memory ; WRite: writes specified sector(s) to disk. ; EXit: returns to system. ; ;********************************* 2.1 - 24 Nov 84 GRH ; Rework to remove externals. Add stand-alone capability. ; VERSION EQU '20' ; ;******************* TRUE INCLUD EQU FALSE ; ; MEMORY LOCATIONS ; DEFBFR EQU 0080H BDOS EQU 0005H TPA EQU 0100H ; ; DISK CONTROLLER ;  UTIL.REL RTNS: EXTRN MOVEM,FILLM,DISPM,SUBSM,READHX EXTRN DISTRT,DISEND ENTRY RDCON, CRLF, SKIPOH, GETHEX ; SYMBOLS UL,SGNONM ;OUTPUT SIGN-ON MESSAGE CALL EDITOR LD HL,($MEMRY) ;MAKE RAM START ON EVEN NIBBLE LD A,L AND 0FH ;IF ALREADYCO POP BC CALL RDCON LD HL,INBUFR+1 ;PUT NUL AT END OF LINE LD A,(HL) INC HL ;PTR = 1ST CHAR OF CMD PUSH HL ;SOMAT INC DE DJNZ CMDLP INC HL ;FOUND, GET EXECUTION ADDR LD E,(HL) INC HL LD D,(HL) EX DE,HL LD DE,CMDRET0 !%)- "&*. #'+/  $(,0 TITLE QT CLOCK/CALENDAR READ UTILITY LIST NOCOND ;***************************************************************************************************************** FALSE EQU 0 TRUE EQU NOT FALSE LSTINC EQU FALSE *INCLUDE SYSPARAM.INC LIST ON  UPPER NIBBLE LD C,A WAITL: IN A,(CLKDAT) ;NOW WAIT FOR CHANGE AND CLKDMSK CP C JR Z,WAITL LD (SEC),A ;SAVE SECOISPLAY MONTH NAME CALL SPACE CALL SPACE LD A,(IX + CLKMONL) AND CLKDMSK ;MASK OFF UPPER NIBBLE BIT 0,(IX + CLKMO ;SET UP RETURN ADDR PUSH DE LD C,' ' ;SET COMMAND PTR TO NEXT OPERAND PUSH HL ;SAVE COMMAND ENTRY LD HL,(CMDPTR)  LD HL,INVCM ;OUTPUT INVALID COMMAND MESSAGE CALL EDITOR JP MAINLP ;############################ ; ; SIGN ON MESSAGE *addr %' DB CR,LF,'LOad addr filename.HEX' DB CR,LF,'MOve first, last, dest' DB CR,LF,'FIll first, last, data' DB CRSTITUTE DW SUBSC DB 2,'LO' ;LOAD HEX DW LOADHXC DB 2,'RE' ;READ DW READC DB 2,'WR' ;WRITE DW WRITEC DB 2 LD E,'9' CALL CONOUT LD A,(IX + CLKYRH) CALL NUMOUT LD A,(IX + CLKYRL) CALL NUMOUT ; DISPLAY TIME CALL SPACEJP 0 SUBTTL SUBROUTINES ; ; SPACE OUTPUT SUBR ; SPACE: LD E,' ' ; ; CONSOLE OUTPUT SUBR ; CONOUT: LD C,2 JP BIT 7,E ;IF BIT 7 SET THEN DONE RET NZ JR NXTCH ; ; GET CLOCK DATA SUBR ; ENTRY- C= CLOCK REGISTER # ; EXIT - A= REDS DS 15 ;RESERVED FOR OTHER DATA ; ; MONTH TABLE ; MONTBL: DW NTSET,JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC ** ; ; THIS UTILITY DISPLAYS THE TIME INFORMATION FROM THE QT COMPUTER ; SYSTEMS CLOCK/CALENDAR BOARD. ; ; DISPLAY IS IN SUBTTL DEFINITIONS BDOS EQU 0005H LF EQU 0AH CR EQU 0DH SUBTTL MAIN ORG 100H JP START START: LD SP,(BDOS + 1NDS LD HL,SEC + 1 ;SET PTR LD B,12 ;NUMBER OF READS LD C,CLKSECH ;FETCH REMAINING DATA GETLP: CALL GETD LD (HL),ANH) ;IF > 9 THEN ADD 10 JR Z,MONOK ADD A,10 MONOK: CP 13 ;IF MONTH 0..12 THEN OK JR C,MSET XOR A ;ELSE MONTH = NOT CALL SERCHH LD (CMDPTR),HL POP HL ;EXECUTE COMMAND JP (HL) CMDRET: PUSH AF ;TERMINATE LINE CALL CRLF POP AF J ; ;############################ SGNONM: DB CR,LF,' Diagnostic Disk Utility Ver ' DB HIGH VERSION DB '.' DB LOW,LF,'DIsplay <,last>' DB CR,LF,'SUbstitute addr' DM CR,LF,'EXit return to system',CR,LF,LF INVCM: DM CR,LF,LF,'Inv,'FO' ;FORMAT DW FORMTC DB 2,'EX' ;EXIT DW EXITC DB 2,'HE' ;HELP DW HELPC DB 1,'?' ;SAME AS HELP DW HELPC  CALL SPACE CALL SPACE LD A,(IX + CLKHRSH) AND 3 ;MASK OFF CONTROL BITS CALL NUMOUT LD A,(IX + CLKHRSL) CALL NBDOS ; ; TEXT OUTPUT SUBR OUTPUTS TEXT STRINGS FROM TABLE ; ENTRY- A= TABLE OFFSET ; HL= TABLE PTR ; TXTOUT: LD C,A GISTER DATA ; GETD: LD A,C ;SET UP READ SET CLKRD,A ;SET READ BIT OUT (CLKCMD),A EX (SP),HL ;DELAY EX (SP),HL  JAN DM 'January' FEB DM 'February' MAR DM 'March' APR DM 'April' MAY DM 'May' JUN DM 'June' JUL DM 'July' AUG DM 'AugustTHE FORM: ; DAY_OF_WEEK MONTH DAY,YEAR HH:MM:SS ; ;***********************************************************************) DEC SP DEC SP LD E,CR CALL CONOUT LD E,LF CALL CONOUT LD A,[1 SHL CLKRD] + CLKSECL ;READ SECONDS UNTIL CHANGE  INC C ;NEXT CLK REGISTER INC HL ;NEXT SAVE LOC DJNZ GETLP ;DO UNTIL GOT ALL ; GOT DATA, RELEASE CLOCK & DISPLAYSET MSET: LD HL,MONTBL CALL TXTOUT ; DISPLAY DAY OF MONTH CALL SPACE LD A,(IX + CLKDAYH) AND 3 ;MASK OFF CONTROP NC,MAINLP JP CMDERR NOMAT: INC HL ;WASTE TABLE ENTRY DJNZ NOMAT INC HL DEC C ;IF NOT LAST THEN LOOP LD DE,( VERSION DB CR,LF,' (c) 1981 GRH Electronics',CR,LF OPTMSG: DB CR,LF,'OPTIONS:' DB CR,LF,' Prints this lialid command! - Re-enter.',CR,LF,LF ;############################ ; ; COMMAND TABLE ; ;############################ CM ENTCNT: EQU 11 SUBTTL COMMANDS ;**************************** ; ; EXIT COMMAND ; ;**************************** EXITC: UMOUT LD E,':' CALL CONOUT LD A,(IX + CLKMINH) CALL NUMOUT LD A,(IX + CLKMINL) CALL NUMOUT LD E,':' CALL CONOU;COMPUTE TABLE PTR LD B,0 ADD HL,BC ADD HL,BC LD A,(HL) ;GET MESSAGE PTR FROM TABLE INC HL LD H,(HL) LD L,A NXIN A,(CLKDAT) RET ; ; NUMBER OUTPUT SUBR ; ENTRY- A= BINARY NUBER 0..9 ; NUMOUT: AND CLKDMSK ;MASK OFF STRAY BITS AD' SEP DM 'September' OCT DM 'October' NOV DM 'November' DEC DM 'December' ; ; DAY OF WEEK TABLE ; DAYTBL: DW SUN,MON,T***** ; ; REVISIONS: ; ; X.X - 6 MAR 83 GRH ; INITIAL RELEASE ; VERS EQU '00' ; ;*************************************OUT (CLKCMD),A EX (SP),HL ;DELAY FOR CHIP EX (SP),HL IN A,(CLKDAT) ;GET 1ST READING THEN SAVE AND CLKDMSK ;MASK OFF DATA LD IX,SEC ;SET PTR TO DATA LD A,(IX + CLKWEEK) ;DISPLAY DAY OF WEEK AND 7 LD HL,DAYTBL CALL TXTOUT ; DL BITS CALL NUMOUT LD A,(IX + CLKDAYL) CALL NUMOUT ; DISPLAY YEAR LD E,',' CALL CONOUT LD E,'1' CALL CONOUT CMDPTR) JR NZ,NXTCMD ;---------------------------- ; ; INVALID COMMAND- ERROR ; ;---------------------------- CMDERR:st' DB CR,LF,'FOrmat a disk' DB CR,LF,'REad :drive @trk >sec #cnt *addr %(translate)' DB CR,LF,'WRite :drv @trk >sec #cnt DTBL: DB ENTCNT DB 2,'MO' ;MOVE DW MOVEC DB 2,'FI' ;FILL DW FILLC DB 2,'DI' ;DISPLAY DW DISPC DB 2,'SU' ;SUBLD SP,(SYSSTK) ;RESTORE STACK JP 0 ;**************************** ; ; HELP COMMAND ; ;**************************** HET LD A,(IX + CLKSECH) CALL NUMOUT LD A,(IX + CLKSECL) CALL NUMOUT LD E,CR CALL CONOUT LD E,LF CALL CONOUT TCH: LD E,(HL) ;GET CHAR FROM MESSAGE PUSH HL PUSH DE ;OUTPUT CHAR CALL CONOUT POP DE POP HL INC HL ;NEXT CHAR D '0' ;CONVERT TO ASCII LD E,A ;OUTPUT IT JP CONOUT SUBTTL DATA AREA ; ; TIME DATA SAVE AREA ; SEC: DW 0 ;SECONUE,WED,THU,FRI,SAT,NTSET SUN DM 'Sunday' MON DM 'Monday' TUE DM 'Tuesday' WED DM 'Wednesday' THU DM 'Thursday' FRI DM 'F0 !%)- "&*. #'+/  $(,0{;;  > O(2! w #!~!{~  F( 8!~~,1*************************************** FALSE EQU 0 TRUE EQU NOT FALSE LSTINC EQU FALSE *INCLUDE SYSPARAM.INC LIST ON  UPPER NIBBLE LD C,A WAITL: IN A,(CLKDAT) ;NOW WAIT FOR CHANGE AND CLKDMSK CP C JR Z,WAITL LD (SEC),A ;SAVE SECOISPLAY MONTH NAME CALL SPACE CALL SPACE LD A,(IX + CLKMONL) AND CLKDMSK ;MASK OFF UPPER NIBBLE BIT 0,(IX + CLKMOLPC: LD HL,OPTMSG CALL EDITOR OR A RET DATA SYSSTK: DW 0 CMDPTR: DW INBUFR INBUFR: DB BUFSZ ;CONSOLE READ BUFFOLLOWING WAS IMPLEMENTED TO ALLOW REPEATED ACCESSES ; LD A,(DSEC) ;MOVE PARAMETERS TO LOCAL VARS LD (CSEC),A LD HL,(DBUFR) CALL BSTDMA LD A,(WRFLG) OR A JR NZ,WRT CALL RDSEC JR OPDONE WRT: CALL WRSEC OPDONE: BIT 7,A ;IF ERROR ,'Disk Error - Returned Code= ' ;############################ ; ; DISK ACCESS TABLE ; ;############################ CH SUBR ; ;************************************** DSETUP: LD HL,(CMDPTR) LD C,':' ;FETCH DRIVE # CALL SERCHH LD A,(DDRRKOK: LD (DTRK),A LD C,A CALL SETTRK LD HL,(CMDPTR) ;FETCH SECTOR # LD C,'>' CALL SERCHH LD A,(DSEC) ;DEFAULT = CUZ,BFROK INC HL ;FETCH OFFSET CALL SKIPOH PUSH HL POP BC CALL GETHEX LD DE,($MEMRY) ;ADD IN OFFSET ADD HL,DE  JP C,DATAERR ;IF NO OPERANDS THEN RETURN CP 3 JP C,DATAERR LD HL,(PARAM1) ;ADD OFFSET TO PARAMS CALL ADDOFF JP C9~ ~ ~~:~~:~~   O ~#fo^#{ySUBTTL DEFINITIONS BDOS EQU 0005H LF EQU 0AH CR EQU 0DH SUBTTL MAIN ORG 100H JP START START: LD SP,(BDOS + 1NDS LD HL,SEC + 1 ;SET PTR LD B,12 ;NUMBER OF READS LD C,CLKSECH ;FETCH REMAINING DATA GETLP: CALL GETD LD (HL),ANH) ;IF > 9 THEN ADD 10 JR Z,MONOK ADD A,10 MONOK: CP 13 ;IF MONTH 0..12 THEN OK JR C,MSET XOR A ;ELSE MONTH = NOT ER LENGTH DB 0 ;CONSOLE CHARS READ DS BUFSZ REL ;**************************** ; ; READ SECTOR COMMAND ; ;*****P) LD (CBUFRP),HL LD HL,(DSCNT) LD (CSCNT),HL DKLP: LD A,(DTRAN) ;IF TRANSLATE FLAG = TRUE THEN TRANSLATE OR A LD ATHEN EXIT JR Z,OPOK PUSH AF LD HL,DSKERM ;OUTPUT MESSAGE CALL EDITOR POP AF LD L,A ;OUTPUT ERROR CODE CALL PUDATA DDRIVE: DB 0 ;DISK DRIVE DTRK: DB 1 ;TRACK # ; *** THESE TWO MUST BE IN THIS ORDER TO WORK *** DSEC: DB 1 ;SECTOR # DSIVE) ;DEFAULT DRIVE = CURRENT DRIVE JR Z,DRVOK INC HL CALL SKIPOH PUSH HL POP BC CALL GETDEC LD A,L DRVOK: LDRRENT_SECTOR JR Z,SECOK1 INC HL CALL SKIPOH PUSH HL POP BC CALL GETDEC LD A,L SECOK1: LD (DSEC),A LD C,A  EX DE,HL BFROK: LD (DBUFRP),DE LD HL,(CMDPTR) ;SET TRANSLATION FLAG LD C,'%' CALL SERCHH RET Z ;IF NOT SPEC'D THE,BNDSERR LD (PARAM1),HL LD HL,(PARAM2) CALL ADDOFF JP C,BNDSERR LD (PARAM2),HL LD HL,(PARAM3) CALL ADDOFF 0_;  > 18@EJMQU[dksJanuarFebruarMarcApriMaJunJulAugusSeptembeOctobeNovembeDecembe) DEC SP DEC SP LD E,CR CALL CONOUT LD E,LF CALL CONOUT LD A,[1 SHL CLKRD] + CLKSECL ;READ SECONDS UNTIL CHANGE  INC C ;NEXT CLK REGISTER INC HL ;NEXT SAVE LOC DJNZ GETLP ;DO UNTIL GOT ALL ; GOT DATA, RELEASE CLOCK & DISPLAYSET MSET: LD HL,MONTBL CALL TXTOUT ; DISPLAY DAY OF MONTH CALL SPACE LD A,(IX + CLKDAYH) AND 3 ;MASK OFF CONTRO*********************** READC: XOR A ;CLEAR WRITE FLAG JR DACCES ;**************************** ; ; WRITE SECTOR COM,(CSEC) LD C,A LD B,0 JR Z,TRNOT CP 27 ;IF ATTEMPTING TO TRANSLATE > 26 SECTORS THEN JR NC,TRNOT ;NO TRANSLATION THEX CALL CRLF OR A ;RETURN CLEAN RET OPOK: LD HL,(CBUFRP) ;PTR := PTR + SECTOR SIZE LD DE,SECSZ ADD HL,DE LD CNT: DW 1 ;SECTOR COUNT DBUFRP: DW 0 ;DISK DATA BUFFER PTR CBUFRP: DW 0 CSEC DB 1 CSCNT DW 1 WRFLG: DB FALSE ;DISK WR (DDRIVE),A LD C,A LD E,0 ;LOGON VECTOR := FULL LOGON CALL BSELDK LD HL,(CMDPTR) LD C,'@' ;FETCH TRACK # CALL SECALL SETSEC LD HL,(CMDPTR) LD C,'#' CALL SERCHH LD DE,1 JR Z,CNTOK INC HL CALL SKIPOH PUSH HL POP BC CALN USE LAST INC HL CALL SKIPOH LD A,(HL) SUB '0' ;0: FALSE, /0: TRUE NOTRN: LD (DTRAN),A RET SUBTTL MOVE MEMO JP C,BNDSERR LD (PARAM3),HL CALL MOVEM ;GOTO EXTERNAL SUBR JP C,BNDSERR RET SUBTTL FILL MEMORY COMMAND ;**SundaMondaTuesdaWednesdaThursdaFridaSaturdaCLOCK NOT SETOUT (CLKCMD),A EX (SP),HL ;DELAY FOR CHIP EX (SP),HL IN A,(CLKDAT) ;GET 1ST READING THEN SAVE AND CLKDMSK ;MASK OFF DATA LD IX,SEC ;SET PTR TO DATA LD A,(IX + CLKWEEK) ;DISPLAY DAY OF WEEK AND 7 LD HL,DAYTBL CALL TXTOUT ; DL BITS CALL NUMOUT LD A,(IX + CLKDAYL) CALL NUMOUT ; DISPLAY YEAR LD E,',' CALL CONOUT LD E,'1' CALL CONOUT MAND ; ;**************************** WRITEC: LD A,TRUE ;SET WRITE COMMAND DACCES: LD (WRFLG),A CALL DSETUP ; ; THE F DEC C ;EXPECTS {0..N-1} LD DE,SDTRAN ;SET TRANSLATION TABLE PTR CALL SECTRN LD C,L TRNOT: CALL SETSEC LD BC,(CBUFRP(CBUFRP),HL LD HL,CSEC INC (HL) INC HL ;IF COUNT = 0 THEN DONE DEC (HL) JR NZ,DKLP RET DSKERM: DM CR,LF,LFITE FLAG DTRAN: DB FALSE ;SECTOR TRANSLATION FLAG REL ;************************************** ; ; DISK PARAMETER FETRCHH LD A,(DTRK) ;DEFAULT = CURRENT_TRACK JR Z,TRKOK INC HL CALL SKIPOH PUSH HL POP BC CALL GETDEC LD A,L TL GETDEC EX DE,HL CNTOK: LD (DSCNT),DE LD HL,(CMDPTR) ;FETCH BUFFER PTR LD C,'*' CALL SERCHH LD DE,(DBUFRP) JR RY COMMAND ;**************************** ; ; MOVE COMAND ; ;**************************** MOVEC: CALL GETPARMS ;GET PARAMS ************************** ; ; FILL COMAND ; ;**************************** FILLC: CALL GETPARMS JP C,DATAERR ;IF PARM CNT 0 !%)- "&*. #'+/  $(,0riday' SAT DM 'Saturday' NTSET DM 'CLOCK NOT SET ' END  LD HL,1 LD A,L LD (QZENDOFFIL ),A CC35: CC33: CC30: JP CC36 CC26: LD A,(QZPASS ) CALL CCSXT PUSH HL LD HL,2  ADD HL,DE CALL CCGINT LD (QZSTART ),HL LD HL,QZCTRLHIGH PUSH HL LD HL,0 ADD HL,HL POP DE ADD HL,DE CALL CCGIND A,H OR A,L JP Z,CC39 CALL QZNL LD HL,CC1+262 PUSH HL CALL QZPUTS POP BC CALL QZNL CALL QZEXIT CC39: CC38:  < 3 THEN ERR CP 3 JP C,DATAERR LD HL,(PARAM1) CALL ADDOFF JP C,BNDSERR LD (PARAM1),HL LD HL,(PARAM2) CA************* DISPC: CALL GETPARMS CP 3 ;IF PARM CNT > 2 THEN ERR JP NC,DATAERR LD C,A LD HL,(PARAM1) ;IF P1 <> -1ALL DISPM ;EXTERNAL SUBR OR A RET SUBTTL SUBSTITUTE MEMORY COMMAND ;************************************** ; ; SUBST HL,(CMDPTR) CALL SKIPOH ;IF NO OPERAND THEN ERR JP Z,DATAERR LD (CMDPTR),HL ;P1 = VALUE 1 PUSH HL POP BC CALL  LD (HL),'X' LD BC,INFCB CALL OPEN INC A JR NZ,LOAD1 LD HL,FNFMSG CALL EDITOR OR A RET LOAD1: LD BC,(P##### ERRMTBL: DW HXFILER DW HXCONVE DW BNDSM FNFMSG: DM CR,LF,'File Not Found!',CR,LF HXFILER: DM CR,LF,'Hex File  BOUNDS ERROR MSG OUTPUT SUBR ; ;************************************** BNDSERR: LD HL,BNDSM CALL EDITOR OR A RET PARAM OR SPACE BEFORE ; EXIT - NUMPARS = ACTUAL PARAMETER COUNT (0-3) ACCEPTED ; A = NUMPARS ; PARAM1-3 = PARAMETER VALUWIT PUSH HL LD A,(QZSEGMENT ) CALL CCSXT POP DE ADD HL,DE CALL CCGCHAR LD A,L LD (QZSWITCHES ),A LD HL,QZCTRLL POP DE CALL CCEQ LD A,H OR A,L JP Z,CC37 LD HL,1 LD A,L LD (QZDONE ),A JP CC38 CC37: LD HL,2 LD A,L LD T LD (QZSTOP ),HL LD HL,0 LD (QZCODECOUN ),HL LD HL,(QZOFFSET ) LD (QZPGMCOUNT ),HL LD HL,(QZSKIPCOUN ) LD (QZSKIP CC36: JP CC24 CC25: INC SP RET QZNL: LD HL,13 PUSH HL CALL QZPUTCHAR POP BC RET QZSKIP: CC40: LD HL,2 ALL ADDOFF JP C,BNDSERR LD (PARAM2),HL CALL FILLM ;GOTO EXT SUBR JP C,BNDSERR RET SUBTTL DISPLAY MEMORY COMMAN THEN INC HL LD A,L OR H DEC HL JR Z,DISP1 CALL ADDOFF ;P1 = P1 + OFFSET JR DISP2 DISP1: LD HL,(DISEND) ;ELSITUTE MEMORY COMMAND ; ;************************************** SUBSC: CALL GETPARMS JP C,DATAERR CP 2 ;IF COUNT > 1 THGETHEX LD (PARAM1),HL LD HL,(CMDPTR) ;GET FILENAME LD C,' ' CALL SERCHH JP Z,DATAERR LD (CMDPTR),HL LD HL,(PARAM1) LD DE,(BDOS+1) CALL READHX ;EXTERNAL SUBR OR A ;IF NO ERRORS THEN RETURN RET Z AND 3 DEC A ;COMPUTE OFFSError',CR,LF HXCONVE: DM CR,LF,'Hex Conversion Error',CR,LF BNDSM: DM CR,LF,'Command Value out of Bounds!',CR,LF DATAM: D ;###################################### ; ; 3740 FORMAT PARAMETERS ; **** CP/M SINGLE DENSITY **** ; ;################ES ; PARAM1 = -1 IF LEADING ',' ENCOUNTERED ; PARAM2-3 = 0 IF NO PARAMS GIVEN ; ;***************************************OW PUSH HL LD A,(QZSEGMENT ) CALL CCSXT ADD HL,HL POP DE ADD HL,DE CALL CCGINT LD (QZSTART ),HL LD HL,QZCTRLHI(QZPASS ),A LD HL,0 LD A,L LD (QZENDOFFIL ),A LD HL,0 LD A,L LD (QZSEGMENT ),A LD HL,QZCTRLSWIT PUSH HL LD HL,CNT ),HL LD HL,(QZINKEY ) PUSH HL CALL QZFCLOSE POP BC LD HL,0 LD A,L LD (QZBYTECNT ),A LD HL,(QZINFILEPT ) PUDD HL,SP CALL CCGINT CALL CCGCHAR PUSH HL LD HL,32 POP DE CALL CCEQ PUSH HL LD HL,4 ADD HL,SP CALL CCGINT D ;********************************************************** ; ; DISPLAY MEMORY COMMAND - TRICKY ; ENTRY- IF PARAM1 = -1 TE P1 = LAST END DISP2: LD (PARAM1),HL LD HL,(PARAM2) ;IF P2 <> 0 THEN LD A,L OR H JR Z,DISP3 CALL ADDOFF ;P2 =EN ERR JP NC,DATAERR LD HL,(PARAM1) CALL ADDOFF JP C,BNDSERR LD (PARAM1),HL JP SUBSM ;EXTERNAL SUBR SUBTTL ARAM1) ;ADD OFFSET CALL ADDOFF JP C,BNDSERR LD (PARAM1),HL LD HL,(CMDPTR) LD DE,INFCB CALL FCBFMT LD A,0 ;FET SLA A LD HL,ERRMTBL ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD A,(HL) INC HL LD H,(HL) LD L,A CALL EDITOM CR,LF,'Not Enough Data!',CR,LF ;************************************** ; ; DATA ERROR MSG OUTPUT SUBR ; ;************###################### SDTRAN: DB 1,7,13,19,25,5,11,17,23,3,9,15,21 DB 2,8,14,20,26,6,12,18,24,4,10,16,22 SUBTTL SUBROUTI******************* GETPARMS: LD HL,0 ;INIT VALUES LD (NUMPARS),HL LD (PARAM2),HL LD (PARAM3),HL DEC HL ;P1 = -1 GH PUSH HL LD A,(QZSEGMENT ) CALL CCSXT ADD HL,HL POP DE ADD HL,DE CALL CCGINT LD (QZSTOP ),HL JP CC35 CC34: 0 POP DE ADD HL,DE CALL CCGCHAR LD A,L LD (QZSWITCHES ),A LD HL,QZCTRLLOW PUSH HL LD HL,0 ADD HL,HL POP DE SH HL LD HL,CC1+260 PUSH HL CALL QZFOPEN POP BC POP BC LD (QZINKEY ),HL PUSH HL LD HL,0 POP DE CALL CCEQ LCALL CCGCHAR PUSH HL LD HL,0 POP DE CALL CCNE POP DE CALL CCAND LD A,H OR A,L JP Z,CC41 LD HL,2 ADD HL,SP HEN OLD PARAM2 IS USED FOR PARAM1 ; IF PARAM2 = 0 THEN 16 LINES ARE OUTPUT ; ;********************************************* P2 + OFFSET JR DISP4 DISP3: LD DE,16*16 ;ELSE P2 = P1 + 16 LINES LD HL,(PARAM1) ADD HL,DE DISP4: LD (PARAM2),HL CLOAD HEX FILE COMMAND ;**************************** ; ; LOAD HEX FILE COMAND ; ;**************************** LOADHXC: LDUDGE UNTIL NEW FCBFMT PROM BURNED LD (INRECD),A LD HL,INTYPE ;MAKE HEX FILE LD (HL),'H' INC HL LD (HL),'E' INC HL R OR A RET ;###################################### ; ; HEX FILE ERROR MESSAGES ; ;#################################************************** DATAERR: LD HL,DATAM CALL EDITOR OR A RET ;************************************** ; ;NES ;********************************************************** ; ; GET PARAMETERS SUBR ; ENTRY- (CMDPTR) = POINTER TO 1ST  LD (PARAM1),HL LD HL,(CMDPTR) ;SKIP LEADING SPACES CALL SKIPOH SCF RET Z LD (CMDPTR),HL LD A,(HL) ;IF CHAR = !0 !%)- "&*. #'+/  $(,0',' THEN SKIP TO 2ND CP ',' JR Z,GETP2 PUSH HL POP BC CALL GETHEX LD (PARAM1),HL ;SAVE P1 LD HL,NUMPARS INC THEX LD (PARAM3),HL LD A,(NUMPARS) ;CNT = CNT + 1 INC A LD (NUMPARS),A RET ;***********************************) ; EXIT - HL= PTR TO FOUND CHAR ; DE= HL ON ENTRY ; ZF= NOT FOUND ; ;************************************************ S************************************************ SKIPOH: LD A,(HL) ;IF *PTR != ' ' THEN RETURN NZ CP ' ' JR NZ,SKIPFND ************ EDITOR: LD E,(HL) ;GET CHAR & 7FH RES 7,E PUSH HL ;OUTPUT IT LD C,2 CALL BDOS POP HL BIT 7,(HL OR A ;IF CHAR == 0 THEN RETURN RET Z SUB '0' ;CONVERT ASCII TO BINARY RET C ;IF CHAR < 0 THEN RETURN ERR CP 10ATED) ; EXIT - HL= NUMBER ; CF= INVALID NUMBER ; DE= ? ; ;************************************************ GETDEC: LD HL GETDLP ;********************************* ; ; OUTPUT HEX NUMBER SUBR ; ENTRY- HL= # TO OUTPUT ; ;********************POP AF RET SUBTTL CPM RTNS ;********************************* ; ; CONSOLE INPUT FUNCTION ; EXIT - A= CHAR ; ;*****C POP DE LD C,10 JP BDOS ;********************************* ; ; CONSOLE STATUS FUNCTION ; EXIT - A= 0: NOT READY EQ RDSEQ: PUSH BC POP DE LD C,20 JP BDOS ;**************************** ; ; SET DMA FUNCTION ; ENTRY- BC= XFER ADDY CHAR LESS THAN 21H) ; DE= FCB PTR ; ZF= NO WILDCARDS USED ; NZ= WILDCARD(S) USED (A= # OF WILDCARDS) ; ;*************(HL) GETP2: LD HL,(CMDPTR) ;GET NEXT PARAM LD C,',' CALL SERCHH RET Z INC HL ;PASS ',' CALL SKIPOH RET Z L*** ; ; ADD OFFSET SUBR ; ENTRY- HL= VALUE TO BE OFFSET ; EXIT - HL= NEW VALUE ; DE= MODIFIED ; CF= OVERFLOW ; ;******ERCHH: LD A,(HL) ;IF CHAR == 0 THEN RETURN 0 OR A RET Z CP C ;IF CHAR == *PTR THEN BREAK JR Z,SERCHFND INC HL  INC HL JR SKIPOH SKIPFND: OR A ;RETURN NZ RET ;************************************** ; ; CRLF OUTPUT SUBR ) ;IF CHAR > 80H THEN RETURN RET NZ INC HL ;ELSE NEXT CHAR JR EDITOR SUBTTL CONVERSION RTNS ;******************* ;IF CHAR > 9 && CHAR < 'A' THEN RETURN ERR JR C,GETHOK SUB 7 CP 10 RET C CP 16 CCF RET C GETHOK: ADD HL,H,0 ;TOTAL = 0 GETDLP: LD A,(BC) ;GET CHAR OR A ;IF CHAR == 0 THEN RETURN NC RET Z SUB '0' ;CONVERT ASCII TO BINAR************* ENTRY PUT2HX, PUTHEX PUT2HX: LD A,H CALL PTHEX PUTHEX: LD A,L PTHEX: OR A ;CLEAR CY RLA CALL PRDIG **************************** CI: LD C,1 JP BDOS ;**************************** ; ; CONSOLE OUTPUT SUBR ; ENTRY- C= CHA; ;********************************* ENTRY CSTS CSTS: LD C,11 JP BDOS ;**************************** ; ; OPEN FILE FR ; ;**************************** ENTRY SETDMA SETDMA: PUSH BC POP DE LD C,26 JP BDOS SUBTTL FCB FORMATTER SUBR ************************************************ DFLTDK: EQU 0004H ;DEFAULT DISK LOCATION ZROSIZ: EQU 21 ;NUMBER OF BYTES TOD (CMDPTR),HL ;SAVE PTR PUSH HL POP BC CALL GETHEX LD (PARAM2),HL LD HL,NUMPARS ;CNT = CNT + 1 INC (HL) GETP3: ******************************** ADDOFF: LD DE,(OFFSET) ADD HL,DE RET ;OVERFLOW ERROR SUBTTL ASCII RTNS ;********** ;NEXT CHAR JR SERCHH SERCHFND: OR A ;RETURN NZ RET ;************************************************ ; ; SKIP ; ;************************************** CRLFM: DM CR,LF CRLF: LD HL,CRLFM ;OUTPUT STRING ;******************************************************* ; ; ASCII -> HEX CONVERSION ; ENTRY- BC= TEXT PTR (0 TERMINATED) ; EXIT - HL= NUMBER ; CF= IL ;SHIFT TOTAL OVER ADD HL,HL ADD HL,HL ADD HL,HL ADD L ;ADD NEW TO TOTAL LD L,A INC BC ;NEXT CHAR JR GETHLY RET C ;IF NOT NUMERIC THEN RETURN CF CP 10 CCF RET C PUSH HL ;TOTAL POP DE ADD HL,HL ;TOTAL = TOTAL * ((4 PRDIG: RLA ;OUTPUT MS DIGIT RLA RLA RLA PUSH AF ;SAVE PUSH HL AND 0FH ;MASK CP 10 ;IF NUMERIC THEN OK AS R ; ;**************************** ENTRY CO, CHOUT CHOUT: CO: LD E,C LD C,2 JP BDOS ;*****************************UNCTION ; ENTRY- BC= FCB PTR ; ;**************************** OPEN: PUSH BC POP DE LD C,15 JP BDOS ;**************;************************************************************* ; ; CP/M FILE CONTROL BLOCK FORMATTER ; ENTRY- HL= POINTER TO  INIT NAMCNT: EQU 8 ;FILENAME CHAR CNT TYPCNT: EQU 3 ;FILE EXTENSION CHAR CNT FCBFMT: PUSH DE ;SAVE FCB PTR FOR RETURN LD HL,(CMDPTR) LD C,',' CALL SERCHH RET Z INC HL CALL SKIPOH RET Z LD (CMDPTR),HL PUSH HL POP BC CALL GE************************************** ; ; SEARCH FOR CHAR SUBR ; ENTRY- C= CHAR TO SEARCH FOR ; HL= TEXT PTR (0 TERMINATEDCHARS UNTIL NEXT FIELD SUBR ; ENTRY- HL= TEXT PTR (0 TERMINATED) ; EXIT - HL= 1ST NON-SPACE CHAR PTR ; ZF= END OF LINE ; ;********************** ; ; TEXT OUTPUT SUBR ; ENTRY- HL= TEXT PTR (>80H TERMINATED) ; ;************************************NVALID NUMBER ; ;************************************************ GETHEX: LD HL,0 ;TOTAL = 0 GETHLP: LD A,(BC) ;GET CHARP ;************************************************ ; ; ASCII -> DECIMAL CONVERSION SUBR ; ENTRY- BC= TEXT PTR (0 TERMIN + 1) * 2) ADD HL,HL ADD HL,DE ADD HL,HL ADD A,L ;ADD NEW TO TOTAL LD L,A LD A,0 ADC A,H LD H,A INC BC JRIS JR C,NTALPH ADD 7 ;ELSE CONVERT 10..15 -> A..F NTALPH: ADD '0' ;CONVERT TO ASCII LD C,A CALL CHOUT POP HL ********* ; ; READ CONSOLE BUFFER FUNCTION ; ENTRY- BC= BUFFER PTR ; ;************************************** RDCON: PUSH B************** ; ; READ SEQUENTIAL FUNC ; ENTRY- BC= FCB PTR ; EXIT - A= 0: OK ; ;**************************** ENTRY RDSASCII STRING OF FILENAME ; DE= POINTER TO FCB TO FORMAT ; EXIT - HL= POINTER TO TERMINATION CHAR OF STRING ; ('/' OR AN EX DE,HL SKIP: LD A,(DE) ;SKIP LEADING SPACES CP '/' JR Z,L89 CP ' ' JR C,L89 JR NZ,FCB1 INC DE JR SKIP"0 !%)- "&*. #'+/  $(,0 FCB1: SUB '@' ;MAKE 'A'-'P' = 1-15 FOR DRIVE # LD B,A INC DE ;IF NEXT CHAR = ':' THEN MUST BE DRIVE LD A,(DE) CPA ;ADD CHAR TO FCB FILENAME INC DE LAB: DJNZ L98 ;IF NOT DONE THEN LOOP LAF: CALL RSVP ;IF RESERVED CHAR THEN EXIT  NZ,LD9 LD (HL),'?' JR LDB LD9: LD (HL),A ;ADD CHAR TO FCB INC DE LDB: DJNZ LC8 LDF: CALL RSVP ;IF RESERVED COR A POP HL ;SET UP REGS FOR RETURN EX DE,HL RET ;************************************** ; ; RESERVED CHAR TEST SUBC RET RSVPT: DB '=_.:;,<>/' ;RESERVED CHAR TABLE TABCNT: EQU $-RSVPT DATA NUMPARS DB 0 ;NUMBER OF PARAMETERS :15 pm (gtf) ; Fixed bug in CPMIO which returned wrong error status. ; Added PUTS() function ; Un-hardwired I/O b(); ; GETC, PUTC now operate on chars. ; CGET, CPUT now operate on bytes( no check ; for CR, LF or CTRL-Z. ;- RET ;Fetch a full 16-bit integer from the address in HL CCGINT: LD A,(HL) INC HL LD H,(HL) LD L,A RET ;Store a sing SUBTTL BIOS RTNS ;**************************** ; ; SELECT DISK FUNCTION ; ENTRY- C= DRIVE # ; E= LOGON FLAG ; ;********# ; ;**************************** ENTRY SETSEC SETSEC: PUSH DE LD DE,[11 * 3] - 3 JR BIOSE ;**************************************** ; ; WRITE SECTOR FUNCTION ; EXIT - A= 0: OK, 1: ERR ; ;********************************* ENTRY WRSEC ********************* ENTRY FORMTC FORMTC: RET END  ':' JR Z,L90 DEC DE ;ELSE BACK UP & USE DEFAULT DRIVE L89: LD A,(DFLTDK) LD (HL),A ;FCB(DISK) := DRIVE # JR L96 JR Z,LC0 INC DE ;SKIP OVER EXTRA CHARS TO '.' JR LAF LB9: INC HL ;FILL REMAINDER OF FCB WITH SPACES LD (HL),' ' DHAR THEN EXIT JR Z,LF0 INC DE ;WASTE CHARS JR LDF LE9: INC HL ;FILL REMAINING TYPE WITH SPACES LD (HL),' ' DJNZBR ; ENTRY- (DE) = CHAR TO TEST ; EXIT - ZF = FOUND ; ;************************************** RSVP: LD A,(DE) ;IF CHAR <= ENTERED PARAM1 DW 0 ;1ST PARAM ENTERED PARAM2 DW 0 ;2ND PARAM ENTERED PARAM3 DW 0 ;3RD PARAM ENTERED OFFSET EQU $MEMRY ;POINuffer count. ; Made GETCHAR() print LF after reading CR. ; Made GETCHAR() return -1 on EOF (=CTRL-Z) ; Added EOL ----------------------------------------------------------------- ; ; Runtime library initialization. Set up default drive fole byte from HL at the address in DE CCPCHAR: LD A,L LD (DE),A RET ;Store a 16-bit integer in HL at the address in DE CCP******************** ENTRY BSELDK BSELDK: PUSH DE LD DE,[9 * 3] - 3 BIOSE: LD HL,(1) ADD HL,DE POP DE JP (HL) *********** ; ; SET XFER ADDR FUNCTION ; ENTRY- BC= XFER ADDR ; ;********************************* ENTRY BSTDMA BSTDMA: WRSEC: PUSH DE LD DE,[14 * 3] - 3 JR BIOSE ;************************************** ; ; SECTOR XLATE FUNCTION ; ENTRYn in HL CCASL: EX DE,HL DEC E ;DDJ 2-81 BUG FIX GRH RET M ADD HL,HL JP CCASL+1 ;Subtract HL from DE and return in HL L90: LD A,B ;USE SPECIFIED DISK LD (HL),B INC DE ;SKIP OVER ':' L96: LD B,NAMCNT ;B := MAX CHARS L98: CALL RSVP JNZ LB9 LC0: LD B,TYPCNT ;COUNT = SIZEOF(TYPE) CP '.' ;IF CHAR != '.' THEN FILL WITH SPACES JR NZ,LE9 INC DE ;GET N LE9 LF0: LD B,ZROSIZ ;ZERO EXTENT, S1, S2, RECORD COUNT LF2: INC HL LD (HL),0 DJNZ LF2 POP HL ;COUNT WILDCARDS ' ' THEN RETURN Z CP ' ' + 1 JR NC,RSVP1 XOR A RET RSVP1: PUSH BC PUSH HL LD B,TABCNT ;B := ENTRY COUNT LD HLTER TO DATA BUFFER INFCB: DS 9 INTYPE: DS 3 DS INFCB + 36 - $ INRECD EQU INFCB + 32 DS 128 STACK: EQU $ END DDand LF equates, instead of magic numbers ; V4d As of July 16, 1980 9:00 pm (gtf) ; Added EXIT() function ; ; V5 Septembr CP/M. CCGO: LD C,QUERY ;get logged-in disk CALL BDOS INC A ;make it so it will work in fcb LD (DFLTDSK),A RET ;FetINT: LD A,L LD (DE),A INC DE LD A,H LD (DE),A RET ;Inclusive "or" HL and DE into HL CCOR: LD A,L OR E LD L,A L ;**************************** ; ; SET TRACK FUNCTION ; ENTRY- C= TRACK # ; ;**************************** ENTRY SETTRK SPUSH DE LD DE,[12 * 3] - 3 JR BIOSE ;********************************* ; ; READ SECTOR FUNCTION ; EXIT - A= 0: OK, 1- BC= LOGICAL SECTOR ; DE= XLATE TABLE PTR ; EXIT - HL= PHYSICAL SECTOR ; ;************************************** ENTRY S CCSUB: LD A,E SUB L LD L,A LD A,D SBC A,H LD H,A RET ;Form the two's complement of HL CCNEG: CALL CCCOM INC HL JR Z,LB9 INC HL ;PTR := PTR +1 CP '*' ;IF WILDCARD THEN ENTER '?' JR NZ,LA9 LD (HL),'?' JR LAB LA9: LD (HL),EXT CHAR AFTER '.' LC8: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LE9 INC HL ;IF CHAR <> '*' THEN EXIT CP '*' JR PUSH HL LD BC,NAMCNT+TYPCNT L01: INC HL LD A,(HL) CP '?' JR NZ,L09 INC B L09: DEC C JR NZ,L01 LD A,B ,RSVPT RSVPL: CP (HL) JR Z,RSVPX ;IF FOUND THEN EXIT INC HL DJNZ RSVPL INC B ;RETURN NZ RSVPX: POP HL POP ISK er 12, 1981 grh ; Changed code to Z-80 for CZ80, added extended ; CP/M functions: bios();codend();topofmem(); and bdosch a single byte from the address in HL and ; sign extend into HL CCGCHAR: LD A,(HL) CCSXT: LD L,A RLCA SBC A,A LD H,A D A,H OR D LD H,A RET ;Exclusive "or" HL and DE into HL CCXOR: LD A,L XOR E LD L,A LD A,H XOR D LD H,A RET ETTRK: PUSH DE LD DE,[10 * 3] - 3 JR BIOSE ;**************************** ; ; SET SECTOR FUNCTION ; ENTRY- C= SECTOR : ERR ; ;********************************* ENTRY RDSEC RDSEC: PUSH DE LD DE,[13 * 3] - 3 JR BIOSE ;***************ECTRN SECTRN: PUSH DE LD DE,[16 * 3] - 3 JR BIOSE ;**************************** ; ; FORMAT COMMAND STUB ; ;******* RET ;Form the one's complement of HL CCCOM: LD A,H CPL LD H,A LD A,L CPL LD L,A RET ;Multiply DE by HL and ret#0 !%)- "&*. #'+/  $(,0c Prom Programmer UtilityVer 1.2 Copyright (c) 1981,'82,'83 GRH Enterprises Cupertino, CA 1w*+"!G !vN˹y(JK KB8BJ8Z: 8O_8Eg8?oKB8?K "K KB8 %*8w# 8!v G ! !"[R[R8*y* *y*t "*">2   8/ ڙ"  8}<(2 (&o[*t  ڙ"= [R> C + *t5 [(~. |}[*tͻ *[R " Yy( :O:2 ~ȹ(;#~ #    ~#Ob ( = ( A˸  *t5 "t:=[ؼ>2 ! :8))))o: <2 :  ,ȷ7|C }H X O  80*RBK>){_zW({> REad addr d:file SAve first, last HEX d:file FIll first, last, value MOve first, last, dest DIsplay <, last> SUbs/M RE=FINE7MODIVSUPRSAHE?HCPCHUCO9vqÇ *R0!;>O(!_y !~>2>>>t>>>>>K[͹  y s) not Programmable. Try erasing. Successful Program. OK Bytes requested exceeds prom size! Wrong configurator installed! T2?\(652?`($( $&2?#$($(%($&###2?d(##%( ; } JP FOPIF4 FOPIF1: ; else if(*mode=='w' || *mode=='W'){ LD HL,(MODE) LD A,(HL) CP 77H ; 'w' 9 Jun 80 rj J#!v"t*t5 ~*(\!p 8* (!+>P!OV"> 2! < ! G ! G + F 8(! G ! G = * + * ! *tͻ *[R#" "*t ' 5 "t ' 5 "t!p  <(! G  Y(yl {(#"*t~!(M͛  ڙ*"*R#"*"  >2 8}<(2 (&o[l {(#" ! G *t~! " S8} = = *txR,E- ^ !h G ~H( @G:(:wxp (#* 6?w (#6 .  (#* 6?w (#6 #6St #~?  x!0z }o{_zW=t Prom Overlay Not Found Enter Prom Type - Disk Read Error Disk Write Error, Probably Full! File Existtitute addr CHecksum first, last PRogram > ComPare  y >$˯@(!88 !>K*[> >: o$urn off Inhibit Switch & type any key - Hardware Error- No EOC! Program Voltage out of tolerance! : Prom not erased! Contin$&662?h(65%( $&W % %$& "$& /%(%%& - % %65$&HP Z,FOPIF1A CP 57H ; 'W' 9 Jun 80 rj JP NZ,FOPIF5 FOPIF1A: LD C,DELETE ; cpm(DELETE,unit); LD HL,(UNIT) EX DE,HL t5 ("t^#V!;F#~ #~ #^#V*t ' 5 "t###Í>2 *t  ڙ"*t ' 5 "t{>2 *t ' "t!p>2 !"*:̈́ڥ*}BA"0G!"x(Q8_[R|8N}8H8B~8<#82 ̈́8+ ̈́8(N͛  ڙ*[R#"S*"  >2 8}<(2 (&o[l {(#"*t(~,(  "*t>,(O' *}#~E#~X#~ J:8''''GJ:8GWx! G 70 ? ?: q& ! 7 !">2 *~#"! 5! (#=_.:;,<>v> #N˹#"t 6C& ! : *|(![S[& s, Delete?..(Y/N) - *** Syntax Error ***...Type 'HElp' For List File Not Found Value Out of Bounds Memory Error Hex File skip>> COpy count <, dest<, skip>> CTRL-C To Exit to CP/M RE=FINE7MODIVSUPRSAHE?HCPCHUCO9v y>*[K[ !"!z{!͹!~!!͹: oj$ y[*[K[ ue? (Y/N) - $H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!I, Data Read Back = Data Written = PASSED Command Error, Type H or ? for list. Command not implemented yet! ,IX CALL BDOS LD C,CREATE ; if(cpm(CREATE,unit)<0){ LD HL,(UNIT) EX DE,HL CALL BDOS OR A JP P,FOPIF3 LD HL,(UNIT)   < !C G !S G K: (F 8 ! G !h G 2 *"Jڄ: q_qgqo"*"$*}:̈́88 ͻ8! G ͛  ڙ[*Ry:*w͛ * ڙ"* "* o#5 "t  "= *"[R> *~#C c 8} "*~0 0>.O #[{ z c *q#": <2 ?ҴS&  2 7̈́: ( !<7GWx????X Ö́8xX Ö́! *":=v *t5 7"t  *t,' 7#5 7"t *t,' 7#5 7"t s#r#* "* "Error Hex Conversion Error Illegal Hex Load Address Regression! Illegal Hex Record Type! Hex File Empty! HElp NEw {z{z~ Data Error at Is: Should be: Bit($I$I$UUU$$A$ (SP),IY! 1 (F)%65655& 2?%-%&%(%($(652?%B X+>">-f:?: ; freeio(unit); PUSH HL CALL FREEIO POP HL LD HL,NULL ; return(NULL); RET ; } FOPIF3: LD HL,(IP) ; ip$0 !%)- "&*. #'+/  $(,0 &cpuo); cpui.AF = MF_SCAL << 8; cpui.BC = time_array.day << 8; cpui.DE = (time_array.month << 8) + (time_array.yes) not Programmable. Try erasing. Successful Program. OK Bytes requested exceeds prom size! Wrong configurator installed! T2?\(652?`($( $&2?#$($(%($&###2?d(##%(HL,(UNIT) EX DE,HL CALL BDOS OR A JP P,FCLIF5 LD HL,0 ; t = 0; LD (ZT),HL FCLIF5: LD HL,(UNIT) ; freeio(unit×í*R0!?"O(!cy !>2>>>t>>>>>K[  y Bit(s) not Programmable. Try erasing. Successful Program. OK Bytes requested exceeds prom size! Wrong configurator installed2?\(652?`($( $&2?#$($(%($&###2?d(##%( ; /* to absorb LF */ CALL CGET LD A,L POP HL CALL GETCRET ; GETCRET(C'); POP HL ; RETURN C; RET ; GETCmÃ*R0!O(!9y !X>2>>>t> >>>>'K[ͣ  y !cessful Program. OK Bytes requested exceeds prom size! Wrong configurator installed! Turn off Inhibit Switch & type any key 2?\(652?`($( $&2?#$($(%($&###2?d(##%( ;putcerr: POP BC ; return(-1); LD HL,-1 RET ; ; cput(c,unit) ; CPUT: QZCPUT: POP BC POP DE POP HL LD (Zar & 0xff); cpui.HL = time_array.week & 0xff; farcall( (WORD) MR_FUN, this_bnk, &cpui, &cpuo); } urn off Inhibit Switch & type any key - Hardware Error- No EOC! Program Voltage out of tolerance! : Prom not erased! Contin$&662?h(65%( $&W % %$& "$& /%(%%& - % %65$&H); PUSH HL CALL FREEIO POP HL LD HL,(ZT) ; return(NULL+t); RET ; ; fcb(fp,name) ; QZFCB: FCB: POP HL ;get a!_Y> y >"˯@(!88 !dK*[{z~> >: o$ y! Turn off Inhibit Switch & type any key - Hardware Error- No EOC! Program Voltage out of tolerance! : Prom not erased! Co$&662?h(65%( $&W % %$& "$& /%(%%& - % %65$&HRET: CP CTRLZ ;IF (C == EOF) RETURN; RET NZ LD HL,(UNIT) ; unit[FLAG] != EOF_FL; LD DE,FLAG ADD HL,DE LD A,(HL) O_Y> y >$˯@(!88 !>K*[{z~> >: o$ y- Hardware Error- No EOC! Program Voltage out of tolerance! : Prom not erased! Continue? (Y/N) - I @BB $A"$&662?h(65%( $&W % %$& "$& /%(%%& - % %65$&HCH),HL EX DE,HL LD (UNIT),HL PUSH DE PUSH HL PUSH BC LD DE,FCBSIZE ; ip = unit + FCBSIZE; ADD HL,DE LD (IP),HL  y>*[K[ !"!z{!͹!~!!͹: oj$ y[*[K[ ue? (Y/N) - $H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!ITE ; if(cpmio(WRITE,unit)<0) PUSH HL LD HL,(UNIT) PUSH HL CALL CPMIO POP DE POP DE LD A,H OR A JP P,FCLIF4 rgs POP DE ;name POP BC ;fp PUSH BC PUSH DE PUSH HL INC DE ; if(name[1]==':'){ LD A,(DE) DEC DE CP ':' Ky({z>> >  y>*[Ḱ !&!z{!!~!!ntinue? (Y/N) - ! BH" !I B  $$!BD! $!BI D@"!$I$$H"!I ; } PAD2: RET ; return; ; ; getc(unit) ; QZGETC: POP BC POP HL ; get args PUSH HL PUSH BC ; c=cget(unR EOFFLG LD (HL),A LD HL,-1 ; return(-1); RET ; ; cget(unit) ; CGET: QZCGET: POP DE POP HL LD (UNIT),HL PUSH>*[KW !!z{!ͣ!~!!ͣ: of$ yW*[KW !$$$I$$H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!IPUT POP DE LD A,H OR A JP M,PUTCERR LD A,L ; if(c=='\r') CP EOL JP NZ,PUTCRET LD HL,LF ; cput('\n',unit);  LD DE,NEXTP ; cp = ip[NEXTP]; ADD HL,DE LD E,(HL) INC HL LD D,(HL) EX DE,HL LD (CHP),HL LD HL,(IP) ; if(ip[U!7 *|!R!*[K͹w: oҲ$ y¤>{z{z~ Data Error at Is: Should be: Bit($I$I$UUU$$A$  LD HL,0 ; t = 0; LD (ZT),HL FCLIF4: ; } FCLIF3: ; } FCLIF1: LD C,CLOSE ; if(cpm(CLOSE,unit)<0) LD  JP NZ,FCBIF1 LD A,(DE) ; A = *name - '@'; SUB 40H ; '@' 9 Jun 80 rj INC DE ; name += 2; INC DE CP 61H-41H ;: oҐ$ y*[Ḱ !;*[Kw: o$ y¸>{z Data Error at Is: Should be: $I$I$UUU$$A$ it); PUSH HL CALL CGET POP DE LD A,L ; if(c=='\r') CP EOL JP NZ,GETCRET PUSH HL ; C' = cget(unit) PUSH DE  HL PUSH DE LD DE,FLAG ; if(unit[FLAG] & EOF_FL) ADD HL,DE LD A,(HL) AND EOFFLG JP Z,GETCIF1 LD HL,-1 ; return*[Kͣw: oҜ$ yŽ>{z Data Error at Is: Should be: Bit(s) not Programmable. Try erasing. Suc$I$I$UUU$$A$ PUSH HL PUSH DE CALL CPUT POP DE POP DE LD A,H OR A JP M,PUTCERR PUTCRET: POP HL ; return(c); RET PUTCERR:NUSED]==0){ LD DE,UNUSED ADD HL,DE LD A,(HL) INC HL OR (HL) JP NZ,PUTCIF1 LD HL,WRITE ; if(cpmio(WRITE,unit)~=0)%0 !%)- "&*. #'+/  $(,0mÃ*R0!O(!9y !X>2>>>t> >>>>'K[ͣ  y !cessful Program. OK Bytes requested exceeds prom size! Wrong configurator installed! Turn off Inhibit Switch & type any key 2?\(652?`($( $&2?#$($(%($&###2?d(##%(CHAR1: CP EOL ; if(t==EOL) JP NZ,GETCHAR2 PUSH HL ; putchar('\n'); LD C,PUTCH LD E,LF CALL BDOS POP HL GETCHAmà *R0!O(!9y !X>2>>>t> >>>>'K[ͣ  y !cessful Program. OK Bytes requested exceeds prom size! Wrong configurator installed! Turn off Inhibit Switch & type any key 2?\(652?`($( $&2?#$($(%($&###2?d(##%((HL) ;GO TO IT! BIOSRTN: LD L,A ;SET UP PARAM LD H,0 RET ; ; codend() ; Returns last address of compiled code + 1 ; mÃ@*R0!O(!9y !X>2>>>t> >>>>'K[ͣ  y !cessful Program. OK Bytes requested exceeds prom size! Wrong configurator installed! Turn off Inhibit Switch & type any key 2?\(652?`($( $&2?#$($(%($&###2?d(##%(AD INITIAL VALUE PUSH HL ;DEST = SRC + 1 POP DE INC DE DEC BC ;COUNT = COUNT - 1 (FOR 1ST BYTE) LDIR ;FILL RET ; _Y> y >$˯@(!88 !>K*[{z~> >: o$ y- Hardware Error- No EOC! Program Voltage out of tolerance! : Prom not erased! Continue? (Y/N) - I @BB $A"$&662?h(65%( $&W % %$& "$& /%(%%& - % %65$&HR2: RET ; return(t); ; ; puts(cp) ; QZPUTS: POP BC ; get args POP HL PUSH HL PUSH BC PUTS1: LD A,(HL) ; _Y> y >$˯@(!88 !>K*[{z~> >: o$ y- Hardware Error- No EOC! Program Voltage out of tolerance! : Prom not erased! Continue? (Y/N) - I @BB $A"$&662?h(65%( $&W % %$& "$& /%(%%& - % %65$&HQZCODEND: LD HL,CCCODEND RET ; ;----------- End of Small-c library ----------- ; ; ; C library utilities file: ; ; Ve_Y> y >$˯@(!88 !>K*[{z~> >: o$ y- Hardware Error- No EOC! Program Voltage out of tolerance! : Prom not erased! Continue? (Y/N) - I @BB $A"$&662?h(65%( $&W % %$& "$& /%(%%& - % %65$&H; movmem(src,dest,count) ; QZMOVMEM: POP IX POP BC ;COUNT POP DE ;DEST POP HL ;SRC PUSH HL PUSH DE PUSH BC PUS>*[KW !!z{!ͣ!~!!ͣ: of$ yW*[KW !$$$I$$H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!Iputchar('\n'); LD E,LF CALL BDOS LD HL,(CHP) ; return(buff); RET ; ; getchar() ; QZGETCHAR: LD C,GETCH ; t = cwhile(*cp) OR A JP Z,PUTSRET LD E,(HL) ; putchar(*cp++); INC HL PUSH HL LD C,PUTCH CALL BDOS POP HL JP PUTS1>*[KW !!z{!ͣ!~!!ͣ: of$ yW*[KW !$$$I$$H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!IAMS POP BC POP DE PUSH DE ;RESTORE STACK PUSH BC PUSH IX LD HL,(1) ;GET BASE ADDR OF BIOS DEC HL DEC HL DEC HLrsions: ; 1.0 - release ; ;********************************************************** ; ; Contents: ; ; inp(port) char po>*[KW !!z{!ͣ!~!!ͣ: of$ yW*[KW !$$$I$$H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!IRN ADDR PUSH IX JP (IY) ;THEN GO TO IT CALLARET: LD L,A ;RETURN A IN HL LD H,0 RET ; ; setmem(addr,length,val) ; H IX LD A,B ;IF COUNT == 0 THEN RETURN OR C RET Z LD A,H ;IF DEST > SRC THEN MOVE DOWNWARD CP D JR C,TAILF JR NZ,H*[Kͣw: oҜ$ yŽ>{z Data Error at Is: Should be: Bit(s) not Programmable. Try erasing. Suc$I$I$UUU$$A$ pm(GETCH,0) & 0377; CALL BDOS LD L,A LD H,0 CP CTRLZ ; if(t==CTRLZ) JP NZ,GETCHAR1 LD HL,-1 ; t = -1; GET PUTSRET: RET ; return; ; ; putchar(c) ; QZPUTCHAR: POP BC POP HL LD (ZCH),HL PUSH HL PUSH BC EX DE,HL *[Kͣw: oҜ$ yŽ>{z Data Error at Is: Should be: Bit(s) not Programmable. Try erasing. Suc$I$I$UUU$$A$  LD A,E ;ADDR=OFFSET*3+BASE ADD A,A ADD E LD E,A LD D,0 ADD HL,DE LD IX,BIOSRTN ;SET RETURN VECTOR PUSH IX JP rt; /* inputs data from 'port' */ ; outp(port,val) char port, val; /* outputs val to port */ ; call(addr,a,h,b,d) int addr,a,h*[Kͣw: oҜ$ yŽ>{z Data Error at Is: Should be: Bit(s) not Programmable. Try erasing. Suc$I$I$UUU$$A$ QZSETMEM: POP IX POP DE ;VALUE POP BC ;LENGTH POP HL ;START ADDR PUSH HL PUSH BC PUSH DE PUSH IX LD (HL),E ;LOEADF LD A,L CP E JR C,TAILF RET Z ;IF DEST == SRC THEN SAVE TIME BY RETURNING HEADF: LDIR RET ; TAILF: DEC BC ;&0 !%)- "&*. #'+/  $(,0;;; Universal Prom Programmer Test Program Ver 1.1 COPYRIGHT 1982, GRH ENTERPRISES Options: 0- Confidence !%>!!v20(## t1(## 2(!%>!~~!8}w|w{ia!x*Timer to Set, (0..2 or any other to abort) - Turn Program Switch "OFF" & Press Any Key.. Turn Program Switch "ON" & Press Any,32,105,110,112,117,116,32,102,105 DB 108,101,33,0,67,97,110,110,111,116 DB 32,99,108,111,115,101,32,111,117,116 DB 112,11ÎSUNDAYMONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAYJANUARYFEBRUARYMARCHAPRILMAYJUNEJULYAUGUSTSEPTEMBEROCTOBERfo^#V"x(Q!"t(*t(͓#,*t(͔#B!"r(*x(!]î*t(}2n(*x(~j*x(^!,#j*x(#"x(I*x(~{*x(#~—*v(#"B!!$:m(o&"B!!9!DAY=Err: %sDATE=Err: %sErr: %sErr: %sTIME=Err: %s >!x y  ! H >Yx>$˯@(7׷ Key.. Inhibit Switch Error! A/D Returned All 0s! A/D Returned all 1s! EOC Not Returned in Reasonable Time! TEST FAILED7,116,32,102,105,108,101,33,0 QZCMDPTR: DS 2 QZCMDBFR: DS 128 QZCODECOUN: DS 2 QZCODEPTR: DS 2 QZCODEBUFR: DS 1024 QZOUTBFNOVEMBERDECEMBER"!"z(!(!z(!!͠#!9*(ͺ"}2q(́! 9^#V!2#!"r(!"v(*v()!9~#fo^#V"x(*v(#v()!9~#fo^#V"x(Þ*x(#"x(*x(Q!}2p(ë!*x(!eD š*x("x(*x(~!"r(*x(!kî*x(Q!}2l(!}2j(}2kATE=mmm d,yy> >> (24 Hour) Press any key to set time. %s %s %2d,19%2d %2d:%2d:%2d "!"&*&#"&*9!Q"z(:n(o&ͪ""|(:p(o&":o(o&ͪ""~(:m(o&""(!(!z(:q(o&!͠#!9)"! 9! 9^#V! is program also strips off the line number field of the ASMZ file. Input files should be *.SRC, but need not be. Output file w"x.0" /************************************************************* */ #define false 0 #define true 1 #define null 0 ************************* variable declarations *************************************************************/ int ioutfile[nbufsiz]; /* output filename buffer */ int outkey; /* output file key */ int temp; int ch; /*********? or H- Re-type This List CTRL-C - Return to Main Program !- H(h(?(0!080!u_~#fox! A8_0 8  ?))))o>_(  !P{ˇ_ Done Not Returned in Reasonable Time! Test Ru, Data Read Back = Data Written = PASSED Command Error, Type H or ? for list. Command not implemented yet! ,IXRCN: DS 2 QZOUTPTR: DS 2 QZOUTBUFR: DS 1024 QZINFILEPT: DS 2 QZINKEY: DS 2 QZOUTFILEN: DS 15 QZOUTKEY: DS 2 QZINBUF: DS 8"v(*v(! 9~#fo͓#ʮ!*x(!:D p!!$*x("t(*t(͔#f!"r(*x(!?î*t(}2m(ë!*x(!GD (*x(~"*x(^!:#"*x(#"x(*x(^!:"8*x(#"x(*x(~ʗ*x(Q!}2k(*x(~m*x(^!:#m*x(#"x(L*x(^!:"ʃ*x(#&!9~#fo͓#>!*&)!9~#fo^#V!9^#VD ;*&!,"! 9^#V!9~#foͅ#c!{z! 9^#V)!9~#fo^#VError8)"!9N#F!" &!9^#V"&!9~#fo#s#r+^"&| *&%" !!9s!""&! "$&!'"&&!9~#fo#s#r+^"&-ill be named INPUTFILE.Z80 in order to be compatible with ASMB. SYNTAX: A>ASMZCV INFILE.SRC This will accept ASMZ s #define namesiz 14 #define nbufsiz 19 #define ibufsiz 1024 #define obufsiz 1024 #define defltbufr 0x80 #define noerrorsbufcnt; /* input buffer byte count */ char *ibufptr, /* input file bufer ptr */ ibuf[ibufsiz]; /* input file buff**************************************************** program start ******************************************************> W P G#!>!>!. !>![ !>!'>W!z!{nning, Type any key to Abort.. Enter New Divisor (Return to Terminate, Non-Hex to abort) - Existing Timer divisor = Input (SP),IY! 1 (F)%65655& 2?%-%&%(%($(652?%B X+>">-f:?:0 QZENDOFFIL: DS 1 QZENDOFLIN: DS 1 QZSTATUS: DS 2 QZSWITCHES: DS 1 QZTEMP: DS 2 QZMEMTOP: DS 2 QZOFFSET: DS 2 QZSYMTAB:­! !$*x("t(*t( ͔#!"r(*x(!Mî*t(#}2o(*v(! 9~#foͅ#!"r(*x(!Uî*v(#"v()!9~#"x(*x(~ʗ*x(Q!}2j(ë!"r(!s î*r(|! !!+:j(o&:k(o&:l(o&:p(o&:n(o&! !$:o(o&+"!T"z(!(!z(:q(o&!͠#!9*(ͺ"}2j(*(ͺ"}2k(*("}2l(!S"z(!(!z(:q(o&!͠#!9*(ͺ"}2"ʢ!""&!9~#fo#s#r+^"&*&0"!0"$&!9~#fo#s#r+^"&*&*" *&##"&++^#V"(&!9~#fo#s#r+^"ource file 'INFILE.SRC' as input and create 'INFILE.Z80' on same drive. **************************************************** false #define error (-1) #define asmeof 1 #define ctrlz 0x1a #define cr 0x0d #define lf 0x0a #define tab 0x09 #definer */ int obufcnt; /* output buffer byte count */ char *obufptr, /* output file buffer ptr */ obuf[obufsiz];*******/ main(){ initialize(); run(); exit(); } /* initialize & fetch user comand */ initialize(){ c'0 !%)- "&*. #'+/  $(,0har *cptr; temp = ( *defltbufr) & 0xff; /* save char count */ cptr = defltbufr + 1;/* remove leading spaces */ infile.Z80' */ while ((*cptr != null) & (*cptr != '.') & (*cptr != ' ')){ cptr++ ; } *cptr++ = '.'; * converter */ run(){ char field, flag; flag = false; field = 0; ch = (fetch() & 0xff); while ((ch > 0) & (nt; output( tab ); output( ';'); } else output( ch ); } else i'*') & (flag == false)){ output( ';' ); field = comment; } else if (ch > spaces else field = label; } } if (ch == cr){ output( lf ); flag = false;  *ibufptr++ = status; ibufcnt++; } else{ *ibufptr++ = 0;/* set eof flag !"); nl(); exit; } obufcnt--; } obufcnt = 0; obufptr = obuf; put file!"); nl(); } status = fclose( outkey ); if (status < 0){ nl(); puts("Cannot close output file!"); while ((*cptr == ' ') & (temp > 0)){ temp = temp - 1; cptr++; } if (temp == 0){ nl(); puts("Inpucptr++ = 'Z'; *cptr++ = '8'; *cptr = '0'; if ((inkey = fopen( infile, "r")) == false){ nl(); puts("Input filech != asmeof)){ if (field == comment){ if (ch > spaces){ ch = ch - spaces;/* convert to # spaces f (field == opcode){ if (ch > (spaces + 4)){ field = comment; output( tab ); ou){ field = opcode; output( ':' ); output( tab ); } else{  field = 0; } ch = (fetch() & 0xff); } output( ctrlz); finishup(); } /* functions */ n*/ ibufcnt++; } } ibufptr = ibuf; } ibufcnt--; return *ibufptr++; } *obufptr++ = chr; obufcnt++; } finishup(){ int status; obufptr = obuf; while (obufcnt > 0){ nl(); exit(); } } #include cz80.lib #include cutil.lib t file needed."); nl(); exit(); } movmem( cptr, infile, namesiz ); if ( temp > namesiz) temp = namesiz ;  not found!"); nl(); exit(); } if ((outkey = fopen( outfile, "w")) == false){ nl(); puts("Disk full?"); */ while (ch > 0){ output(' '); ch = ch - 1; } } tput( tab ); output( ';'); } else if (ch > spaces){ field = operand;  output( ch ); flag = true; } } else if (field == 0){ if (ch > spaces){ l(){ putchar(13); } fetch(){ int status; if (ibufcnt == 0){ ibufptr = ibuf; status = noerrors; } output(chr) char chr;{ int status; if (obufcnt >= obufsiz){ obufcnt = obufsiz; obufptr = obuf; status = cput( *obufptr++, outkey); if (status < 0){ nl(); puts("Disk full on last write!"); nl(); br infile[ temp ] = null; movmem( infile, outfile, namesiz); /* outfile = infile */ cptr = outfile; /* make outfile ' nl(); exit(); } ibufcnt = 0; /* init buffer vars */ obufcnt = 0; obufptr = obuf; } /* main else output( ch ); } else if ( field == operand ){ if (ch > spaces){ field = comme output( tab ); } else output( ch ); } else if (field == label){ if ((ch ==  if (ch > (spaces + 1)){ field = opcode; output( tab ); }  while ((ibufcnt < ibufsiz) & (status >= noerrors)){ status = cget( inkey); if ( status >= 0){  while (obufcnt > 0){ status = cput(*obufptr++, outkey); if (status < 0){ nl(); puts("Disk fulleak; } obufcnt--; } status = fclose( inkey); if (status < 0){ nl(); puts("Cannot close in(0 !%)- "&*. #'+/  $(,0* \ \ !%!A"!9!!-!9%! H*!TA|ʁ*!͸"!9%#-+;!"!"!";;!9!*!9!*!A"*!T*!NA|!9!H|*!T|ʺ!:͠! ͠(*͠!9!*È!9!H|ʈ*!T|ʈ*!!T||!9!*! ͠È!9!n!\ *+"#ý!"!"*#"+!9**#"+!"*!T|ʪ!9*#"+*-!9%)<  D  }o{_zW=!  , , z/W{/_x/Gy/O{_zW{zn+n+n+:I _ ! >)<  D  }ozW=!  , , z/W{/_x/Gy/O{_zW{zn+n+n+:I _ ! >!>w *J ͓ !*J "J !"X *J !~ʛ !*J *J $"L *L ^#V"N *L "P *N *P zw ƒ {҃ *N 6#"N } ! |!"V "J $"L ^#V"N *L ~#w!*J )|`!*L s#r*L "N *L ^#s x|8 }8 l&Input file needed.rInput file not found!wDisk full?Disk full!Disk fu*!H|ʢ!6\ !9%!! *!T|!"!*!*!!! !9!-!*!͸"*!T|ʷ! ͠*!͸"Î*͠È!9!H|*!T|!9!*! ͠!;!**! H|ʸ! ͠!9!*!9!*!A"<!͠E! *!H|ʋ!"!9!!h|ʟ!yê*+"#L!9* -!9%!h|!!9* -!9%!h|ʌ  !6!6!||g}oä)ò{ozg/g}/oDM!yxGyOȯ{_zWDMzz, x4 >ʌ  !6!6!||g}oä)ò{g/g}/oDM!yxGyOȯ{_zWDMzz, x4 >c !*J )| !"X *J  !"X *J ͓ *X : @ :I & . . &..! 6}.Vr+s*N #*L  s#r:V *N w&o"N +V6+^6O *N +^#6s#r# *N o&!  ~^#ll on last write!Cannot close input file!Cannot close output file!9%!N!9%!.NA!9%! NA|S!9%#-+!9%#-+!.*!9%#-+!Z*!͠*͠È!9!H|ʖ*!!T|d!9!*! ͠! ͠!;͠Ó*!T|ʋ!9!*-*!h!9%!bA|ʅ!9*h-!9%!b|j*#"+!9%**#"+Â*#"+!**#"!\ <2I ~og~#fo}}|}o|g}o|g}o|gn+n+n+n+n+n+{_z!{ɳ7͘)<  D  }o{_zW=!  , , z/W{/_x/Gy/O{_zW{zn+n+n+:I _ ! >)<  D  }ozW=!  , , z/W{/_x/Gy/O{_z"T "R u "J |$"L *L *L  s#r*J *R ͺ *J a{ - .((..}:|-.h} Vh}V*J !~w!"J !~}!*J "V :V # *V &"Z "J *J n&}*J $*Z M*J  "X *X |y!|!9%#-+!8*!9%!0*!!IA "!H|!K\ !!aA "!H|!c\ ! ͠Ó*͠È!9!H|+*!*H!9!HA|!;͠!9!*(*!T|!9!*+!"*+"#*#"+*!b|'!"!"*!T|!9*#"+*-!9%!h|+͘+͘+͘+zŸ{!||g}oä)ò{ozg#|/g}/oDM!yxGyOȯ{_zWDMzz, x4 >ʌ  !6!6!||g}oä)ò{ozg/g}/oDM!yxGyOȯ{_zWDMzz, x4 >n&}*T ~rʖ R¿ *J  *J ͓ !*L s#r *T ~w W *J *J  *J ͓ !*L s#r*J $"L ^#V"N *L ~#!*J )|ʵ!*L s#r*L "N *L ^#Vr+s*N #*L  s#r*N ~o&|}ʍ*+*+++{_!o&h&i!o&)0 !%)- "&*. #'+/  $(,0 DDISK Diagnostic Disk Utili Table of Contents 1. System Requirements 1 2. Useful th assembly language & will crash if not run on a Z80 generic processor. 2. CP/M (Tm) is required. Both BDOS functions and o an CP/ compatabl dis controller becaus al the others use the BIOS vectored calls which are common to all CPM sys al memor examination/modificatio command star o syste track read-i buffer.) Yo ma mak not o th origi 1 Al command consis o word o whic onl th firs tw character are required. All other characters are optionad checkin o inputte dat i don t tr t catc typos bu DDISK assumes you know what you're doing when you invoke it. Sion bu we all forget. EXit or ctrl-c Return to CP/M .pa FOrmat Thi comman get yo int th JAem tracks image. or use ctrl-c to return to main menu Enter function number: _ Function '1' will format to JADE Dogle density Function '4' will format only track 0 & 1 (the first two) to Jade format: Track 0 Single den - secto (JAD I secto) a buffe relative location 0. Functio '6 wil writ th buffe content startin witREad <:d> <@t> <>s> <#c> <*a> <%> Read a sector(s) off a disk. Where: :d is drive specifier (numerical, A ty Documentation ings to know 2 3. Detailed Command Summary  BIOS calls are utilized. 3 JAD Compute Product Doubl dis controlle i recommended bu no required ɠ devetems. .pa 2. Useful Things to Know 1 If fo an reason yo wan t mov th buffe u na valu fo back-trackin i cas somethin goe wrong, then increase it's value to make room for more data or code. NOTEl. 2 REa WRit command hav man operand preceede b specia character Thes specia character neeo be careful. 5 Al buffe addres reference ar buffe relative Tha is 0000 valu correspond t th firsD Doubl forma utility Upo entry you are prompted with another menu: Jade DD Disk Formatter Ver 1.0 by Girvin Heuble Density format: Track 0 Single density Track 1 - 76 Double density Function '2' will fsity Track 1 Double density Thi theoreticall coul b don t disk containin dat withou  buffe relativ location out to the system tracks (0 & 1) on a disk you specify. Note however tha i orde t writ s= 0, B = 1 etc.) DEFAULT = 1 @t is optional decimal track specifier 0 - 76 DEFAULT = 0 >s  GRH Electronics 18921 Pendergast Ave. Cupertino, CA 9501 3 4. Error Summary 8 .pa .PN 1 lope thi Utilit t enabl m t buil u th JADŠ forma syste disk I yo don' hav th JAD Doubl controller thi ra (i.e t mak roo fo patch) ther i locatio tha ma b change t d this Locatio 0103Ƞ contain w I th lo byt o thi pointe doe no en i (xxx0H) the th DIspla comman wil no outpu dat field cor no b i an specia order bu mus be immediatly followed by the particular data. All other commands require entry of op locatio o th buffer no locatio o syste ram. 6. Items enclosed in angle brackets (<>) are optional items for rr (c) 1981 GRH Electronics, Cupertino, CA ****** Functions List ****** 1. Format Jade Double Density 8" 2. Format Jaormat to JADE Single density format: Track 0 Single density Track 1 Double density  overwritin th Director o trac 2 however yo d thi a som peri o losin you daomethin meaningful yo mus hav rea th syste track of anothe disk o someho programme th buffe previously FOr is optional decimal start sector number 1 - 48 DEFAULT = 1 #c is optional decimal sector count 1 - 255 4 (c) 1982 by GRH Electronics ALL RIGHTS RESERVED .OP .PA .HE DDISK User's Manual PRELIMINARY  1. System Requirements 1 Don' eve tr t ru thi progra o a 8080/85 I i code i Z8e d NO us th built-i dis formatte command I i peculia t th JADŠ controller Al othe command shoul woror pointe t th firs availabl RA locatio afte th DDISˠ program DDISˠ use thi a th star o it buffe ( forectly I like modul 1 memory address value. .pa 3. Detailed Command Summary Notes: erands in a specific order. 3. Spaces are delimiters. Any number are allowed, but must be at least one. 4 Som bouncommands. .pa Miscellaneous commands: HElp or ? Output th comman summar list Th lis i outpu afte invokatde Single Density 8" 3. Format IBM 3740 Standard 8" 4. Format system tracks only. 5. Read system tracks image. 6. Write syst Track 2 - 76 Single density Function '3' will format to IBM Single density format (STD): Track 0 - 76 Sinta. Functio '5 wil rea th syste track of dis yo specif an loa the int th buffe startin wit tracmat does not check this for you! CTRL-C will get you back to DDISK command level NOT CP/M. .pa Disk action commands:  DEFAULT = 1 *a is optional hexadecimal buffer address to read into DEFAULT = 0 i optiona *0 !%)- "&*. #'+/  $(,0translat flag I present th sector wil b translate as they are accessed on the disk. WRite <:d> <@t> <>LT = 1 *a is optional hexadecimal buffer address to write from DEFAULT = 0 i optiona translat flag I .pa Buffer data manipulation commands: MOve first, last, dest Mov bloc o dat fro 'first throug 'last i ptional start address. DEFAULT = previous 'last' address ,last optional end address. D th ne dat followe b return Onl th las tw digit entere wil b used I yo d no wis t chang thi not found on the disk you specified. Hex File Error The Hex file being read in has a record error of some sort. Hplease. Transfer Incomplete O rea o writ syste tracks th operatio ha a error Probabl th dis contro&Q !"(&% !9~#fo#s#r+^"&*&%#^!"Q *(& x"*&"(& *&." !9~#fo#s#r+^"&*"ʪ *9*.&U#"*&**&*&&2# *&&"*&*"&|\ 0 * &#" &*(&+"(&#**&2#\ *$&`i""Y !) !",&l *,&#",&*.&~ʣ *,&*&&1#ʣ )"!=$! 9^#V )"!9N#F`i "Q ! 9^#V! ` "Q !! 9^#V` )"! 9N#F! ^#V`i^#Vͅ#ʖ"/!`in&"s!`is#r! s#r!`i~#@! ^#V!"y!! 9! ^=#! 9^#V! ^#Vs> <#c> <*a> <%> Write a sector(s) to a disk. Where: :d is drive specifier (numerical, A = 0, B = 1 etc.)  present th sector wil b translate as they are accessed on the disk. LOad addr filename.HEX Loath buffe t 'dest i th buffer Al entrie ar buffe relativ an i Hexadecima radix. FIll first, last, data EFAULT = 16 lines (256 bytes) All entries are buffer relative and in Hexadecimal radix. SUbstitute addr Allo mod particula location ente onl return T abor bac t th DDIS comman mode ente perio ('.' an return. .ex Conversion Error The hex file being read in has an invalid hex digit. Command Value out of Bounds! The addlle belched tr again I tha fails tr re-bootin startin again. If that fails, well it works on mine! &##"&++^#V"&&!9~#fo#s#r+^"& !"&& !9~#fo#s#r+^"&*&%#^!" *&& x"*&"&&ó !"*&*& *.&#".&+^`i""ʠ !e *,&* &" &*"&| * &#" &*(&+"(&#**&2# ! `i"" !ù *&`i"" !9^#V!"^!9^#V`i~#fo#s#r+s!")"!2$DM`i$͓# `i DM )"!9N#F!"0&`i~`is#r! ^#V! ^#V! s#r!`in&"s! 9^#V`i~#fo#s#r+s!")"!2$DM`i~`i DM$ͅ#! DEFAULT = 1 @t is optional decimal track specifier 0 - 76 DEFAULT = 0 >s is optional deci HE fil int buffe startin a 'addr' Th firs HE fil loa addres correspond t 'addr al loa addresse ar Fil bloc o th buffe fro 'first throug 'last wit 'data' Al entrie bu 'data ar buffe relativ an i ification byte-by-byt o th buffe contents startin a 'addr' Come bac o th nex lin wit th buffe relativpa 4. Error Message Summary Invalid command! - Re-enter. DDISK did not understand you. Rress you entered for the command is outside the buffer. Not Enough Data! The command just entered requires more operal"* !9~#fo#s#r+^"&!"*&N *&h"N !9~#fo#s#r+^"&*& !",&u ! ",&u !",&u !",&**&!9*, !* &#" &* &!".$"0$! 9~2,$G+V+^+6"*$+N+V+^!.$w#< yl /w#` m !1$>^)|ځ gQ! ^!"!^"0&! ^*0&""0&! ^!"Q! ^#V!! s*0&)"!9N#F! "-%! ^!"ʅ!`is#r! s#r! s#r`i)"!9N#F! ^HT!! s#r`i! s#r!u"4&|:!! s#r!`in"mal start sector number 1 - 48 DEFAULT = 1 #c is optional decimal sector count 1 - 255 DEFAU offse accordingl int th buffer Bound checkin i don t assur th LOade progra i onl goin into the buffer.Hexadecima radix. DIsplay <,last> Display buffer contents, 16 per line, like DDT. Where: first o addres followe b th existin content a tha locatio an allow yo t ente tw digi hexadecima numbe oe-check command syntax. Disk Error CP/M returned a disk error code. File Not Found! Hex file specified wasnds. Check again. Formatter Errors IS NOT A VALID SELECTION Only 1 - 6 or ctrl-c &*& !9".&**&*&"& *&##"&++^#V".& "*& *&##"&++^#V"&*&!9".&s ^#c do oT s u] xf !,y s+=t Z! ~**$+"*$w!.$m #£ **$ +6-0123456789abcdef)"!9N#F`i~ `i#DM+^ " ! ! !! ^!"! ^#V`i^#VU#"2&*2&! ^#V! ^=*2&#!`in&"s!`is#r! s#r!! 9^#V!s*4&! s#r!&s# y–*"(*$"($ò)"!!~&! !:o&"~&s!"B&!~&DM!"+0 !%)- "&*. #'+/  $(,0&*&1#ʑ`i^! "+`i^! "3`i#DM`i~ʑ`i^!>"Q!"'e`i^!<"B!"'`i#DM^! "„`i^! !"!ͽͲA:$$$.SUB)"!"(!)"!con:CON:lst:LST:prn:PRN:pun:PUN:rdr:RDR:)"! 9^#'s#r!*')"!9^#V!1#8!9^#V! 2#B!"(!!9^#V)))$DM! ^#V! ^#V"!9s#r!! s! s!- !)"!9N#F͢!& ^ !- !!% s!)"!9^#V)))$DM! 9^#V! 9^#V! ^#V! ^)%^#V""(|!!$ ^! 9~#fo"!$ s{A`i!~#fo#s#r!)"! 9N#F! 9^#V"L(*L(+"L(#|ʛ`i^! "ʅ! !"(!"(!!! !"R(!*(|4!`i"R(!! ^#V"T(!)"!9^#V)))$^G"!oG""*&!"&! ^#V##^#V"Z(! ^#V^#V`i~#fos#r! ^#V##^#V! s#r`i^#V*b(ͅ#`i^#V*b("r! ^#V*`(##s#r÷*b())PY"Z(*Z(#=yʦ    Ϳ30_zW/=@ : >k Aڦ[\@haڦ{Ҧ`w# .ʆʟnͭ! 9F+N+V+^+~+ng!;!}O!;! /!++w x/!ɯE!~# xE!)"!9N#F`i^! "z!`i^! "ʂ!`i#DM#!}#|#!}|)#}|?>o&zo&|C#}|>o&|o&}/o|/g#}}o|gBK^#Vz~##yx####f##xs##~((((((8888B/%G/%L5%Q5%V5%[5%`5%e5%j;%o;RTN RET ; NMBRD: LD C,A ;SELECT DRIVE LD E,LOGVC ;SELECT DRIVE BUT IGNORE READ ERROR CALL SELDSK LD HL,MSGXX ;PRINT TY"ʇe`i"'`i#DM~`i^! "²`i^! "!`i#DM+sÌ*'*'|!*'t"'!*'͕"'*'"V!! 9^#V͕)"!$"'!"'û*'"'*'#"'*' 1#*'^#V!("ê!"(!!G%DM`iDM`i~# s`is!(! s#r!9^#V)"! 'DMï`i'DM`iD(͓#`i%~ç!"(!! 9^#V"D("!"(!*D(")"!DM!9^#V"F(*F(&^ *F($~*F($^!U#DM! 9~#fo͔#! 9^#VBK! 9^#V*F(ͷ- !!`i#DM+^!]! 9^#V)"! 9N#F! 9^#V"N(*N(+"N(#|`i#DM+^! 9^#Vü! 9^#V)"!9N#F!#*&¨*&!4š#4*&+"&}pʸʸo&"(*&)"!9!29^#VDM !9!DM- `i"!"(*`(##s#r! ^#V*Z(##s#r`i^#V*b(U#*Z(s#r*b(`is#r*`("Z(!! s#r`i`i*Z("!DM"!!`is#r!!w#o{o|g ʟͭw#&jz!|*¶ >?a{ 0:7!9^#V*$*(}|*$"$|!=!9}_|#W^!!"h(`i^!-"ʤ!!"h(`i#DM÷!`i^!+"ʷ!`i#DM!"f(`i^!%#^!"!*f( x"`i#DM+^"f(ý!*h(|"*f(K##fo}|>?o&}|>o&!#! 9^#V###~#fo ^#V#!##!$9~#fo s#r#%A%( 00000 @@@@@@@@@@@@@@@ @@@@@@@ @@@@@ PE CR WHEN READY MSG CALL MSGOT CALL CNSIN ;IF NOT CR THEN REPEAT CP CR JR NZ,REPTD AND A ;ELSE CLEAR FLAG & RETURN ?!!q *'!͍ !!͍ !! ! Î`i*&#"&+)B&s#r`i#DM~ʎ`i^! "|`i^! "ʋ!!9^#V`i^#V9 ! ^#V"'! 9^#V!"#" '* '"Z*'^*'s{Z!"(!* '"ʁ*'#^*'#s{!"(!  "D(*D( ! 9^#V!"+!!"q! 9^#V!"a!"n!"(- !Ô! 9^#V!" 9^#V`iU#ͺ""H(|`*H(! 9^#V`i*F(j"J(|`- *H(*J(U#ͪ"PYDM|]!`i*H(ͪ"PYDM`i! 9~#fo͓#ʫ`i!~#!!$ s!`i!~#fo+s#rͯ9!!"P(*P(͔#l*P(+"P(^!#i*P(#"P(l?*P(!$ s!!!)"!9N#F! ^#V+))"^(! 9^#Vu"\(|q*\(PY#q! 9^#V*^(͔#]*^(e! 9^#V*\( *\()"!9^ s#r`i*Z(DMõ)"!9^#V!"d(*d(##~#=!*Z(DMN! ^#VBK`i*d(͔#m! ^#V*d(͔#ʡ! ^#V`iͅ#ʞ*"(G" o&G" 2%:& _G" :%_!9M !9F+N+V+^+~+ngxk k k # V og!9V+^+~+ngw"*f(DM!99`i"|DM!99!!"`i~# x<"!9V"&~#]"!j"u"|DM!>} #,3<DMSY]bgnx@@@@ RET ; ; WORKING VARIABLES ; SYSWP: DW 0 ;ADDRESS POINTER RWOPV: DB 0 ;READ OR WRITE VECTOR MSGSV: DW 0 ;MESSAGE SAVE ADD`i#DM+sÎV!B&*&͒!Can't open file for redirection: $)"*-%"!DM`i 1#`i#DM+!9~#! ^#V*'s#r*'##^*'##s*'###^*'###s!8*'s#r*'!9^#V!9^#V!9^#V*'^#V"! 9!1#!(*"ʔ!"(- !!!! s#r!# s!$ s*D(!& s`i!9^#V!s#r! 9^#V!"#!% s!!9^#V!s#r! 9^#V!"! 9^#V`iU#! 9^#V`i*F(ͷʫ- `i- ! 9^#V)"!9N#Fͯ1#!! 9^#V!$ ^!!9^#V !""ʞ`i!~#fo#s#r!!$ s!)"!"R()"!9N#F!!*R(PY#!! ^#V*T(#D!!"("*(#V###ͺ"#"b(*Z("`(|¨!V("`("X("Z(*`(##^#VBK`i"`(! ^#VBK! ^#V`i#B! ^#V`i^#V))PY"B! ^#V*Z("d(PY͔#¡! ^#V*d(͓#¡E! ^#V*d(##s#r*d(! s#r`i"Z(!G"G"*&DM*&og!9N#F#^#Vkb6#> 6 #=>6ʉ #~ |!9á !9F+N+V+^+~+ng対ʳ #ë x w # ó w|!9~#fo # }!9^#V#N#F#nx s# ))҈" =€"}{_ʷ"|"|7g}o"{_ʷ")²"}{_ʷ"|g}o"|g}o|/g}/o|g}o|g}o|##}#|(???????????888((LEGAL THEN CONTINUE ILLG: LD HL,MSGSE ;PRINT SELECT ERROR MESSAGE CALL MSGOT JR REPTD ; EXITD: SCF ;SET FLAG TO CALLING R TRKNO: DB 0 ;TRACK NUMBER HOLD SECNO: DB 0 ;SECTOR NUMBER HOLD FFLAG: DB 0 ;FORMAT FLAG (DCM) RETADR: DW 0 ;MAIN PGM RETUR,0 !%)- "&*. #'+/  $(,0N ADDR STKSAV: DW 0 ;MAIN PGM STACK PTR ; ; 3740 SECTOR TRANSLATION ; TK0SL: DB 1,7,0DH,13H,19H,5 DB 0BH,11H,17H,3,9H,0E DW 2 ;TRACK OFFSET ; DS IDSSD+30H-$ ;LOCATE DCM BLK ; DB 6 ;SECTOR STAGGER (TRNS) SDFLG: DB 00000010B ;DISKETTE FLAGS ; DS IDSDD+30H-$ ;LOCATE DCM BLOCK ; DB 6 ;SECTOR STAGGER (TRNS) DDFLG: DB 00000110B ;DISKETTE FLAGS (FORMAT TYPE) ; D DB '4. Format system tracks only.',CR DB '5. Read system tracks image.',CR DB '6. Write system tracks image.',CR DB 'or uete',0 ; MSGXX: DB CR,LF DB 'Type RETURN when drive ' DRLTR: DB ' is ready. ',0 ; ; SINGLE DENSITY INJECTION MODULE FO,6 ;THEN WRITE 6 00H BYTES SRPT2: IN A,XPDSH LD A,ZEROS XOR C OUT WDDTA,A DJNZ SRPT2 IN A,XPDSH ;WRITE INDEX MARK LA IN A,XPDSH ;WRITE SIDE # LD A,0 XOR C OUT WDDTA,A IN A,XPDSH ;WRITE SECTOR # LD A,(HL) XOR C OUT WDDTA,A INCA,XPDSH ;WRITE DATA MARK LD A,0FBH XOR C OUT WDDTA,A LD B,128D ;WRITE 128 E5 BYTES SRPT7: IN A,XPDSH LD A,0E5H XOR C HL ;COUNT GAP 4 LENGTH JP SRPT9+OFFSET ; SS3740: DB 1,2,3,4,5,6,7,8D,9D,10D,11D,12D,13D,14D,15D,16D DB 17D,18D,19D,20D,2;THEN WRITE 12 00H BYTES DRPT10: IN A,XPDSH XOR A XOR C OUT WDDTA,A DJNZ DRPT10 LD B,3 ;WRITE GAP C2 - 3 F6H BYTES DP A1 - 3 F5H BYTES DRPT3: IN A,XPDSH LD A,0F5H XOR C OUT WDDTA,A DJNZ DRPT3 IN A,XPDSH ;WRITE ID MARK LD A,0FEH X DRPT4: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT4 LD B,8D ;THEN WRITE 8 00H BYTES DRPT5: IN A,XPDSH XOR A FH DB 15H,2,8H,0EH,14H,1AH DB 6,0CH,12H,18H,4,0AH DB 10H,16H ; ; JADE SINGLE DENSITY IDENTITY SECTOR ; IDSSD: DB 'Ja (TYPE OF FORMAT) DS IDSSD+SECSZ-$ ; ; JADE DOUBLE DENSITY IDENTITY SECTOR ; IDSDD: DB 'Jade ;DD Double density format 'S IDSDD+SECSZ-$ ;EXTEND TO FULL SECTOR ; ; MESSAGES ; MSGBG: DB CR,LF,'Jade DD Disk Formatter',CR DB 'Ver 1.0 by Girvinse ctrl-C for return to main menu.',CR,LF DB 'Enter function number: ',0 ; MSGSE: DB CR,LF LTRSE: DB 'IS NOT A VALID SELECTRMATTER ; ; DS ($+100H) MOD 100H ;START AT NEXT PAGE BOUNDARY ; FT3740: EQU $ NAME: EQU $ OFFSET: EQU FMTEA-NAME ;DETERD A,0FCH XOR C OUT WDDTA,A LD B,26D ;WRITE GAP 1 - START WITH 26 FFH BYTES SRPT3: IN A,XPDSH LD A,ONES XOR C OUT WD HL IN A,XPDSH ;WRITE SECTOR SIZE LD A,0 ;(128) XOR C OUT WDDTA,A IN A,XPDSH ;WRITE CRC WORD (2 BYTES WRITTEN TO DISK)C OUT WDDTA,A DJNZ SRPT7 IN A,XPDSH ;WRITE CRC WORD LD A,0F7H XOR C OUT WDDTA,A LD B,27D ;WRITE GAP 3 - START WITH1D,22D,23D,24D,25D,26D ; ; DOUBLE D DOUBLE DENSITY INJECTION MODULE ; DS ($+100H) MOD 100H ;START AT EVEN PAGE ; FTJ48DRPT11: IN A,XPDSH LD A,0F6H XOR C OUT WDDTA,A DJNZ DRPT11 IN A,XPDSH ;WRITE INDEX MARK LD A,0FCH XOR C OUT WDDTAOR C OUT WDDTA,A IN A,XPDSH ;WRITE TRACK # IN A,WDTRK OUT WDDTA,A IN A,XPDSH ;WRITE SIDE # XOR A XOR C OUT WDDTA XOR C OUT WDDTA,A DJNZ DRPT5 LD B,3 ;WRITE GAP A1 - 3 F5H BYTES DRPT6: IN A,XPDSH LD A,0F5H XOR C OUT WDDTA,A DJde DD Single density format ' ; DS IDSSD+20H-$ ; DW 26D ;SECTORS PER TRACK DB 3 ;BLOCK SHIFT FACTOR DB 7 ;BLOCK MASK  ; DS IDSDD+20H-$ ; DW 48D ;SECTORS PER TRK DB 4 ;BLOCK SHIFT FACTOR DB 00001111B ;BLOCK MASK DB 1 ;NULL MASK DW 2 Herr',CR DB '(c) 1981 GRH Electronics, Cupertino, CA',CR,0 ; MSGFL: DB CR,LF,'****** Functions List ******',CR DB '1. ION',0 ; MSGFD: DB CR,LF DB 'Write format on drive A-D (RETURN to reselect): ',0 ; MSGRS: DB CR,LF DB 'Read system from MINE ADDR OF OFFSET DB 'FORMAT!' DB 'S' LD HL,SS3740+OFFSET LD E,26D ;SET # SECTORS BG3740: LD B,40D ;WRITE PREAMBLE - DTA,A DJNZ SRPT3 RP3740: LD B,6 ;THEN WRITE END OF GAP 3 - 6 00H BYTES SRPT4: IN A,XPDSH LD A,ZEROS XOR C OUT WDDTA,A  LD A,0F7H XOR C OUT WDDTA,A LD B,11D ;WRITE GAP 2 - START WITH 11 FFH BYTES SRPT5: IN A,XPDSH LD A,ONES XOR C OU 27 FFH BYTES SRPT8: IN A,XPDSH LD A,ONES XOR C OUT WDDTA,A DJNZ SRPT8 DEC E ;# SECTORS -1 JP NZ,RP3740+OFFSET ;IF : EQU $ DOFSET: EQU FMTEA-FTJ48D ;DETERMINE ADDR OFFSET DB 'FORMAT!D' LD HL,SSJ48D+DOFSET LD E,48D ;SECTOR COUNT BGJ48D:,A LD B,32D ;WRITE GAP 1 - START WITH 32 4EH BYTES DRPT12: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT12 RPJ48D:,A IN A,XPDSH ;WRITE SECTOR # LD A,(HL) XOR C OUT WDDTA,A INC HL IN A,XPDSH ;WRITE SECTOR SIZE (128) LD A,0 XOR NZ DRPT6 IN A,XPDSH ;WRITE DATA MARK LD A,0FBH XOR C OUT WDDTA,A LD B,128D ;WRITE 128 E5 BYTES DRPT7: IN A,XPDSH LD DB 0 ;NULL MASK DW 242D ;DISK SIZE -1 DW 63D ;DIRECTORY MAXIMUM DB 11000000B ;ALLOC 0 DB 0 ;ALLOC 1 DW 16D ;CHECK SIZ24D ;DISK SIZE -1 DW 63D ;DIRECTORY MAXIMUM DB 10000000B ;ALLOC 0 DB 0 ;ALLOC 1 DW 16D ;CHECK SIZE DW 2 ;TRACK OFFSET Format Jade Double Density 8',22H,CR DB '2. Format Jade Single Density 8',22H,CR DB '3. Format IBM 3740 Standard 8',22H,CR drive: ',0 ; MSGWS: DB CR,LF DB 'Write system to drive (RETURN to re-select): ',0 ; MSGNC: DB CR,LF DB 'Transfer IncomplSTART WITH 40 FFH BYTES SRPT1: IN A,XPDSH ;WAIT FOR DATA REQ LD A,ONES XOR C OUT WDDTA,A ;WRITE DATA DJNZ SRPT1 LD B DJNZ SRPT4 IN A,XPDSH ;WRITE ID MARK LD A,0FEH XOR C OUT WDDTA,A IN A,XPDSH ;WRITE TRACK # IN A,WDTRK OUT WDDTA,T WDDTA,A DJNZ SRPT5 LD B,6 ;THEN WRITE 6 00H BYTES SRPT6: IN A,XPDSH LD A,ZEROS XOR C OUT WDDTA,A DJNZ SRPT6 IN ANY LEFT THEN REPEAT LD HL,0 ;COUNT = 0 SRPT9: IN A,XPDSH LD A,ONES ;WRITE GAP 4 UNTIL INTERRUPT XOR C OUT WDDTA,A IN LD B,80D ;WRITE PREAMBLE - START WITH 80 4EH BYTES DRPT1: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT1 LD B,12D  LD B,8D ;THEN WRITE END OF GAP 3 - 8 00H BYTES DRPT2: IN A,XPDSH XOR A XOR C OUT WDDTA,A DJNZ DRPT2 LD B,3 ;WRITE GAC OUT WDDTA,A IN A,XPDSH ;WRITE CRC WORD LD A,0F7H XOR C OUT WDDTA,A LD B,22D ;WRITE GAP 2 - START WITH 22 4EH BYTES A,0E5H XOR C OUT WDDTA,A DJNZ DRPT7 IN A,XPDSH ;WRITE CRC WORD LD A,0F7H XOR C OUT WDDTA,A LD B,24D ;WRITE GAP -0 !%)- "&*. #'+/  $(,03 - START WITH 24 4EH BYTES DRPT8: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT8 DEC E ;IF SECTORS LEFT THEN REPEAD,48D ; END  TITLE DEBUG 26 DEC 80 10:20 ;************************************************************* ; ; This DEBUG program tory or ; a particular block or blocks to be read from or written ; to a tape. ; ; NOTE: This program does use the I/O OCTMSK: EQU 00000111B HEXMSK: EQU 00001111B CTLMSK: EQU 01100000B CUCMSK: EQU 01000000B ; ; ASCII CONSTANTS ; LF: EQU ONE: EQU 1 TEN: EQU 10D WRTEN: EQU 1 PRVIEW: EQU -8D DMPCNT: EQU 9D OPNMOD: EQU 1 REGMOD: EQU -1 FLGSP: EQU 2 REGCNT:  CO CRLF: JP CRLFOT MLTSPC: JP MSPACE EDITOR: JP EDITR ; BPVECT: DW BPVADR ;RESTART 56D BREAKPOINT VECTOR LOC'N ABOVCT: DW 1ST TIME THROUGH, CARRY WAS RLA ;0, MAKING THE 1ST DIGIT MAX OF 3 PUSH AF ;SAVE IT AND OCTMSK ;MASK OUT UPPER BITS ADDONVERT TO ASCII CALL CONOUT POP AF ;RESTORE # RET ; ; BREAKPOINT 16 BIT BINARY TO ASCII CONVERSION SUBR'N ; PASS I'NONE' CALL EDITOR RET ; ; TAB PER BASE SUBR- COMPUTES PROPER NUMBER OF LEADING ; SPACES TO VALUE. ; EXIT - SPAT JP NZ,RPJ48D+DOFSET LD L,E LD H,L DRPT9: IN A,XPDSH LD A,4EH ;WRITE GAP 4 - 4EH BYTES UNTIL INTERRUPT XOR C OUT Wis a stand-alone program to allow ; programs to be loaded and debugged by modification & ; by use of breakpoints. It is si proms. ; ;************************************************************* FORM ; ; EXTERNAL ROUTINES ; REWIND: EQU 0F41 0AH FORMF: EQU 0CH CR: EQU 0DH AESC: EQU 1BH ASPACE: EQU 20H AMINUS: EQU 2DH APEROD: EQU 2EH ;'.' ASLASH: EQU 2FH ;'/' EQU 3 RPSP: EQU 2 JMP: EQU 0C3H RST7: EQU 0FFH NOBRK: EQU -1 RCNT: EQU 8D SETMSK: EQU 1 BUFMAX: EQU 80D ENTMOD: EQU -1  ABORT ;SYSTEM RETURN VECTOR SYSSTK: DW ISTACK ;SYSTEM STACK POINTER ; ; CONVERT BINARY BYTE IN A TO ASCII & DISPLAY IT ; AZERO ;CONVERT TO ASCII CALL CONOUT POP AF ;RESTORE # RET ;LAST TIME,RETURNS TO CALLING PGM ; HXNUMB: POP AF ;RESTORE N 16 BIT VALUE IN HL. IF ZERO, 'NONE IS ; DISPLAYED. ; CHKNON: LD A,L ;IF HL=FFFFH THEN OUTPUT 'NONE' (NO ; BREAKPOINCE COUNT IN A ; OHTAB: LD A,(NUMBAS) ;COMPUTE SPACE COUNT CPL ADD 3 PUSH AF CALL MLTSPC ;OUTPUT SPACES POP AF RET DDTA,A INC HL ;COUNT NUMBER OF GAP 4 BYTES JR DRPT9 ; SSJ48D: DB 1,5,9D,13D,17D,21D,25D,29D,33D,37D,41D,45D DB 2,6,10D,1milar to the PHIMON ; DTx program, but allows I/O ports to be examined/loaded, ; and display mode to be changed while in tEH WRITF: EQU 0F415H SETDRV: EQU 0F40CH STOP: EQU 0F418H SETDMA: EQU 0F403H SETBID: EQU 0F406H SETCNT: EQU 0F409H READF: AZERO: EQU '0' AEIGHT: EQU '8' ANINE: EQU '9' COLON: EQU ':' SCOLON: EQU ';' ALT: EQU '<' AEQUAL: EQU '=' AGT: EQU '>' A; ; COMPILE TIME PARAMETERS ; BPVADR: EQU 0E016H ABORT: EQU 0 ISTACK: EQU 0C080H ; FORM ;**************************** PRNUMB: OR A ;CLEAR CARRY PUSH AF LD A,(NUMBAS) ;IF BASE FLAGE=0 THEN HEX OUTPUT OR A JR Z,HXNUMB POP AF ;RESTORE # # RLA ;PUT MSB IN CARRY CALL PRHXDG PRHXDG: RLA ;PUT MSD IN LSD RLA RLA RLA PUSH AF ;SAVE IT AND HEXMSK ;MASK OT) AND H INC A JR Z,NONE ; ; OUTPUT 16 BIT NUMBER IN HL TO CONSOLE DEVICE ; PRTDBL: LD A,H ;DISPLAY H CALL PRNUMB  ; ; DUMP LOCATION SUBROUTINE ; CONTENTS OF HL ARE DISPLAYED FOLLOWED BY A '/' AND ; FOLLOWED BY THE CONTENTS OF THE L4D,18D,22D,26D,30D,34D,38D,42D,46D DB 3,7,11D,15D,19D,23D,27D,31D,35D,39D,43D,47D DB 4,8D,12D,16D,20D,24D,28D,32D,36D,40D,44he program and ; search through memory for a particular string of bytes. ; It also allows Files to be loaded via the direcEQU 0F412H MSPACE: EQU 0FC15H CRLFOT: EQU 0FC1BH CO: EQU 0FC09H CI: EQU 0FC03H EDITR: EQU 0FC12H ; FORM ; ; MASKS ;X: EQU 'X' AY: EQU 'Y' LCASE: EQU 'a' LCOFFS: EQU 20H CESC: EQU AESC+CUCMSK ; ; CONSTANTS ; HOFSET: EQU 7 ZERO: EQU 0********************************* ; ORG 100H ; DEBUG: JP DTX ;DEBUG VECTOR ; ; I/O VECTORS ; CONIN: JP CI CONOUT: JP CALL PRDIG ;CONVERT 1ST DIGIT TO ASCII OCTAL CALL PRDIG ;CONVERT 2ND DIGIT PRDIG: RLA ;ROTATE MSD TO LSD RLA ;NOTE, THEUT UPPER BITS CP TEN ;IF NOT ALPHA THEN OK AS IS JR C,NTALPH ADD HOFSET ;ELSE CONVERT 10-15 TO 'A-F' NTALPH: ADD AZERO ;C ; ; OUTPUT 8 BIT VALUE IN L TO CONSOLE DEVICE ; PRTSGL: LD A,L ;OUT L CALL PRNUMB RET ; NONE: LD HL,NONMSG ;DISPLAY OCATION POINTED TO ; BY HL ; DMPLOC: CALL PRTDBL ;DISPLAY HL LD A,ASLASH CALL CONOUT LD A,(HL) ;FETCH DATA CALL PR.0 !%)- "&*. #'+/  $(,0NUMB ;DISPLAY CONTENTS RET ; ; NONMSG: DB 'NONE ',0 FLGTAB: DB 'S',80H,'Z',40H,'H',10H,'P',4,'N',2,'C',1,0 REGTAB: DB '-7" THEN TEST FOR COMMAND JR NC,NOTDIG SUB AZERO JR C,NOTDIG LD B,A ;SAVE DIGIT POP AF ;RESTORE FLAGS ADD HL,HL ;SHIR NC,NTHDIG CP ANINE+1 ;ELSE IF <= '9' THEN OK JR C,NALPHA SUB HOFSET ;ELSE CONVERT 'A-F' TO 10-15 NALPHA: SUB AZERO ;IF TIALIZE LD (DSPMOD),A LD (MODBRK),A LD SP,(SYSSTK) ;SET STACK LD HL,NOBRK ;CLEAR PENDING BREAKPOINT LD (RETADR),HL CL ;POINT TO JP ADDR IN TABLE JR Z,FOUND INC HL DJNZ DTXNXT END: LD A,(DSPMOD) ;TEST PRESENT MODE OR A JP Z,CLEAR ;CLOE LD A,(HL) ;OUTPUT CURRENT VALUE OF LOCATION CALL PRNUMB DEC C ;DUMP COUNT -1 JR Z,ENDUMP INC HL ;ADVANCE POINTER USRSTK),SP ;SAVE USER STACK PTR LD SP,DTXSTK ;SET BREAKPOINT STACK PUSH HL ;SAVE REGS PUSH DE PUSH BC PUSH AF LD HL Z,MAINST LD HL,ALTMSG ;DISP 'ALTERNATE' CALL EDITOR JR FINSET ; MAINST: LD HL,MANMSG ;DISP 'MAIN' CALL EDITOR FINSETNEXT FLAG CHAR AND (HL) ;MASK OUT UNWANTED FALGS LD A,AZERO JR Z,FLAG0 ;IF MASKED FLAG =0, OUTPUT '0' INC A ;IF MASKEUP: INC HL ;POINT TO NEXT REGISTER DATA LD D,(HL) ;SAVE LOW REG OF PAIR INC HL CALL OHTAB LD A,(HL) ;OUTPUT HIGH REG SP PUSH AF CALL MLTSPC PUSH IX ;DISP IX VALUE POP HL CALL OHTAB CALL PRTDBL POP AF CALL MLTSPC PUSH IY ;DISPMSG ;DISP 'BREAKPOINT:' CALL EDITOR LD HL,(ADRBRK) ;DISP BP ADDRESS CALL CHKNON ;IF BP ADDR =FFFFH, DISP 'NONE' LD HL,RFACBEDLH' ; ; GET NUMBER IN DE UNTIL NON-BASE CHAR ENCOUNTERED ; WXIT - LAST CHAR IN B, NUMBER IN DE ; GETNUM: LD HL,ZEFT OLD DIGITS OVER ONE DIGIT ADD HL,HL ADD HL,HL PUSH AF ;SAVE FLAGS LD A,B ;RESTORE DIGIT ADD L ;PUT NEW DIGIT IN DAT<'0' THEN NOT DIGIT JR C,NTHDIG ADD HL,HL ;SHIFT OLD DIGIT OVER 1 DIGIT ADD HL,HL ADD HL,HL ADD HL,HL ADD L ;ADD NEWEAR: CALL PRMSGS ;DISPLAY BREAKPOINT,RETURN ADDRS IN: CALL GETNUM ;INPUT NUMBER,COMMAND LD HL,DTXTAB ;SET COMMAND TABLE PTR SED MODE JP M,REGSTR ;REGISTER DISPLAY MODE DUMP1: LD HL,(LOCATN) ;FETCH MEM LOCATION POINTER DUMP2: LD (LOCATN),HL ;SET LOC CALL CRLF JP NXTDMP ; ENDUMP: LD A,AEQUAL ;OUTPUT '=' CALL CONOUT LD A,OPNMOD ;SET MEMORY OPENED MODE LD (DSPMOD),A ,(USRSTK) ;GET RETURN ADDR LD A,(HL) INC HL LD H,(HL) LD L,A DEC HL LD (RETADR),HL ;SET POINTER XOR A ;SET REGISTE: LD HL,FLGMSG ;DISP 'FLAGS:' CALL EDITOR LD HL,ZERO LD A,(REGMOD AND 0FFH) ;SET REGISTER DISPLAY MODE LD (DSPMOD),A AD FLAG =1, OUTPUT '1' FLAG0: CALL CONOUT LD A,FLGSP ;OUTPUT SPACES BETWEEN FLAGS CALL MLTSPC JR FLAGUP ; REG2: PUSH HLOF PAIR CALL PRNUMB CALL OHTAB LD A,D ;OUTPUT LOW REG OF PAIR CALL PRNUMB DEC C ;COUNT -1 JR NZ,REGUP ;NXT REG PAI IY VALUE POP HL CALL OHTAB CALL PRTDBL CALL CRLF JP IN ;RETURN TO INPUT MODE ; ; CHKMOD SUBROUTINE TESTS IF A BPETMSG ;DISP 'RETURN:' CALL EDITOR LD HL,(RETADR) ;DISP RET ADDRESS CALL CHKNON ;IF RET ADDR =FFFFH, DISP 'NONE' CALL CRLRO ;CLEAR ACCUMULATOR LD A,(NUMBAS) ;IF HEX BASE THEN INPUT HEX OR A JR Z,HEXIN ;0= HEX, 1= OCTAL LD HL,ZERO LD C,H ;RA REG LD L,A LD C,WRTEN ;SET WRITE ENABLE JP DIGUP ;NEXT CHAR ; HEXIN: CALL CONIN CP LCASE ;IF NOT LOWER CASE THEN OK  DIGIT LD L,A LD C,WRTEN ;SET WRITE ENABLE JR HEXIN ; ; NOT HEX DIGIT FALLOUT. MUST BE COMMAND/INVALID CHAR ; NOTDIG: LD A,B ;B STILL HAS LAST CHAR INPUTTED AND CTLMSK ;IF NOT CONTROL CHAR THEN OK AS IS LD A,B JR NZ,NOTC OR CUCMSK ;ELSE ATION POINTER LD DE,PRVIEW ;OUTPUT PREVIOUS LOCATIONS ADD HL,DE PUSH HL ;SAVE POINTER CALL PRMSGS ;DISP. BP, RET POP JP IN ; ; COMMAND FOUND - GET ADDR FROM TABLE & GO TO IT ; FOUND: PUSH DE LD E,(HL) ;GET ADDR INC HL LD D,(HL) ER SET POINTER TO MAIN LD (REGSET),A INC A ;SET IN BP FLAG LD (MODBRK),A ; ; REGISTER DISPLAY ROUTINE ; REGSTR: CALLDD HL,SP ;FETCH SP VALUE LD DE,FLGTAB ;SET TABLE POINTER FLAGUP: LD A,(DE) ;FETCH FLAG CHAR INC DE ;POINTER +1 OR A ; ;PUSH STACK POINTER VALUE LD HL,REGMSG ;DISP 'REGISTERS:' CALL EDITOR POP HL ;POP STACK POINTER VALUE & INC TO A INC HR ; CALL OHTAB LD A,I ;OUTPUT INTERRUPT REG CALL PRNUMB LD HL,STKMSG ;DISP 'STACK PTR' CALL EDITOR CALL OHTAB PU HAS TAKEN PLACE & ; IF SO,RETURNS. IF NOT, IT RETURNS TO THE INPUT MODE. ; CHKMOD: LD A,(MODBRK) OR A RET NZ ;BP =1F CALL CRLF RET ; ; REGISTERS ; DATA: DB 0 ;STORAGE FOR DATA REPLACED BY BP DSPMOD: DB 0 ;0 =DISPLAY CLOSED, 1 =MEMORYESET WRITE ENABLE FLAG PUSH AF ;SAVE MODE DIGUP: CALL CONIN ;INPUT DATA LD B,A CALL CONOUT LD A,B CP AEIGHT ;IF <> "0AS IS JR C,UC SUB LCOFFS ;ELSE CONVERT TO UPPER CASE UC: LD B,A CALL CONOUT LD A,B CP 'F'+1 ;IF >'F' THEN NOT HEX J POP AF ;COMPENSATE FOR SPLIT OCTAL RR H NTHDIG: EX DE,HL ;SAVE DATA REG RET ; ; MAIN PROGRAM START ; DTX: XOR A ;INIMAKE CTRL CHAR INTO UPPER CASE NOTC: LD B,(HL) ;GET TABLE ELEMENT COUNT DTXNXT: INC HL ;PTR CP (HL) ;TEST FOR MATCH INC HL HL LD C,DMPCNT ;SET COUNT NXTDMP: CALL PRTDBL ;OUTPUT ADDR CALL SPACE LD A,ASLASH ;OUTPUT '/' CALL CONOUT CALL SPACX DE,HL POP DE XOR A JP (HL) ;SERVICE COMMAND ; ; THIS ROUTINE IS ENTERED UPON BREAKPOINT OCCURRANCE ; ENCBRK: LD ( PRMSGS ;DISP BP, RET LD HL,SETMSG ;DISP 'REG SET:' CALL EDITOR LD A,(REGSET) ;DETERMINE PRESENT REGISTER SET OR A JRTEST FOR END OF TABLE JR Z,REG2 CALL CONOUT ;OUTPUT FLAG CHAR FROM TABLE LD A,(DE) ;FETCH FLAG MASK INC DE ;POINT TO L ;VALUE CALL OHTAB LD A,(HL) ;OUTPUT ACCUMULATOR VALUE FROM STACK CALL PRNUMB LD C,REGCNT ;SET REGISTER PAIR COUNT REGSH AF ;SAVE SPACE COUNT LD HL,(USRSTK) INC HL ;CORRECT STACK PTR TO VALUE AT BREAK INC HL CALL PRTDBL POP AF ADD RP POP HL ;RESTORE STACK BALANCE JP END ; ; PRMSGS SUBROUTINE OUTPUTS BP & RETURN HEADINGS & VALUES ; PRMSGS: LD HL,BRK DISPLAY ; ;MODE, - =REGISTER DISPLAY MODE MODBRK: DB 0 ;0 =NO BP OCCURRED, 1 =BP OCCURRED REGSET: DB 0 ;0/0 !%)- "&*. #'+/  $(,0 =MAIN SET, 1 =ALTERNATE SET ; ; MESSAGES ; BRKMSG: DB FORMF,'BREAKPOINT:',0 RETMSG: DB 8DH,'RETURN:',0 SETMSG: DB 'REG SDB AMINUS DW MINUS DB 'L' DW LOW1 DB 'C' DW CONTIN DB 'G' DW GO DB 'B' DW BREAK DB 'R' DW REGCOM DB 'D' SCII CHAR IN MEMORY CMD ; ASCII: CALL CONIN ;GET CHAR ; ; LOAD LOCATION WITH 0 CMD ; ZEROC: LD E,A ;WHEN THIS ROUTINE E NEXT JP DUMP2 ;UPDATE DISPLAY & RET TO INPUT MODE ; ; CLOSE THIS LOCATION & OPEN PREVIOUS LOCATION CMD ; MINUS: LD HL,(LOP AF POP BC POP DE POP HL LD SP,(USRSTK) RET ; ; EXECUTE FROM DATA CMD ; GO: EX DE,HL ;FETCH ADDR LD A,(MODBRC HL LD E,(HL) LD (HL),[ENCBRK AND 0FFH] INC HL LD D,(HL) LD (HL),[ENCBRK SHR 8] LD (OLDVCT),DE POP DE JP END ;ORE COMMAND JP REGSTR ; ; REGISTER DEPOSIT COMMAND ; DEPSIT: CALL CHKMOD ;IF NOT IN BP, IGNORE CMD LD HL,ZERO ;FETCH JR NZ,NOTIY POP IY ;POP DATA INTO IY JP END ; NOTIY: POP BC ;POP DATA INTO BC CP 'I' ;IF NOT INTERRUPT REG THEN EXIT  CHKMOD ;IF NOT IN BP, IGNORE POP AF ;POP REGISTERS POP BC POP DE POP HL EX AF,AF' ;SWAP REGISTERS EXX PUSH HL  DS 64D ;DEBUG STACK DTXSTK: EQU $ NUMBAS: DB ZERO ;DISPLAY NUMBER BASE SAVE ; ; SET HEX MODE COMMAND ; HEXMC: LD A,ZE ; OUTPUT DATA TO PORT COMMAND ; OUTDC: LD C,E OUTDC1: PUSH BC CALL CRLF LD A,C ;ECHO PORT # CALL PRNUMB LD A,AEQUINPUT DONE CP ASPACE JR NZ,NOTNUM LD A,E ;LOAD DATA TO BUFFER LD (HL),A INC HL LD (HL),ZERO ;SET END FLAG LD A,(ET: ',0 ALTMSG: DB 'Alternate',CR,LF,0 MANMSG: DB 'Main',CR,LF,0 FLGMSG: DB 'FLAGS: ',0 REGMSG: DB CR,LF,'REGISTERS:',CR,LF  DW DEPSIT DB CESC DW ESCAPE DB 'E' DW EXXCHG DB 'H' DW HEXMC DB 'Q' DW OCTMC DB 'I' DW INDATC DB 'P' DNTERED, A=0 LD C,WRTEN ;SET WRITE ENABLE ; ; CLOSE THIS LOCATION & OPEN NEXT LOCATION CMD ; SPCBAR: LD A,(DSPMOD) ;CHECKOCATN) DEC HL ;CLOSE THIS ONE & OPEN PREVIOUS ONE JP DUMP2 ; ; CLOSE THIS LOCATION & OPEN LOCATION SPECIFIED BY LOW ; K) ;IN BP ? OR A JR NZ,GO1 JP (HL) ; ; SET BREAKPOINT CMD ; BREAK: CALL ERSBRK ;REMOVE ANY PREVIOUS BP DEC C ;TES ; ERASE BREAKPOINT SUBROUTINE ; ERSBRK: LD HL,(ADRBRK) ;FETCH BP ADDRESS LD A,(DATA) ;FETCH PGM DATA LD (HL),A ;RESTORSP ADD HL,SP PUSH DE ;PUSH DATA EX DE,HL CALL CONIN ;INPUT DATA AND (NOT LCOFFS) LD C,RCNT ;SET TABLE COUNT LD  JP NZ,NOTINT LD A,C ;ELSE LOAD I REG WITH VALUE LD I,A JP END ; NOTINT: CP 'S' ;IF NOT STACK PTR THEN EXIT JP NZ,E ;PUSH NEW REGS PUSH DE PUSH BC PUSH AF LD A,(REGSET) ;INVERT REGISTER SET FLAG XOR SETMSK LD (REGSET),A JP END ;RO LD (NUMBAS),A JP END ; ; SET OCTAL MODE COMMAND ; OCTMC: LD A,ONE LD (NUMBAS),A JP END ; ; DISPLAY INPUT PORAL CALL CONOUT CALL SPACE CALL GETNUM LD A,B ;SAVE LAST CHAR POP BC OUT (C),E CP ASPACE ;IF LAST CHAR = SPACE THEBUFCNT) INC A LD (BUFCNT),A CP BUFMAX ;IF BUFFER FULL THEN ERROR JR NZ,INLOOP LD HL,BUFERR CALL EDITOR CALL CONIN DB 82H,'A',83H,'B',83H,'C',83H,'D',83H,'E',83H DB 'H',83H,'L',83H,'I',CR,LF,0 STKMSG: DB CR,LF,82H,'STACK PTR',82H,'X INDEXW OUTDC DB 'S' DW SERMC DB 'Y' DW YANKC DB 'W' DW WRTC DB 23H ;'#' DW SETDC DB 'F' DW LDFILC ; DS 6 ;COMM MODE OR A JP Z,CLEAR ;NOTHING OPENED JP M,REGSTR ;REGISTER MODE, NOT MEMORY LD HL,(LOCATN) ;FETCH OPENED LOCATION DE BYTE OF DATA CMD ; LOW1: LD HL,(LOCATN) LD L,E JP DUMP2 ; ; CONTINUE FROM BP CMD ; CONTIN: CALL CHKMOD ;IN BP? LDT & RESET WRITE ENABLE FLG JP NZ,END LD A,(DE) ;SAVE BP PGM DATA LD (DATA),A EX DE,HL ;SET BP LOCATION TO RST 48D LDE ORIGINAL PGM DATA LD HL,NOBRK ;CLEAR BREAKPOINT ADDR LD (ADRBRK),HL PUSH HL PUSH DE LD DE,(OLDVCT) LD HL,(BPVECT) HL,REGTAB ;SET TABLE POINTER DEPSUP: CP (HL) ;IF MATCH THEN FOUND JR Z,DEPOS2 INC HL ;POINTER +1 INC DE ;REGISTER CONTND LD (USRSTK),BC ;SET USER STACK PTR JP END ; DEPOS2: POP BC ;POP DATA INTO BC LD A,C LD (DE),A ;PUT DATA INTO REGIS ; REGISTERS ; LOCATN: DW 0 ;OPENED MEMORY LOCATION POINTER ADRBRK: DW NOBRK ;BREAKPOINT ADDR SAVE (-1=NONE) RETADR: DW NOBT DATA COMMAND ; INDATC: LD C,E ;SET PORT CALL CRLF ;START NEW LINE WITH PORT # LD A,E CALL PRNUMB IN A,(C) ;GET DAN REPEAT JR Z,OUTDC1 JP END ; ; SEARCH MEMORY COMMAND ; SERMC: LD (TADDR),DE SERST: LD HL,BUFFER ;SET BUFFER ADDR X ;PROMPT FOR RETRY AND 5FH ;CONVERT LC CP 'Y' JR Z,SERST JP END ; NOTNUM: LD DE,BUFFER LD HL,(TADDR) ;SET UP TO CO',83H,'Y INDEX',CR,LF,0 ; DTXTAB: DB 22D DB 'O' DW OPEN DB 'A' DW ASCII DB 'Z' DW ZEROC DB ASPACE DW SPCBAR AND EXPANSION ; ; OPEN LOCATION FOR EXAMINATION COMMAND ; OPEN: EX DE,HL ;PUT DATA IN MEM POINTER JP DUMP2 ; ; LOAD AC C ;TEST WRITE ENABLE FLAG JR NZ,SKIPIN ;NOT ENABLED LD (HL),E ;CHANGE MEMORY SKIPIN: INC HL ;CLOSE THIS LOCATION & OPEN HL,(RETADR) ;FETCH RETURN ADDRESS GO1: EX DE,HL LD HL,(USRSTK) ;BACK UP RETURN TO RST 7 LD (HL),E INC HL LD (HL),D P (HL),RST7 LD (ADRBRK),HL ;SET BP ADDRESS POINTER LD HL,(BPVECT) ;SET BREAKPOINT RESTART VECTOR LD (HL),JMP PUSH DE IN LD (HL),E INC HL LD (HL),D POP DE POP HL RET ; ; DISPLAY REGISTER CMD ; REGCOM: CALL CHKMOD ;IF NOT IN BP, IGNENTS POINTER +1 DEC C ;COUNT -1 JR NZ,DEPSUP CP AX JR NZ,NOTIX POP IX ;POP DATA INTO IX JP END ; NOTIX: CP AY TER ON STACK JP END ; ; ESCAPE CMD ; ESCAPE: LD HL,(ABOVCT) JP (HL) ; ; EXCHANGE REGISTER SETS CMD ; EXXCHG: CALLRK ;BREAKPOINT RETURN ADDR SAVE OLDVCT: DW ZERO ;OLD RST7 VECTOR ADDR SAVE USRSTK: DW ZERO ;STACK POINTER SAVE UPON BREAKPOINTTA PUSH AF LD A,AEQUAL CALL CONOUT CALL SPACE POP AF CALL PRNUMB CALL CONIN CP ASPACE JR Z,INDATC JP END ; OR A ;SET CHAR COUNT LD (BUFCNT),A INLOOP: CALL CRLF PUSH HL CALL GETNUM POP HL LD A,B ;IF LAST CHAR NOT SPACE THEN MPARE LD BC,ZERO LD A,(DE) CPIR JP PO,NOTFND ;1ST BYTE NOT FOUND IN ENTIRE ; MEMORY LD (TADDR),HL ;SAVE NEXT LOC00 !%)- "&*. #'+/  $(,0ATION LD A,(BUFCNT) ;IF COUNT -1 =0 THEN DONE LD B,A SERLP: DEC B JR Z,DONE INC DE LD A,(DE) ;IF NEXT CHAR IN STRINGFMAX TADDR: DW ZERO BUFCNT: DB ZERO ; BUFERR: DB CR,LF,'TOO MANY ENTRIES, RETRY? (Y/N) ',0 NTFM: DB CR,LF,'SEQUENCE NOT FOUASE & UCASE ; ; ASCII CHARACTER VALUES ; CTRLX: EQU 18H ESC: EQU 1BH DEL: EQU 7FH ; ; MASKS ; CTRLMK: EQU 01100000T NEXT CHAR CP CASELO ;IF LOWER CASE THEN MAKE UPPER JR C,PCUC CP CASEHI JR NC,PCUC SUB CHAROF PCUC: CP '_' ;SWAP D Z,CONT LD (HL),A ;PUT CHAR IN BUFFER JR NXTCHR ; RUBOUT: INC B ;IF NO ENTRIES THEN IGNORE DEC B JR Z,CONT DEC B ; LNLONG: LD HL,TOOLNG ;PRINT TOO LONG MESSAGE CALL EDITOR POP HL JR LININ ; TOOLNG: DB 'LINE TOO LONG',CR,0 ; ; LINA,'O' CP H JR NZ,NOMCB LD A,'G' CP L JR Z,MCB LD A,'A' CP L JR NZ,NOMCB MCB: LD BC,(BLOCK) INC BC CALL SETB NAME: DB ' ' EX: DB ' ' LENG: DW 0 ;FILE LENGTH IN BLOCKS BLOCK: DW 0 MAP: DW 0 ;MEMORY ADDRESS PTR DW 0 ;RESERVED INPUT FILENAME LD HL,(INBUFP) ;FORMAT FILENAME INC HL CALL DONAME LD HL,DRVMSG ;GET DRIVE # CALL EDITOR CALL GETNUM ),A ;SET CHAR INTO FPB INC DE DJNZ NEXTCH LD A,(HL) ;NEXT CHAR MUST BE '.' RES 7,A NAMEDN: CP APEROD JR Z,EXTNTN ET ; RSVPTB: DB 8D DB ASPACE,AEQUAL,AMINUS,APEROD DB COLON,SCOLON,ALT,AGT ; ; DIRECTORY HANDLING ROUTINES ; DELETE: R A JP M,ENTRY2 NXTFIL: LD B,8D ;SET FILENAME CHAR COUNT INC DE ;IF 1ST ENTRY = DELETED THEN WASTE IT LD A,(DE) BIT 7, NOT ; MATCHING THEN CONTINUE CP (HL) JR NZ,NOTNUM INC HL JR SERLP ; NOTFND: LD HL,NTFM CALL EDITOR CALL CONND, RETRY? (Y/N) ',0 ; ; LINE INPUT EDITOR ; ; ENTRY- Prompt character in D or 0 for no char ; EXIT - Char count at LB ;CTRL CHAR MASK ; LININ: LD HL,(INBUFP) ;GET LINE PTR LD B,ZERO ;CCOUNT=0 LD (HL),B ;SET CCOUNT INC HL ;PTR = 1ST CELETE & UNDERSCORE JR Z,SWAP CP DEL JR NZ,NOSWAP SWAP: XOR 20H ;5FH <-> 7FH NOSWAP: CP DEL ;IF DELETE THEN GO DELETE ;CCOUNT=CCOUNT-2 DEC B PUSH AF LD A,ASPACE ;LAST CHAR = SPACE DEC HL LD (HL),A DEC HL POP AF JR NXTCHR ; CANCEE BUFFER ; INBUFP: DW INBUF ;LINE BUFFER PTR ; INBUF: DS 82D ENDBUF: EQU $ ; MAXLIN: EQU ENDBUF-INBUF-2 ;MAX CHARS ALLOWID LD BC,(LENG) DEC BC CALL SETCNT JR RD ; NOMCB: LD BC,(BLOCK) ;ELSE READ ENTIRE FILE CALL SETBID LD BC,(LENG) STORAGE ; ; FILE NOT FOUND ; NOTFN: LD HL,NTFNDM CALL EDITOR CALL CONIN ;WAIT JP END ; ; SYSTEM ERROR ROUTINE  LD A,E LD (DRIVE),A CALL SETDRV CALL READIR RET ; ; FORMAT FILENAME SUBR ; DONAME: LD DE,NAME ;SET PTR PUSH DLD HL,NAME SET 7,(HL) RET ; EXTNTN: INC HL ;PASS OVER '.' LD B,2 LD DE,EX JR NEXTCH ; ; TEST FOR RESERVED CHAR XOR A ;SET DELETE MODE JR DIRSRH ; ENTRY: LD A,ENTMOD ;(-1) PUSH DE JR DIRSRH ; LOOKUP: LD A,ONE DIRSRH: LD (DIRMOD)A JR Z,NOGOOD NXCHAR: LD A,(DE) ;DO NEXT CHAR RES 7,A ;REMOVE ATTRIBUTE BIT CP (HL) ;IF NAME <> DIR THEN WASTE IT JRIN AND 5FH CP 'Y' JR Z,SERST JP END ; DONE: CALL CRLF LD HL,(TADDR) DEC HL CALL PRTDBL CALL CONIN CP ASPACE INBUF, string from LINBUF+1, ; C= ESC pressed, line terminated by NUL (0) ; ;***************************************HAR OF STRING LD A,D ;IF NO PROMPT THEN SKIP OUTPUT OR A JR Z,CONT LD (HL),A NXTCHR: CALL CONOUT ;OUTPUT CHAR INC H JR Z,RUBOUT CP CTRLX ;ELSE IF CANCEL THEN GO CANCEL JR Z,CANCEL CP ESC ;ELSE IF ESCAPE THEN RETURN WITH C SCF RET Z L: LD A,'$' ;OUTPUT ABORT PROMPT CALL CONOUT CALL CRLF ;NEW LINE JR LININ ; CARRET: CALL CONOUT XOR A ;SET END OF LED IN LINE ; ; ; LOAD FILES COMMAND ; LDFILC: LD (MAP),DE ;USE 1ST PARAMETER AS LOAD ADDR CALL FILSET ;SET UP TO READ CALL SETCNT RD: CALL READF JR C,SYSERR JP END ; ; MESSAGES ; FILMSG: DB CR,LF,'Filename: ',0 DRVMSG: DB CR,LF,'Drive; SYSERR: PUSH AF ;SAVE ERROR CODE LD HL,SERRM1 CALL EDITOR POP AF ADD AZERO CALL CONOUT CALL CONIN JP END ; ;E LD A,ZERO LD B,8D ;FILL NAME BUFFER WITH NULLS DOLP: LD (DE),A INC DE DJNZ DOLP POP DE LD B,6D ;SET NAME CHAR CSUBR ; RSVPT: PUSH BC ;SAVE REGS PUSH HL CP ASPACE+1 JR NC,RSVPTT CP A ;SET Z JR RSVPF ; RSVPTT: LD HL,RSVPTB ;S,A ;SET MODE LD HL,NAME ;SET FILENAME PTR LD DE,DIRBUF ;SET DIRECTORY PTR LD A,(DE) ;SET 1ST FILE BLK ID LD C,A LD B Z,GOOD SET 7,A ;TRY WITH ATTRIBUTE SET CP (HL) JR NZ,NOGOOD GOOD: INC HL INC DE DJNZ NXCHAR LD A,(DIRMOD) ;IF DEL JR Z,NOTNUM JP END ; ; SPACE OUTPUT ROUTINE ; SPACE: PUSH AF LD A,ASPACE CALL CONOUT POP AF RET BUFFER: DS BU****************** ; ; PARAMETERS ; CASELO: EQU 'a' ;LOWER CASE LIMIT CASEHI: EQU '{' CHAROF: EQU 20H ;OFFSET BETWEEN LCL INC B ;CCOUNT +1 CALL SAVCNT LD A,B ;IF MAX LINE LENGTH THEN PRINT MSG CP MAXLIN JR Z,LNLONG CONT: CALL CONIN ;GE CP CR ;ELSE IF RETURN THEN GO RETURN JR Z,CARRET LD E,A ;SAVE CHAR AND CTRLMK ;IF CTRL CHAR THEN IGNORE LD A,E JRINE FLAG LD (HL),A INC B SAVCNT: PUSH HL ;SAVE CHAR PTR LD HL,(INBUF) ;PUT CCOUNT INTO LINE LD (HL),B POP HL RET  CALL LOOKUP JP C,NOTFN LD BC,(MAP) ;SET READ POINTER CALL SETDMA LD HL,(EX) ;IF FILE HAS MCB THEN SKIP 1ST BLOCK LD : ',0 NTFNDM: DB CR,LF,'File not found!',0 SERRM1: DB CR,LF,'PHI-DECK ERROR: ',0 ; ; FILE PARAMETER BLOCK ; DRIVE: DB 0  FILE PARAMETERS SETUP SUBR ; FILSET: LD HL,FILMSG ;OUTPUT PROMPT CALL EDITOR LD D,ZERO ;NO PROMPT CHAR CALL LININ ;OUNT NEXTCH: LD A,(HL) ;GET CHAR RES 7,A ;CLEAR MSBIT INC HL CALL RSVPT ;TEST FOR RESERVED CHAR JR Z,NAMEDN LD (DEET PTR LD B,(HL) ;SET COUNT RSVPLP: INC HL CP (HL) JR Z,RSVPF DJNZ RSVPLP INC B ;SET NZ RSVPF: POP HL POP BC R,ZERO LD (BLKTOT),BC ;SAVE FILES START INC DE ;SET ENTRY COUNT LD A,(DE) LD C,A LD A,(DIRMOD) ;IF ENTRY THEN EXIT OETE THEN GO DELETE OR A JR Z,DELET2 INC DE ;LENGTH -> DE EX DE,HL LD E,(HL) INC HL LD D,(HL) LD (LENG),DE LD 10 !%)- "&*. #'+/  $(,0HL,(BLKTOT) ;START BLOCK -> HL PUSH HL POP BC ;START BLOCK -> SET BLOCK ID LD (BLOCK),BC CALL SETBID XOR A ;SET NC  RES 7,(HL) LD BC,(BLKTOT) ;RESTORE START BLOCK LD A,ONE LD (DIRCHG),A XOR A ;SET NC RET ; ENTRY2: LD B,9D ;SET C DE LD A,(DE) LD B,A PUSH BC POP DE CPL LD H,A LD BC,(LENG) ;GET REQ'D BLKS ADD HL,BC ;IF REQ'D > AVAIL. THEN RY ; CLOSE: CALL DELETE ;IF ALREADY EXISTS THEN DELETE RET C ;IF WRITE PROTECTED THEN RETURN LD HL,DIRBUF ;IF ENTRIES >1 BLKS-REQ'D BLKS LD A,B CPL LD B,A LD A,C CPL LD C,A INC BC EX DE,HL LD A,(DE) ;AVAIL. BLKS LD L,A INC DE  BC,ZERO ;SET BLOCK ID CALL SETBID LD BC,4D ;SET BLOCK COUNT CALL SETCNT CALL REWIND JP READF ; ; WRITE DIRECTORND, ASSUMES DRIVE # SET ; YANKC: CALL BSETUP ;SET UP PARAMETERS CALL READF ;READ BLOCK BLKDON: JP C,SYSERR JP END ; BV JP END ; ; WRITE BYTES TO SPECIFIED BLOCK OF TAPE COMMAND ; WRTC: CALL BSETUP ;INPUT PARAMETERS CALL WRITF JR BLK >k:̈́ˇ̣k( :̈́(! !:̈́( :8WBBO:2O !%s. s.,s.Hs 8!o!$(!o8$nsxOPW !!  :!SW ˇ!o{$:s7:O:G=>Lx0y0xy"7cg*7__C 80i&o&UNKNJRNOPDJNZEDLDICPIINIOUTILDDCPDINDOUTDLDIRCPIRINIROTIRLDDRCPDRINDROTDRNEGRETNRETIRRDRLDIM=;E||g RET ; NOGOOD: INC DE ;WASTE DIRECTORY ENTRY DJNZ NOGOOD CALL ADDBLK ;ADD THIS ENTRY FILE LENGTH TO TOTAL LD A,5D ;SETNAME CHAR COUNT PDLP: INC DE ;SKIP TO END OF DIRECTORY DJNZ PDLP DEC C ;IF AT END OF DIRECTORY THEN GO INSERT JR Z,ATLASSET C LD (BLOCK),HL RET ; ; ADD FILE BLOCKS TO TOTAL SUBR ; ADDBLK: LD HL,(BLKTOT) ;GET TOTAL DEC C ;IF LAST ENTRY 01D THEN RETURN INC HL LD A,(HL) CP 102D CCF RET C INC (HL) ;ENTRIES+1 LD BC,TEN ;ENTRY BYTE COUNT ADLOOP: DEC  LD A,(DE) LD H,A ADD HL,BC EX DE,HL DEC HL DEC SP DEC SP POP BC LD (HL),C INC HL LD (HL),B LD B,9D ;FILLY SUBR ; WRTDIR: LD A,(DIRCHG) ;IF NO CHANGE THEN RETURN OR A RET Z LD BC,DIRBUF ;SET WRITE POINTER CALL SETDMA LD BSETUP: PUSH DE POP BC ;SET ADDRESS CALL SETDMA LD HL,BLKMSG ;INPUT BLOCK ID CALL EDITOR CALL GETNUM PUSH DE POP BDON ; IF ($ AND 0FFH) GT 0 DS 100H-($ AND 0FFH) ENDIF ; DIRBUF: DS 1024D ; END ((#Bͦ : 8C(<8((V:8 0C :!_(!g(##D:8  B ͣ:W0_|F((O H P(> p>ph(> p :(!'(#7/:7kk>kF#ns#:S }}8(SP),DE,(HL)(IX(IYAF,AF'A,(BC),A,(DE),A(C)I,A,IR,A,R FATAL ERROR AT - $NZ ZNC CPOPE P MBCDEHLMABCDEHLAFIXIYSP }o|/g}/o^#V#DM!99`i͍|z2v* :v }C }}|!}|!}|}|?>o&zo& ERROR CODE RET C LD HL,NAME JR NXTFIL ; DELET2: EX DE,HL ;BACK UP TO 1ST CHAR OF ENTRY LD DE,-7 ADD HL,DE INC HLT INC C ;ELSE ADD UP BLOCKS TOTAL & LOOP CALL ADDBLK JR ENTRY2 ; ATLAST: LD BC,(BLKTOT) ;SET BLK ID TO 1ST AVAIL. BLOCK THEN RETURN TO ; MAIN PGM WITH C SET SCF RET Z PUSH BC ;COUNT LD A,(DE) ;ELSE ADD THIS ENTRY'S LENGTH TO TOTAL A ;COUNT JR Z,CLOSE2 ;IF PAST ALL ENTRIES THEN ADD ; NEW ONE ADD HL,BC ;ELSE SKIP OVER THIS ENTRY JR ADLOOP ; CL LAST DIRECTORY ENTRY WITH NULLS EMPTY: INC HL LD (HL),ZERO DJNZ EMPTY LD (HL),E ;SET NEW AVAILABLE BLKS INC HL LD (C,ZERO ;SET BLK ID CALL SETBID LD BC,400H ;SET BYTES TO WRITE CALL SETCNT CALL WRITF PUSH AF ;CLEAR DIRECTORY CHANGC CALL SETBID LD HL,NBLKM ;INPUT # BLKS CALL EDITOR CALL GETNUM PUSH DE POP BC CALL SETCNT RET ; BLKMSG: DB CR G :88=0os̈́Oi&))M ~(os#uu.Ds.Bsu:o{ :z} ou.;s.'ss2>2:S }2>2 S }2>2S }2>2yٷQ2_:Ґ *|p}pu 8!"#)*+4569FNV^fnpqrstuw~@ABCDEFGHIJKMOPQRSVWXYZ[^_`abghijorsxyz{ADDADCSUBSBCANDXORORCPRSTPUSHPOPIYIX| }|>o&|o&z2v* :v ||5 /g}/o#zC /W{/_C DM!>2u))V #}o|gn :u=2uN }:u=2uN }DM ;IF WRITE PROTECT BIT SET THEN ERR BIT 7,(HL) LD A,4D ;SET WRITE PROTECT ERROR SCF RET NZ DEC HL ;ELSE DELETE ENTRY CALL SETBID PUSH BC POP HL LD A,(DE) ;AVAILABLE BLKS -> DE LD C,A ;& BC CPL ;-AVAILABLE BLKS -> HL LD L,A INLD C,A INC DE LD A,(DE) LD B,A ADD HL,BC POP BC ;COUNT LD (BLKTOT),HL ;TOTAL BLKS RET ; ; ADD FILE TO DIRECTOOSE2: INC HL ;POINT TO NEXT AVAILABLE ENTRY LD DE,NAME LD BC,8D ;MOVE COUNT EX DE,HL LDIR POP BC ;AVAIL. BLKS=AVAIL.HL),D LD A,ONE LD (DIRCHG),A RET ; ; READ DIRECTORY SUBR ; READIR: LD BC,DIRBUF ;SET READ POINTER CALL SETDMA LDE FLG XOR A LD (DIRCHG),A POP AF RET ; DIRCHG: DB 0 DIRMOD: DB ONE BLKTOT: DW 0 ; ; YANK A BLOCK FROM TAPE COMMA,LF,'Block ID = ',0 NBLKM: DB CR,LF,'Blks to read/bytes to write = ',0 ; ; SET DRIVE COMMAND ; SETDC: LD A,E CALL SETDR.'s͚{k(ʹ^#VK O*## .LsK+O-DOhsy{ .)s.(0_2>OP!B:xGH> >P >x 2B2B2@=?7os.RETEXXJPLDCALLOUTINEXDIEIHALTRLCARRCARLARRADAACPLSCFCCFINCDECBITRESSETRLCRRCRLRRSLASRAERRSRL!>))ҍ =… }}/o|/g#}||g}o|!|7g}oµ ) }}o|gBK^#Vz #y ### #x #~#fo}|20 !%)- "&*. #'+/  $(,0>?o&}|>o&|g}o!|g}o~# x,!!9w~#C!!P!|͎! 9! 9^#V!H5ͱ"͎!P!9s!r! !9s#r!!9s#r!+9^#V^!#9s#r!-X#!!!9s#r!+9~#fo#s#r+^!#9s#r!#9^#V!0s#!0!9s#r!!9s#r!+#rî%!9! !9^#V&!9s#rî%!9!!9^#V&!9s#rî%!9^#V!9s#rͅ9!9s#r%!9^#V!#9s#r!#9^#V!s#rs! 9^#V`i;DM&! 9^#V͎!#'DM! ^zʄ'`i DMU' ʁ'!#rz)&)!! ^#V`is#r! s#r`i͎!9N#F! ^zd)! ^!}X)!,! ^2!! s͎!#'DM`iU' ~#for+!9^#V!9s#r*+!9~#fo+s#r!9^#Vzo+!9^#V͙)!9s#r!\+!9^#V!9^#V`i#DM+s+*!9^#V͎F! ^!}ʮ-*ͅ! ^#V`i^#V *}!9s#r! ^#V! ^h4!9^#V! ^#V! ^3!`in&} ^#V`i^#V !9~#fos#r5/! ^͛4! s#r!9^#V*ͫ`i~#fos#r!9^#V* !9s#rÀ/ ..!//!9^#V!%} 0DM!$ ^! -3!5!!$ s!͎! 9^#V!%} 0DM!!9s#rs3!!9~#fos#r!9^#V!9~#͎!!5DM 55! !5! DME5`iE5!DM`i͎!9^#V! e5! H5*0ʅ5!9^#V!5͎!8"6!9! 5! !5!^9^#V!9s#r! 9^!ʼ!!! 9^!9s#r! 9DM!9~#fo+s#r#|"`i#DM+^!9~#fo#s#r9~#fo#s#r+^!#9s#r!0#!#9^#V!9#!9^#V! } !#9~#fo!9s#r~#!#9^#V!.M$!!9s#r!+9~#fo#s9!9s#rsî% ou$d$u%x'%sI%cg%u%!9!9~#fo !9s#r!9^#V!9~#fo %!9^#V!9s#r!!9^#Vz&&!9~#fo+_'! 9^#V#^!+!9s#r! 9^#V^(!9^#Vzʿ'!'!! 9^#VͰ1! s!'!!9^#Vz'!'!! s!!ʘ)`i DM&)x)͎! 9N#F! ^#V`i^#V c*! ^! })!! ^#V! ^:3!9s#r!)!! ^#V! 9N#F! ^#V`i^#V ʬ+!,ʬ+!!9^#V`i~#fo#s#r+s!`in&ͧ s!9^#V!}͎!9N#F! 9^#V`is! 9^#Vzʮ-!9^#V*!`i~#fos#r! 9^#VzO.* !! ^#V 9! ^! }0.!! ^#V! ^:3!9s!`in&}s! ^#V! ^h4*! ^#V! ^:3!9s#r! ^#V!9~#fo`is#r! ^#V!9~#fo! s#r!9^#͎!0!9s#r1!9~#fo%s#r!9^#V!1 !1!9^#V!$^z21!" fo !3! 9^#V!9~#fo!5!!5" |3`i!~#fo#s#r`3!9^#V͎! 9^#V!%} 0DM!!9s#r 4!!9Ö5!9^#V!5!9^#V͎!9^#V! 5!9^#V!5!!9^#V"0:*t757!*wDM*y7!*w*!9s#r!9~#fo#s#r+^!9s#r!6DM!"r7ú7*r7#"r7*r7ʭ8!9^#Vz8!9^#V^! 7!9^#V^! 8!9+s!!!9^#Vs!^9^#V͎!9^#V^zN"!9~#fo#s#r+^H5""0123456789abcdef͎!9^#V"O"! 9! 9^#V!#r+^!#9s#r!0M$!#9^#V!9M$!9^#V! } !#9~#fo!9s#r#!-9~#fo##s#r++^#V!9s#r!#9^#VÏ%!9!!s#r#!9~#fo &&!9^#V`i͍%!!9s#rC&!9~#fo#s#r!9^#V^zʆ&!9^#V!9~#foʆ&!9~#fo#s#r+^`i! s#r(!! 9^#VͰ1! s!0(!!9^#VzB(!.E(!*! s!! s#r(!! 9^#VͰ1! s!ʝ(!! ! ^#V **!`i~#fos#r! ^#V`is#r! ^#V!9~#fo! s#r!`in&}s`i~#fo#s#r+^!}͎}{+,!! 9^#V`i!}{+C,!`i͎! 9N#F!9^#V!9~#fo} !9s#r!!9s#rÉ,!9~#r!.!!9^#Vz0.! `in&ͧ s! ^#V`is#r! ^#V!! s#r!͎! 9N#F!9^#V!ƒ.! ^#V`i^#V V!?0! `in&ͧ s!9^#V!;0!9^#Vz?0!!͎!9N#F! ^#V* ! ^#V`i^#V ͎*s0|!!9^#V! 9^#V6'2!" !! 9^#VÛ2!9^#V!5V2!" !î2!9^#V!5!9^#V!5~#fos#r!9^#V!9~#fo !_4! 9^#V!9~#fo!5!"5" |_4`i!~#fo#s#r3!9^#V͎!9^#V!%} 0DM*yDM*{!9N#F#^#Vkb6#> 6 #=!6>6#=*6 : >]6 Aڗ6[N6@Z6aڗ6{җ6`w# .x6ʑ6`6͞6w#a6{o|g~#fo#s#r!9~#fo+s#r7!9^#V!­8`i*r7)6s#r!9^#Vzʞ8!9^#V^! ʞ8!9^#V^! ʞ8!9~#fo+s#r!"ͱ"!*O"s͎!9^#V*O"#"O"+s!}͎!)9N#F!+9~#fo#s#r+^!#9s#rz&!#9^#V!%&!!9s!!!9s#9^#V&!9s#rî%!9^#V!$!9! !9^#V͕ &!9s#r!-!9~#fo+s#rs%!9! !9^#V&!9s4&!!9^#Vz¿&!9~#fo+s#r#!9~#fo ʿ&! `i͍Ò&&!#9^#V`i͍ý"͎!9N#F`i! 9~#foC Q"^!9~#fo+9^#VͰ1! s!ʝ(!!9^#Vzʯ(!ò(! ! s! ^͛4! s#r(! r'w (aY((! ^#Vz)!u0! s! 9^#V͙)DMµ*! 9^#V͙)!9s#r!ʹ*!!9^#V! PYͧ ͎!9N#F!!9s#r*!9~#fo#s#r!9^#V!9#fo#s#r!9^#V!9~#fo !,!9^#V`i#DM+^{+,!z,!9^#V͎! 9N#F!͎!! 9^#V,͎! 9N#ʇ.!!9^#V`i~#fo+s#rs!9^#V͎! 9N#F!,.!!9^#Vm/!9^#V*!! s#r!9^#V*}!9s#rÀ/!0!ͧ6"q0"s0*s0DM!9^#V*s0"s0*s0*q0 0!ͧ6¿0!!*q0"q0ã0`iʎ2!" !î2!" ! 2222Y22! 9^#V#!9^#V!$s!!9^#V!#s!9^#V!!s#r!9^#V!0 %;͎! 9^#V!! s#r!!# s!͎!9^#V!%} 0DM!#5!! ^#V͎!9^#V!%} 0͎!9!.9^#V6!9!5 ʑ6͞6w#‚6!!|a{ !9^#V*5!9}|6"5|!9~#fo#s#r+^`i#DM+s;8!`i#DM+só7!6*r78͎n)!9^#Vz8!845A:$$$.SUB! 9F+N+V+^+~+ngx 30 !%)- "&*. #'+/  $(,09w# 8!9^#V#N#F#nx%9s# 9!9^#V#~#foxK9P9K9# 79!Z9!}!}!9^#V#~#foxʂ9~ʂ9# h user Ram"); break; default: puts("\nProgram error"); } printf("! %d\n",errno); /* <<<ED MEMORY THEN ERR OR A JR Z,CONT1 LD BC,RDERRM ;OUTPUT 'READ ERROR' CALL EDITOR JP 0 ; MEMER: LD BC,MEMERM CALL EJR NZ,NOT1ST INC HL LD A,(HL) CP D JR NZ,NOT2ND INC HL ;FETCH SERVICE ADDR LD E,(HL) INC HL LD D,(HL) PUSH DE /* disassembler main module 31 may 82 */ /* enter processor type between quotes of following declaration, to be displayed ter */ #define version "1.1" /* *************************************************************** Syntax: DISX [ead of labels X i.e.: Hex: LD HL,(3805H) Label: L37B4: LD HL,(L3805) 'offset' Is optional HEX value to be added to  NOTE: The "LOCAL" switches are reset if not specified after each entry. **************************************************fileptr; /* pointer to input filename */ FILE *inkey, /* input file key */ *fopen(), *outkey; /* output f offset */ *symtab, /* Symbol table start pointer */ *symptr, /* Bottom of symbol table pointer */ /* *symbotwitches */ } ctrl[17]; char segment; /* Current control pointer */ char pass, /* Disassembler pass count */ d checksum */ /* main program */ main(argc,argv) int argc; char *argv[];{ initialize(argc,argv); disassemble();q9!9~#foʚ9#Ñ9}!9^#V#^#V#N#F79!9^#V#^#V#N#Fq9!9^#V#~#foxʂ99#9q9!9^#V#^#V#N#<<<<<<<< diag */ exit(0); } #ifdef diag_mode /* temporary disline */ disline(){ output(fetch()); returDITOR JP 0 ; CONT1: EQU $ CALL CRLF LD C,2AH ;OUTPUT PROMPT CALL CONOUT CALL RDCON LD HL,(CMDPTR) CALL SKIPO1 ;SET UP FOR COMMAND LD HL,(CMDPTR) LD C,ASPACE CALL SERCH1 LD (CMDPTR),HL POP HL JP (HL) ; NOT1ST: INC HL ;WASTE Ein sign-on message. */ #define proc_type "Z80" /* (c) 1981 GRH Electronics, CUPERTINO, CA Handles all initialization &] [HEX] inputfile [] [] 1- [] [] 2-..... . n-cr Where: 'sw' Is one or morethe disassembler "program counter" at the start of disassemly (default = 0). 'S skipcount' is optional number of bytes to s************* */ #include libc.h /* Declarations */ /* system */ #define bdos 0x0005 #define inputbufrsize 80ile key */ char outfilename[last]; /* output filename buffer */ char inbuf[80]; /* user controls input buffer */ c, * EXTERNAL ($MEMRY) Bottom limit of symbol table */ *cmdsav, /* Command pointer save */ bytecnt; /* disasse done; /* Done flag */ char *stop, /* Disassembly end limit */ *start, /* Disassembly start limit */ *p finishup(); exit(0); } /* initialize & fetch user inputs */ initialize(argc,argv) int argc; char *argv[];{ F9!9^#V#n~:$:#:!|!9^#V#n@:#7:x: +~@:$:!9~ u: u: u:Ê:!9~Aڊ:[Ҋ:!}!9~n 1; } #endif JR NZ,CONT3 SYNERR: LD BC,SYNERM ;OUTPUT 'SYNTAX ERROR' CALL EDITOR JR CONT1 ; CONT3: LD (CMDPTR),HL LD E,(HL) ;CMD -> NTRY NOT2ND: INC HL INC HL DJNZ NXTCMD ;IF NOT LAST ENTRY THEN LOOP LINOUT: CALL CRLF LD C,23H ;OUTPUT ERROR PROMPT '#'  file I/O. Calls disline to disassemble a line of object & returns the code byte count. ******************************** optional switches: LOCAL GLOBAL /A = Show valid ASCII operands as comments: ;'C' X X /D = Generate 'DB's instead kip at the beginning of the input file. 'low , high' are up to 16D optional groups of addresses to be disassembled with #define noerrors FALSE #define ERROR (-1) #define hexswitch 0x4 #define asciiswitch 0x10 #define dataswitch 0x20 #defhar endoffile, /* end of file flag */ endofline; int status; /* CP/M status returned */ char switches; /* mbler queue count */ #define symbot (memtop - 1) /* temporary definition <<<<<<<<<<<<<< */ struct control{ int lowgmcounter, /* Disassembler program counter */ *skipcount, /* Byte skip count */ *skipcnt; int hexfile; /*  int lcount, ccnt; char *argptr; offset = 0; skipcount = 0; infileptr = 0; hexfile = FALSE; for (ccnt aڊ:{u:!!9~0ڊ::Ҋ:u:!9~aڲ:{Ҳ: o&!9~A:[: o&$:!9~ u: u: u:Ê:!9~Aڊ:[Ҋ:!}!9~TPUT 'ENTER PROM TYPE' CALL EDITOR CALL RDCON JR GOTPRM ; CONT2: LD BC,OVLBFR CALL RDFILE JR C,MEMER ;IF INTO RESERVDE INC HL LD D,(HL) LD HL,CMDTBL LD B,(HL) ;FETCH TABLE SIZE NXTCMD: INC HL ;IF CMD <> ENTRY THEN LD A,(HL) CP E  CALL CONOUT LD BC,(CMDPTR) CALL EDITOR CALL CRLF JR CONT1 ; ; COMMANDS ; ; READ INTO BUFFER ; READC: EQU $ ******************************* Revisions: x.x - Pre-release 1.0 - Released version 1.1 - Aztec C version, should be fasof instructions X X /L = Generate Listing type file instead of Source type X /H = Use HEX values as operands instin the code file. Only those switches marked "LOCAL" in chart above will be honored when used within the 'low,high' groups.ine listswitch 0x80 #define last 15 /* Variables */ char *cmdptr; /* User command from invocation */ char *inCurrent switches */ char *temp; /* Scratch */ char *memtop, /* Top of memory pointer */ *offset, /* File start; /* Current control start addr */ int high; /* Current control end addr */ char switches; /* Current control shex input file flag, selects decoding */ int byt_cnt; /* Byte count of hex file record */ int chk_sum; /* Hex file recor= 1; ccnt < argc; ccnt++){ argptr = argv[ccnt]; if (strcmp(argptr, "/A") == 0) switches |= asciiswitch; el40 !%)- "&*. #'+/  $(,0se if (strcmp(argptr, "/D") == 0) switches |= dataswitch; else if (strcmp(argptr, "/L") == 0) switches |= listswitch; if (strcmp(argptr, "S=") == 0) skipcount += gethex( argptr + 2); else infileptr = argptr; } /* if input file ;puts(" Disassembler for CP/M Ver "); puts(version); puts("\n(c) 1981,1982 GRH electronics, CUPERTINO, CA\n"); /* openme[ ccnt++] = 'D'; outfilename[ ccnt++] = 'I'; outfilename[ ccnt++] = 'S'; outfilename[ ccnt] = '\0'; if ((outkestart disassembly.\n"); /* get control data */ while (( inbuf[0] != 0) & (lcount < 16)){ printf( "%2d - ", lcou } else{ ctrl[ lcount].high = ctrl[ lcount].low; cmdptr = cmdsav; } ; lcount ++; } } /* set end of controls flag */ if (lcount == 0) lcount = 1; ctrl[ lcoumbler main loop */ disassemble(){ char dump; bytecnt = 0; byt_cnt = 0; while (done == FALSE){ /* skip inpcounter + disline(); if (symptr < (settop(0) + 11)) err_exit(3); } /* or if not at last segment t else endoffile = TRUE; } /* if last pass then done & exit saving last of file */ else if (pass == 2if ((inkey = fopen(infileptr, "r")) == ERROR) err_exit(4); byt_cnt = 0; } } } /* skip spacesptr; } /* search for reserved char function */ srchrsvp(ptr) char *ptr;{ while ((*ptr != NULL) & (*ptr != ' ')  else if (strcmp(argptr, "/H") == 0) switches |= hexswitch; else if (strcmp(argptr, "HEX") == 0) hexfile = TRUE; specified then continue else abort */ if (infileptr == 0) err_exit(0); /* set memtop to top of user ram less 1k for  input file */ if ((inkey = fopen(infileptr, "r")) == ERROR) err_exit(1); strncpy( outfilename, infileptr, last -y = fopen( outfilename, "w")) == ERROR ) err_exit(2); /* init segment array to disassemble entire file */ segment = nt + 1); gets(inbuf); if (inbuf[0] != 0){ cmdptr = skip( inbuf); ctrl[ lcount].low = gethex( c cmdptr = skip( search(' ', cmdptr)); ctrl[ lcount].switches = (( switches & nt].low = 0; ctrl[ lcount].high = 0; /* init disassembly variables */ segment = 0; pass = 1; endoffile = Fut until skipcount == 0 or start is matched */ if (endoffile == FALSE){ if ((pgmcounter < start) | ( skipcnthen next segment */ else if ((segment < 16) | ((ctrl[ segment].low != 0) & () done = TRUE; /* if end of 1st pass then re-initialize for 2nd pass */ else{ pass = 2; endoffi function */ skip(ptr) char *ptr;{ while ((*ptr == ' ') & (*ptr != NULL)) ptr ++; if (*ptr == NULL) endofline = TRUE& (*ptr != '.')) ptr ++; if (*ptr == NULL) endofline = TRUE; else endofline = FALSE; return ptr; } /* collect else if (strcmp(argptr, "O=") == 0){ if ( *(argptr + 2) == '-') offset -= gethex( argptr + 3); else istack */ memtop = ((*(bdos + 1)) + (*(bdos + 2) << 8)) - 1024; symtab = symptr = memtop; /* clear symbol table */ 1); outfilename[last] = 0; ccnt = srchrsvp( outfilename) - outfilename;/* if period used, back up */ if (ccnt > (l0; ctrl[0].low = 0; ctrl[0].high = 0xffff; ctrl[0].switches = switches; /* set up end of controls flag */ mdptr); cmdsav = cmdptr; cmdptr = search(',', cmdptr); if (endofline == FALSE) cmdptr = skip( cmdp ( (asciiswitch ^ 0xffff) & (dataswitch ^ 0xffff))) | ALSE; done = FALSE; status = noerrors; pgmcounter = offset; skipcnt = skipcount; /* set up initial controls  != 0)){ if (skipcnt == 0) pgmcounter ++; if (skipcnt != 0) skipcnt --; dump = fetch(); ctrl[ segment].high != 0))){ segment++; switches = ctrl[ segment].switches; start = ctrl[le = FALSE; segment = 0; switches = ctrl[0].switches; start = ctrl[0].low; stop = ctrl[0; else endofline = FALSE; return ptr; } /* search for a char function */ search(chr, ptr) char chr, *ptr;{  switches function */ getswitches(ptr) char *ptr;{ char switches; switches = 0; while (*ptr != NULL){ pf ( *(argptr + 2) == '+') offset += gethex( argptr + 3); else offset += gethex( argptr + 2); } else  if (symtab < (settop(0) + 1024)) err_exit(12); *symtab = 0; /* sign-on */ puts("\n"); puts(proc_type)ast - 4)) ccnt = last - 4; /* if too big, truncate */ outfilename[ ccnt++] = '.'; /* force '.DIS' type */ outfilenactrl[1].low = 0; ctrl[1].high = 0; lcount = 0; inbuf[0] = 1; puts("\nEnter 'start, stop switches' or RETURN to tr + 1); if (endofline == FALSE){ cmdsav = cmdptr; ctrl[ lcount].high = gethex( cmdptr);  (getswitches( cmdptr) & (asciiswitch | dataswitch)))*/ switches = ctrl[ segment].switches; start = ctrl[ segment].low; stop = ctrl[ segment].high; } /* disasse } /* if within range then disassemble */ else if (pgmcounter <= stop){ pgmcounter = pgm segment].low; stop = ctrl[ segment].high; } /* if last control then must be end of pass */ ].high; pgmcounter = offset; skipcnt = skipcount; fclose(inkey); bytecnt = 0;  while ((*ptr != NULL) & (*ptr != chr)) ptr ++; if (*ptr == NULL) endofline = TRUE; else endofline = FALSE; return tr = skip(ptr); if (*ptr == '/'){ ptr ++; if (*ptr == 'A') switches = switches | asciiswitch; 50 !%)- "&*. #'+/  $(,0 else if (*ptr == 'D') switches = switches | dataswitch; else if (*ptr == 'L') switches = switches | listswitch;  if (byt_cnt == 0){ c = NULL; while ((c == NULL) || (c == 0x0d) || (c == 0x0a) || (c == ' ')){  } byt_cnt = c; c = get_hex(); /* dump address field */ c = get_hex(); c = get_h else{ c = getc( inkey); if (c < 0) endoffile = TRUE; } return c; } /* read & convert ascii-hexurn c - '0'; else if ((c > 'F') || (c < 'A')) err_exit(9); else return c - '7'; } /* output file handler */  } /* get hex value function */ gethex(ptr) char *ptr;{ int accum; accum = 0; while ((*ptr != NULL) & uthx(numb) int numb; { int a; a = ((numb & 0xf0) >> 4); if (a > 9) a = a + 7; output(a + '0'); a = numb & 0x case 0: puts("\nNo input file specified"); break; case 1: puts("\n");puts(infileptr); #asm *INCLUDE DISZ.SRC #endasm  else if (*ptr == 'H') switches = switches | hexswitch; else ptr --; ptr ++; /* bypass switch char c = getc( inkey); if (c == CPM_EOF){ endoffile = TRUE; return c; } ex(); /* record "type" */ if (c != 0) { if (c != 1) err_exit(8); else endoffile = TRUE; characters & return byte */ get_hex(){ int accum, c; c = getc( inkey); if (c == ERROR) err_exit(6); accu output(chr) char chr;{ if (pass > 1){ /* if not 1st pass then output */ if ((status = putc( chr, outkey)) == ERR (isdigit(*ptr) | ((*ptr >= 'A') & (*ptr <= 'F')))){ if (*ptr > '9') accum = (accum << 4) + ((*ptr) - '7'); else 0f; if (a > 9) a = a + 7; output(a + '0'); } /* output hex word */ out2hex(numb) int numb;{ outhex(numb > puts(" Input file not found"); break; case 2: puts("\nCannot open output file"); put*/ } else break; } temp = ptr; if (*ptr == NULL) endofline = TRUE; else endofline = FALSE;  else if (c < 0) err_exit(6); } if ( c != ':') err_exit(7); chk_sum = 0;  } } c = get_hex(); byt_cnt--; if (byt_cnt == 0){ tmp = get_hex(); /* adm = hex_conv(c) << 4; c = getc( inkey); if (c == ERROR) err_exit(6); accum += hex_conv(c); chk_sum += accum; OR) err_exit(10); } } /* finish up outputs any remaining output & closes files */ finishup(){ if ((statuaccum = (accum << 4) + (*ptr - '0'); ptr ++; } return accum; } /* output hex byte to output file */ > 8); outhx(numb & 0xff); } /* output tab */ outtab(){ output(9); } /* output cr-lf */ outcrlf(){ s(outfilename); break; case 3: puts("\nSymbol table overflow"); break; case 4:  return switches; } /* fetch a byte from input file function */ fetch(){ int tmp, c; if (hexfile){  c = get_hex(); /* get record count */ if (c == 0){ endoffile = TRUE; return c; d in checksum from record */ if ((chk_sum & 0xff) != 0) err_exit(5); byt_cnt = 0; } }  /* add in checksum */ return accum; } /* hex digit converter */ hex_conv(c) char c;{ if (isdigit(c)) rets = fclose(inkey)) == ERROR) puts("\nCannot close input file!\n"); if ((status = fclose(outkey)) == ERROR) err_exit(11);  outhex(numb) int numb; { if ((numb & 0xf0) > 0x9f) output('0');/* output leading 0 if alpha */ outhx(numb); } o output(13); output(10); } /* error handler saves string space */ err_exit(n) int n;{ switch (n){  puts(infileptr); puts("\nCannot re-open file"); break; case 5: puts("\nChecksum error"60 !%)- "&*. #'+/  $(,0 TITLE Z-80 DISASSEMBLER SUBROUTINE MODULE ;********************************************************** ; ; Z-80 DISASSEMBLER SE ; X.1 - ADD LOOK-AHEAD FOR DD,FD OPS AND ED OPS VALIDITY. ; IF INVALID, OUTPUTS DB OP BEFORE ESCAPE. ; X.2 - CORRECTED BUGGISTER USAGE: ; C = BYTES USED FROM FILE ; B = STATUS: BIT USE ; 0 EXTENDED OP ; 1 IX OP ; 2 IY OP ; 3 ESCAPE USEDDED OP BIT STIXOP EQU 00000010B ;IX OP BIT STIYOP EQU 00000100B ;IY OP BIT STESC EQU 00001000B ;ESCAPE BIT STJPOP EQU 000100E OF PC AT START OF LINE OUT2HEX EQU QZOUT2HEX ;OUTPUT 16 BIT VALUE ON TOP OF ;STACK TO OUTPUT FILE OUTHEX EQU QZOUTHEX ;OUT2HEX POP HL CALL TAB ;TAB TO LABEL FIELD NOADDR: LD BC,(QZPGMCOUNTER) ;IF LABEL IN TABLE THEN PRINT IT CALL PRTLB C C,SGLBYTLDS CP 0C0H JP C,ARITH8 ;80-BFH = 8 BIT ARITHMETIC GRP JP MISC2 ;C0-FFH = MISCELLANEOUS GRP 2 ; ; HANDLERS ALLE MNEMONIC TABLE ELEMENT SUBR ; ENTRY - A = CODE ; OPSELCT: CALL GETFLD LD C,A ; ; OUTPUT CODE & MNEMONIC SUBR ; ENTRYLL OUTPUT LD L,'B' CALL OUTPUT CALL TAB ;TAB TO OPERAND FIELD LD A,(OP) ;OUTPUT VALUE ; ; OUTPUT SINGLE BYTE VALUE  HL CALL OUTPUT LD L,27H ;' JP OUTPUT ; ; DISASSEMBLER ROUTINES ; ; OP CODES 80H THRU BFH ; 8 BIT ARITHMETIC ; ARIT JP OCODE ; NOTHLT: LD C,10H ;OP PTR = 'LD' EXX LD A,B ;IF INDEX THEN COUNT = COUNT +1 EXX AND 6 JR Z,NOINDX1 ODE LD A,(OP) AND 38H JR Z,RST00 RRA ;COMPUTE BASE 10 VALUE RRA RRA LD B,A LD C,8 XOR A BAS10LP: ADD C MODULE VER 2.X ; (c) 1981 GRH Electronics Cupertino, CA ; by Girvin Herr ; DISASSEMBLES A LINE OF SOURCE CODE ; ;******** IN CLEAN: WHICH WAS MASKED BEFORE. ; ADD TRAP IN CLEAN WHEN BYTES USED EXCEEDS BYTES FETCHED ; OUTPUTS ERROR MESSAGE & PROGRA FLAG ; 4 JP () OP ; 5 LD SP,HL OP ; 6 CLEAN HOLD ; 7 ED OP ; FORM ; ; CONSTANT DEFINITIONS: ; CTRLI EQU 9 A00B ;JP () BIT STLDOP EQU 00100000B ;LD SP,HL BIT STCHLD EQU 01000000B ;CLEAN HOLD BIT STEDOP EQU 10000000B ;ED OP BIT EXTMSOUTPUT 8 BIT VALUE ON TOP OF ;STACK TO OUTPUT FILE FETCH EQU QZFETCH ;FETCH BYTE OF CODE FROM INPUT ;FILE SUBR. RETUALL TAB ;TAB TO OP FIELD CALL GETOP ;GET 1ST BYTE OF CODE ; ; DO SELECTION BY OP CODE ; EXX ;BYTES USED = 1 LD BC, RETURN HERE ; DISRTN: CALL CRLF ;TERMINATE LINE EXX BIT 3,B ;IF ESCAPE USED THEN CORRECT JP Z,DISR1 DEC C DISR1- C = OP OFFSET ; OCODE: LD L,C LD H,0 ADD HL,HL ;COMPUTE TABLE ENTRY ADD HL,HL LD BC,MNETBL ADD HL,BC LD B,4 & ASCII EQU IF ASCIISW SET ; OUTSNGL: EXX ;SAVE VALUE LD L,A EXX CALL OBYTE CALL OUTH LD A,(QZSWITCHES) ;IF ASCIH8: CALL OPSELCT ;OUTPUT OP MNEMONIC LD A,(OP) ;OUTPUT OPERAND REG CP 90H ;SELECT WHETHER 'A,' SHOULD BE JR C,A8A ;O CALL GETOPND1 NOINDX1: CALL OCODE LD A,(OP) PUSH AF CALL GETFLD CALL OUTREG8 ;OUTPUT DEST$REG CALL OCOMMA ;COMMDAA DJNZ BAS10LP RST00: LD C,A ;CONVERT TO ASCII & OUTPUT LD B,2 RSTLP: LD A,C RLCA RLCA RLCA RLCA LD C,A AND************************************************** ; ; This subroutine performs a disassembly to an output ; file from an inM COUNTER VALUE AS AN AID ; TO TRACK DOWN WHERE DISZ WAS AT. ; X.3 - ADD ESCAPE FLAG TO CONTROL CLEAN PARAMETER AT DISRTN. ; LF EQU 0AH ACR EQU 0DH ; HEXSW EQU 00001000B ;HEX OUTPUT SWITCH MASK ASCIISW EQU 00010000B ;ASCII EQUIVALENT SWITCH MASK DAK EQU STEXTOP OR STIXOP OR STIYOP OR STESC IXMSK EQU STEXTOP OR STIXOP IYMSK EQU STEXTOP OR STIYOP FORM ; ; EXTERNALS ; RNED IN L CRLF EQU QZOUTCRLF ;OUTPUT CR/LF TO OUTPUT FILE SUBR ; FORM ; ; DISASSEMBLE LINE MAIN SUBR ; QZDISLINE: LD A1 ;STATUS = 0 EXX LD HL,DISRTN ;PUT RETURN ADDR ON STACK PUSH HL LD A,(QZSWITCHES) ;IF 'DB' SWITCH THEN BRANCH AND DA: ;IF HOLD BIT CLEAR THEN BIT 6,B EXX CALL Z,CLEAN ;CLEAN UP INPUT BYTE BUFFER EXX BIT 3,B ;IF ESCAPE USED THEN C;COUNT = 4 OMNEM: PUSH BC PUSH HL LD L,(HL) CALL OUTPUT ;OUTPUT MNEMONIC POP HL POP BC INC HL DJNZ OMNEM JP TAISW TRUE THEN OUTPUT ASCII EQUIV. AND ASCIISW RET NZ EXX ;IF NOT PRINTABLE THEN RETURN LD A,L EXX CP ' ' RET C UTPUT OR NOT CP 98H JR C,A8NA CP 0A0H JR NC,A8NA A8A: LD L,'A' CALL OUTPUT CALL OCOMMA A8NA: LD A,(OP) JP OUTREGA POP AF JP OUTREG8 ;OUTPUT SRC$REG ; ; DISASSEMBLER ROUTINES ; ; OP CODES C0H TO FFH ; MISCELLANEOUS #2 ; MISC2:  0FH ADD '0' LD L,A PUSH BC CALL OUTPUT POP BC DJNZ RSTLP RET ; ; 11XX XXX0 ; DIS41: BIT 1,A JR Z,DIS411 put file of one line of code. ; ;************************************************************ ; REVISIONS: ; X.0 - PRE-RELEANEEDED FOR ED OPS. (NOT ALL USE ESCAPE:). ; ;************************************************************* ; ; ALTERNATE RETASW EQU 00100000B ;OUTPUT 'DB's SWITCH MASK LISTSW EQU 10000000B ;LISTING FORM OF OUTPUT MASK ; STEXTOP EQU 00000001B ;EXTEN;SWIT EQU QZSWITCHES ;BYTE CONTAINING SWITCHES TAB EQU QZOUTTAB ;OUTPUT TAB TO OUTPUT FILE SUBR ;PGMCTR EQU QZPGMCOUNTER ;VALU,(QZSWITCHES) ;IF NOT LISTING THEN SKIP AND LISTSW JP Z,NOADDR LD HL,(QZPGMCOUNTER) ;ELSE OUTPUT ADDRESS PUSH HL CALL TASW JP NZ,PRDB DOOP2: LD A,(OP) CP 40H ;0-3FH = MISCELLANEOUS JP C,MISCOPS CP 80H ;40-7FH = 1 BYTE LOAD GROUP JPORRECT ; CORRECTION JP Z,DISR2 INC C DISR2: ;RETURN BYTES USED LD A,C EXX LD L,A LD H,0 RET ; ; COMPUTB ;TAB TO OPERAND FIELD ; ; OUTPUT 'DB' OPTION OR ON ERROR ; PRDB: EXX ;SET UP 1 BYTE USED LD C,1 EXX LD L,'D' CA CP 7FH RET NC LD L,A PUSH HL CALL TAB ;TAB TO COMMENT FIELD LD L,';' CALL OUTPUT LD L,27H ;' CALL OUTPUT POP8 ; ; OP CODES 40H THRU 7FH ; SINGLE BYTE LOADS ; SGLBYTLDS: CP 76H ;IF OP <> 'HALT' THEN EXIT JR NZ,NOTHLT LD C,17HBIT 0,A JP Z,DIS41 BIT 1,A JP Z,DIS42 BIT 2,A JP Z,DIS43 ; ; 11XX X111 (RSTx) ; LD C,8 ;OP PTR = 'RST' CALL OC BIT 2,A JR Z,DIS412 EXX INC C ;2 BYTE CODE EXX CALL OPSELCT LD A,(OP) ;OUTPUT 'A,' ON REQ'D OPS CP 0E6H JR NC70 !%)- "&*. #'+/  $(,0,IMMED CP 0D6H JR Z,IMMED CALL OUTA CALL OCOMMA IMMED: CALL GETOPND1 ;OUTPUT IMMEDIATE DATA LD A,(OPND1) JP OUTSNGLTR = 'RET' CALL OCODE LD A,(OP) ;OUTPUT CONDITION JP OUTCC ; ; 11XX XX01 ; DIS42: BIT 3,A JR NZ,DIS421 BIT 2,A CP 0E9H ;IF JP (HL) THEN EXIT JR Z,JPIND CP 0F9H ;IF LD SP,HL THEN EXT JR Z,LDSPHL CP 0CDH ;IF CALL THEN EXIT JR Z, OP ; DDOPS: LD B,IXMSK ;IX EXTEND JR EXTOPS ; UNCRET: LD C,0DH ;OP PTR = 'RET' JP OCODE ; EXXOP: LD C,0EH ;OP PTR PND2 ;OUTPUT NN VALUE JP OUTADDR ; ; DD/FD OPS LOOK AHEAD SUBR ; RETURNS CF IF ILLEGAL OPERAND ; LKAHEAD: CALL GETOPND1EH,56H,5EH,66H,6EH,70H,71H,72H,73H,74H DB 75H,77H,7EH,86H,8EH,96H,9EH,0A6H,0AEH,0B6H DB 0BEH,0E1H,0E3H,0E5H,0E9H,0F9H ; XDL ORPAR CALL OCOMMA OUTA: LD L,'A' JP OUTPUT ; NOTOUT: CP 0DBH ;IF NOT 'IN' THEN EXIT JR NZ,NOTIN LD C,13H ;OP PTR OT 'EX' THEN EXIT JR NZ,NOTEXDE LD C,14H ;OP PTR = 'EX DE,HL' CALL OCODE LD HL,DEXXM JR OUTXXHL ; NOTEXDE: CP 0F3 INC C EXX CALL GETOPND1 LD HL,OPND1 CBOPS1: LD A,(HL) CP 40H ;IF BYTE2 < 40H THEN EXIT JR C,CBNOTBIT AND 0C0H CODES 0 THRU 3FH ; MISCELANEOUS OPS ; MISCOPS: AND 7 JP Z,DIS11 CP 1 JP Z,DIS12 CP 2 JP Z,DIS13 CP 6 JP C,DISSAVE VALUE FOR SYMBOL JP SYMBOL ; ; COMPUTE DISPLACEMENT ADDRESS FOR SYMBOL ; ENTRY- A= DISPLACEMENT BYTE VALUE ; COMPADDLUE ; EXIT - BC = SAVED ; OUTDISP: PUSH BC LD B,'+' ;ASSUME POSITIVE LD C,A BIT 7,A ;IF NEGATIVE THEN USE '-' JP  ; ; 11XX X010 ; DIS412: LD C,0FH ;OP PTR = 'JP' DIS412A: CALL OCODE EXX ;COUNT = COUNT + 2 INC C INC C EXX  JR Z,POPRP LD C,09H ;OP PTR = 'PUSH' XRP: CALL OCODE LD A,(OP) CALL GETFLD LD C,A EXX LD A,B ;CLEAR ALL BUT EXTUNCCALL CP 0DDH ;IF IX THEN EXIT JR Z,DDOPS CP 0EDH ;IF ED OPS THEN EXIT JP Z,EDOPS LD B,IYMSK ;SET IY STATUS EXTO= 'EXX' JP OCODE ; JPIND: LD C,0FH ;OP PTR = 'JP (HL)' CALL OCODE EXX SET 4,B EXX LD A,4 ;OUTPUT '(HL)' JP OUT ;IF CB THEN EXIT LD A,(OPND1) CP 0CBH JR Z,LKATCB PUSH HL LD HL,XDOPTBL LD B,XDOPS LKALP: CP (HL) JR Z,LKAFND OPS EQU $-XDOPTBL ; ; 11XX X011 ; DIS43: CP 0C3H ;IF NOT JP THEN EXIT JR NZ,NOTJP LD C,0FH ;OP PTR = 'JP nn' JR AD= 'IN nn' CALL OCODE CALL OUTA CALL OCOMMA CALL OLPAR EXX INC C EXX CALL GETOPND1 LD A,(OPND1) CALL OBYTE H ;IF NOT 'DI' THEN EXIT JR NZ,NOTDI LD C,15H ;OP PTR = 'DI' JP OCODE ; NOTDI: LD C,16H ;OP PTR = 'EI' JP OCODE ; RLCA RLCA DEC A ADD 22H LD C,A PUSH HL CALL OCODE POP HL LD A,(HL) CALL GETFLD ;COMPUTE BIT # ADD '0' PUS14 JP Z,DIS15 LD A,(OP) ;OP CODE CALL GETFLD ADD 18H LD C,A JP OCODE ; ; OUTPUT 16 BIT VALUE SUBR ; ENTRY- HL = R: LD C,A LD B,0 LD HL,(QZPGMCOUNTER) ;ADD 2 FOR THIS JR INSTRUCTION INC HL INC HL BIT 7,A ;SIGN EXTEND JP Z,COMPZ,DISPOS LD B,'-' NEG LD C,A DISPOS: LD L,B ;OUTPUT SIGN 1ST PUSH BC CALL OUTPUT POP BC LD A,C ;THEN OUTPUT VAL LD A,(OP) ;OUTPUT CONDITION CALL OUTCC CALL OCOMMA ;OUTPUT COMMA CALL GETOPND2 ;OUTPUT ADDR JP OUTADDR ; ; 11XX XXENDED FLAGS AND EXTMSK LD B,A EXX LD A,C JP OUTRP ;OUTPUT REG$PAIR ; ; 11XX 0001 ; POPRP: LD C,0AH ;OP PTR = 'POPS: EXX LD A,B EXX LD C,A PUSH BC CALL LKAHEAD ;IF ILLEGAL OPERAND THEN POP BC JP C,PRDB ;TREAT AS DB LD A,C IRP ; LDSPHL: LD C,10H ;OP PTR = 'LD SP,HL' CALL OCODE EXX SET 5,B EXX LD A,6 ;OUTPUT REG$PAIR',HL' JP OUTRPHL INC HL DJNZ LKALP SCF ;NOT FOUND IN TABLE, ERR LKAFND: POP HL RET ; LKATCB: CALL GETOPND3 ;SKIP OFFSET BYTE FOR OPCDROPND ; NOTJP: CP 0CBH ;IF CB OPS THEN EXIT JP Z,CBOPS CP 0D3H ;IF NOT 'OUT' THEN EXIT JR NZ,NOTOUT LD C,12H ;OP PCALL OUTH JP ORPAR ; NOTIN: CP 0E3H ;IF NOT 'EX (SP),HL' THEN EXIT JR NZ,NOTEXISP LD C,14H ;OP PTR = 'EX (SP),HL' CA ; TEXTS ; SPINDM: DB 5 DB '(SP),' ; DEXXM: DB 3 DB 'DE,' ; ; CB CODES ; CBOPS: EXX LD A,B ;IF INDEX NOT PENDINH HL LD L,A CALL OUTPUT ;OUTPUT BIT # CALL OCOMMA ;OUTPUT ',' CBOUTREG: POP HL LD A,(HL) ;OUTPUT REG JP OUTREG8 BYTE PTR TO CODE ; EXIT - HL = VALUE ; OUT16B: ;OUTPUT HI BYTE 1ST LD E,(HL) INC HL LD D,(HL) PUSH DE CALL OUT2H1 LD B,-1 COMP1: ADD HL,BC ;COMPUTE ADDRESS PUSH HL ;SAVE VALUE PUSH HL POP BC ;BUILD SYMBOL TABLE CALL SYBLD2 SYUE CALL OBYTE POP BC RET ; ; ASCII SUBR ; ; OUTPUT RIGHT BRACKET ; ORPAR: LD L,')' JP OUTPUT ; ; OUTPUT LEFT BRA00 ; DIS411: BIT 2,A JR Z,DIS4111 LD C,11H ;OP PTR = 'CALL' JR DIS412A ; ; 11XX X000 ; DIS4111: LD C,0DH ;OP PP' JR XRP ; ; 11XX 1X01 ; DIS421: CP 0C9H ;IF RETURN THEN EXIT JR Z,UNCRET CP 0D9H ;IF EXX THEN EXIT JR Z,EXXOP  OR B EXX LD B,A EXX CALL ESCAPE EXX ;SET UP FOR 2ND LOOP INC C EXX CALL GETOP JP DOOP2 ;LOOP BACK FOR NEXT; UNCCALL: LD C,11H ;OP PTR = 'CALL nn' ADDROPND: CALL OCODE EXX ;COUNT = COUNT + 2 INC C INC C EXX CALL GETOODE LD A,(OPND3) AND 7 CP 6 RET Z SCF RET ; XDOPTBL: DB 9,19H,21H,22H,23H,29H,2AH,2BH,34H,35H,36H,39H DB 46H,4TR = 'OUT' IMMEDOP: CALL OCODE CALL OLPAR EXX INC C EXX CALL GETOPND1 LD A,(OPND1) CALL OBYTE CALL OUTH CALLL OCODE LD HL,SPINDM ;OUTPUT '(SP),' OUTXXHL: CALL OEDITR LD A,4 ;OUTPUT 'HL' JP OUTRP ; NOTEXISP: CP 0EBH ;IF NG THEN EXIT AND 6 JR Z,CBNOTI INC C ;BYTE$CNT = BYTE$CNT + 1 EXX CALL GETOPND2 LD HL,OPND2 JP CBOPS1 ; CBNOTI:  ; CBNOTBIT: LD A,(HL) CALL GETFLD ADD 25H LD C,A PUSH HL CALL OCODE JP CBOUTREG ; ; DISASSEMBLER OPS ; ; OP EX CALL OUTH POP HL RET ; ; OUTPUT ADDRESS VALUE SUBR ; OUTADDR: CALL SYBLD ;ADD VALUE TO SYMBOL TABLE PUSH BC ;MBOL: LD L,'L' ;OUTPUT SYMBOL CALL OUTPUT CALL OUT2HEX POP HL RET ; ; OUTPUT DISPLACEMENT VALUE SUBR ; ENTRY- A = VACKET ; OLPAR: LD L,'(' JP OUTPUT ; ; SPACE OUTPUT ; OSPACE: LD L,' ' JP OUTPUT ; ; COMMA OUTPUT ; OCOMMA: LD L,','80 !%)- "&*. #'+/  $(,0 JP OUTPUT ; OUTH: LD L,'H' JP OUTPUT ; ; OUTPUT CONDITION CODE SUBR ; ENTRY- A = CODE ; EXIT - HL = SAVED ; OUTRCC:M THEN EXIT JR Z,INDREG PUSH HL LD HL,RTAB ;COMPUTE REGISTER TABLE ENTRY ADD L LD L,A JP NC,OUTREG8A INC H OUTRE ')' ; R8IY: LD HL,IIYM ;OUTPUT '(IY' JP R8I ; ; TEXTS ; IHLM: DB 4 DB '(HL)' ; IIXM: DB 3 DB '(IX' ; IIYM: D EXX ;IF IY THEN EXIT BIT 2,B EXX JR Z,RPALLSET LD A,10 ;'IY' JP RPALLSET ; RPIX: LD A,8 ;'IX' JP RPALLSET ; 41: BIT 3,A JR Z,DIS143 INC C DIS143: CALL OCODE CALL SET5 ;SET BIT 5 OF STATUS LD A,(OP) CALL GETFLD JP OUTRP ;  COMPADDR ; NOPOP: LD C,2FH ;OP PTR = 'NOP' JP OCODE ; DJNZOP: LD C,30H ;OP PTR = 'DJNZ' CALL OCODE JP JRUNC ; EXA',' LD HL,OPND1 JP OUT16B ; ; 00XX 1001 ; DIS121: LD C,0 ;OP PTR = 'ADD' CALL OCODE LD A,4 ;OUTPUT 'HL' CALL OUTDE EXX INC C INC C EXX LD HL,OP BIT 3,(HL) JR Z,OUTINX CALL SELREG ;OUTPUT REG PAIR CALL OCOMMA ;OUTPUT COMMUT ')' ; ; 000X X010 ; DIS131: LD C,10H ;'LD' CALL OCODE LD HL,AIBCM ;OUTPUT 'A,(BC)' LD A,(OP) BIT 4,A JR Z,NOTA JP OUTSNGL ; D15IR: LD A,(OP) ;IF NOT 36H THEN ERR CP 36H JP NZ,ERROR1 CALL GETOPND2 LD A,(OP) ;OUTPUT REGISTER AF TO SP CALL Z,SET5 POP AF JP OUTRP ; ; 01XX X00X ; EDIO: LD C,12H ;OP PTR = 'OUT' CP 1 JR Z,EDIN INC C ;CHAN ED OP JP NZ,PRDB CP 0BCH ;IF > BBH THEN NOT ED OP JP NC,PRDB AND 7 ;COMPUTE OP TABLE ENTRY LD C,A LD A,(OPND1)  SUB 20H ;CORRECTION FACTOR FOR JRs ; OUTCC: AND 38H ;PLACE FIELD IN POSITION RRA RRA PUSH HL LD HL,CONDTBL ;TABLE PG8A: LD L,(HL) CALL OUTPUT POP HL RET ; RTAB: DB 'BCDEHLMA' ; INDREG: EXX LD A,B EXX BIT 1,A ;IF IX THEN EXITB 3 DB '(IY' ; ; OUTPUT REG PAIR SUBR ; ENTRY- A = CODE ; EXIT - HL = SAVED ; OUTRP: PUSH HL BIT 2,A JR NZ,RPNOTSTD  RPNOTI: EXX ;IF NOT LD SP,HL THEN EXIT BIT 5,B EXX JR Z,RPALLSET LD A,0CH ;'SP' JP RPALLSET ; ; REGISTER PAIR TA ; 00XX X000 ; DIS11: LD A,(OP) OR A ;IF 0 THEN EXIT JR Z,NOPOP CP 10H ;IF <= 10H THEN EXIT JR C,EXAFAFOP JR Z,DJNFAFOP: LD C,14H ;OP PTR = 'EX AF,AF'' CALL OCODE LD HL,AFAFM ;OUTPUT 'AF,AF'' JP OEDITR ; AFAFM: DB 6 DB 'AF,AF''' RP CALL OCOMMA ;OUTPUT COMMA CALL SET5 ;SET BIT 5 OF STATUS LD A,(OP) CALL GETFLD ;OUTPUT SOURCE REG PAIR JP OUTRP A CALL GETOPND2 ;OUTPUT '(nn)' VALUE JP OUTCONT ; OUTINX: CALL GETOPND2 ;OUTPUT '(nn)' CALL OUTCONT CALL OCOMMA ;OUTPIDE LD HL,AIDEM ;OUTPUT 'A,(DE)' NOTAIDE: BIT 3,A JR NZ,D13REV INC HL INC HL D13REV: LD B,6 JP OSTRNG ; ; TEXT  CALL GETFLD CALL OUTREG8 CALL OCOMMA ;OUTPUT COMMA LD A,(OPND2) JP OUTSNGL ;OUTPUT N VALUE ; ; 01XX X010 (ED OPS) GE TO 'IN' CALL OCODE LD A,(OP) CALL GETFLD CALL OUTREG8 CALL OCOMMA LD HL,CINDM ;OUTPUT '(C)' LD B,3 JP OSTRNG AND 18H RRCA ADD C ADD 32H LD C,A EXX ;BUMP BYTE COUNT INC C EXX JP OCODE ; EDLTA0: LD HL,EDOPSTBL ;VERIFY OTR ADD L ;COMPUTE ENTRY ADDR LD L,A JP NC,HOK INC H HOK: LD B,2 CALL OSTRNG POP HL RET ; CONDTBL: DB 'NZ ZNC JP NZ,R8IX BIT 2,A ;IF IY THEN EXIT JR NZ,R8IY LD HL,IHLM ;OUTPUT '(HL)' JP OEDITR ; R8IX: LD HL,IIXM ;OUTPUT '( RPALLSET: RES 0,A LD HL,RPTAB ;COMPUTE TABLE ENTRY ADD L LD L,A JP NC,RPHOK INC H RPHOK: LD B,2 ;OUTPUT REGISTER BLE ; RPTAB: DB 'BCDEHLAFIXIYSP' ; ; 00XX X011 ; 00XX X100 ; 00XX X101 ; DIS14: LD A,(OP) LD C,20H ;'INC' BIT 2,A ZOP LD C,2EH ;OP PTR = 'JR' CALL OCODE LD A,(OP) CP 18H ;IF UNCONDITIONAL THEN EXIT JR Z,JRUNC CALL OUTRCC ;OUTPU ; ; 00XX X001 ; DIS12: LD HL,OP BIT 3,(HL) JR NZ,DIS121 LD C,10H ;'LD' CALL OCODE CALL SET5 ;SET BIT 5 OF STATUS ; ; SET BIT 5 OF STATUS BYTE SUBR ; EXIT - HL = SAVED ; SET5: EXX SET 5,B EXX RET ; ; 00XX X010 ; DIS13: LD A,(OPUT COMMA ; ; SELECT REG OR REG PAIR SUBR ; ENTRY - E = CODE ; SELREG: EXX LD A,E EXX CP 7 JP NZ,OUTRP JP OUTREG8 ; AIBCM: DB 'A,(BC),' AIDEM: DB 'A,(DE),' DB 'A' ; ; 00XX X110 (LD R,N) ; DIS15: LD C,10H ;'LD' CALL OCODE EXX ; EDADC: LD A,(OP) AND 38H LD C,03H ;OP PTR = 'SBC' BIT 3,A JR Z,EDSBC DEC C ;MAKE 'ADC' DEC C EDSBC: CALL OCODE ; EDIN: CALL OCODE LD HL,CINDM LD B,3 CALL OSTRNG CALL OCOMMA LD A,(OP) CALL GETFLD JP OUTREG8 ; CINDM: DB '(CP IN TABLE LD B,NUMEDOPS EDOPLP: CP (HL) JR Z,EDOPOK INC HL DJNZ EDOPLP ;IF NOT DONE THEN LOOP JP PRDB ;ELSE TREAT  CPOPE P M' ; ; OUTPUT REGISTER SUBR ; ENTRY - A = CODE ; EXIT - HL = SAVED ; OUTREG8: AND 7 ;INSURE MOD 8 CP 6 ;IF IX' R8I: CALL OEDITR CALL GETOPND1 ;OUTPUT DISPLACEMENT EXX INC C EXX LD A,(OPND1) CALL OUTDISP JP ORPAR ;OUTPUTPAIR CALL OSTRNG POP HL RET ; RPNOTSTD: BIT 1,A JR NZ,RPNOTI EXX ;IF IX THEN EXIT BIT 1,B EXX JR NZ,RPIX  JR Z,DIS141 BIT 0,A JR Z,DIS142 INC C DIS142: CALL OCODE LD A,(OP) CALL GETFLD JP OUTREG8 ; ; 00XX X011 ; DIS1T CONDITION CODE CALL OCOMMA ;OUTPUT COMMA JRUNC: CALL GETOPND1 ;OUTPUT DISPLACEMENT EXX INC C EXX LD A,(OPND1) JP LD A,(OP) CALL GETFLD ;COMPUTE & OUTPUT REG PAIR CALL OUTRP EXX INC C INC C EXX CALL GETOPND2 CALL OCOMMA ;) BIT 5,A JR Z,DIS131 EXX LD E,4 BIT 4,A JR Z,D13NTR8 LD E,7 D13NTR8: EXX LD C,10H ;OP PTR = 'LD' CALL OCO ; ; OUTPUT LOCATION ADDR VALUE - '(nn)' ; OUTCONT: CALL OLPAR ;OUTPUT '(' CALL OUTADDR ;OUTPUT VALUE JP ORPAR ;OUTPINC C LD A,B EXX AND 6 JR NZ,D15IR LD A,(OP) CALL GETFLD CALL OUTREG8 CALL OCOMMA CALL GETOPND1 LD A,(OPND1) LD A,4 ;FORCE 'HL,' CALL OUTRP CALL OCOMMA ;OUTPUT COMMA LD A,(OP) CALL GETFLD PUSH AF RES 0,A CP 6 ;CHANGE )' ; EDOPS: CALL GETOPND1 ;SPLIT 2BYTE FROM GARBAGE LD A,(OPND1) CP 0A0H JR C,EDLTA0 BIT 2,A ;IF BIT 2 = 1 THEN NOTAS DB ; EDOPSTBL: DB 40H,41H,42H,43H,44H,45H,46H,47H,48H,49H,4AH DB 4BH,4DH,4FH,50H,51H,52H,53H,56H,57H,58H,59H DB 5AH,590 !%)- "&*. #'+/  $(,0BH,5EH,5FH,60H,61H,62H,67H,68H,69H,6AH DB 6FH,72H,73H,78H,79H,7AH,7BH ; NUMEDOPS EQU $-EDOPSTBL ; EDOPOK: CALL ESCAPE EXT 'R,A' SKPR: BIT 4,A JR Z,EDREV INC HL INC HL EDREV: LD B,3 JP OSTRNG ; IAIM: DB 'I,A,I' RARM: DB 'R,A,R' ; ; 01 DEC C ;OP PTR = 'RRD' EDROTL: JP OCODE ; ; 01XX X110 ; EDIM: LD C,47H ;OP PTR = 'IM' CALL OCODE LD A,(OP) AND 38H TO OUTPUT FILE SUBR ; ENTRY- HL = MSG PTR (POINTING TO CNT BYTE) ; OEDITR: PUSH BC LD B,(HL) ;GET COUNT INC HL CALL OET ; GETOPND1: LD A,(QZBYTECNT) CP 2 RET NC CALL FETCH LD A,L LD (OPND1),A LD A,2 LD (QZBYTECNT),A RET ; GURN RET Z CP 4 ;IF (USED > 3) { JP C,CLNOTALL XOR A ; COUNT = 0 LD (QZBYTECNT),A RET ; RETURN } ; CLNOTALLALPH: ADD '0' PUSH HL LD L,A PUSH HL CALL QZPUTCHAR POP HL POP HL POP AF RET ; CLEAN1: LD (QZBYTECNT),A RET USED FLAG FOR DISRTN EXX RET ; ; ERROR HANDLER SUBR OUTPUTS DBs TO GET IN SYNC AGAIN ; ERROR1: LD A,(OP) ;SAVE CURRENT TORE OP LD (OP),A EXX ;SET CLEAN HOLD BIT FOR RETURN LD B,40H EXX RET ; ; ROUTINE TO BUILD & ACCESS THE SYMBOL TABER LABEL CALL OUTPUT SCF RET ; ; SYMBOL TABLE BUILD ; SYBLD: CALL GETOPND2 ;FETCH DATA SYBLD1: LD A,(OPND1) LD C,A LD A,C LD (DE),A XOR A ;RESTORE END OF TABLE FLAG DEC DE LD (DE),A EX DE,HL ;UPDATE BOTTOM OF TABLE PTR LD (QZSYMPUND, DE=OPEN LOCATION ; NC=FOUND, DE=PTR TO SYMBOL ; HL RESTORED ; LOOKU: PUSH HL LD HL,(QZSYMTABL) EX DE,X INC C SET 7,B ;SET ED FLAG FOR ERROR1 EXX CALL GETOP LD A,(OP) ; ; 01XX XXXX ; EDOLT80: AND 7 CP 2 JP C,EXX X101 ; EDRETS: LD C,44H ;OP PTR = 'RETI' LD A,(OP) AND 38H CP 8 JP Z,OCODE DEC C ;'RETN' JP OCODE ; ; 01XX  CP 8 JR C,EDIM0 RRCA RRCA RRCA DEC A EDIM0: ADD '0' LD L,A JP OUTPUT ; ; OUTPUT REG PAIR SUBR ; OUTIRP: PUSTRNG ;OUTPUT STRING POP BC RET ; ; MESSAGE EDITOR W/CNT SUPPLIED SUBR ; ENTRY- HL = PTR TO STRING ; B = COUNT ; OSTETOPND2: CALL GETOPND1 ;GET OPND1 FIRST CP 3 RET NC CALL FETCH LD A,L LD (OPND2),A LD A,3 LD (QZBYTECNT),A RET: LD E,A ;SAVE USED LD A,(QZBYTECNT) ;IF (USED > COUNT) ERROR SUB E JP NC,CLEAN1 FATERR: LD HL,FATERM ;OUTPUT ERR MSG Z ;IF (COUNT == 0) RETURN LD A,4 ;MOVECNT = 4 - USED SUB E RET Z ;IF (MOVECNT == 0) RETURN LD C,A LD B,0 LD D,B OP PUSH AF EXX ;IF NOT IX PENDING THEN IY LD A,B EXX LD B,A BIT 1,B LD A,0DDH JR NZ,ERROR1A ;IF IX THEN OUTPUTLE ; SYMBO: CALL SYBLD OR A ;INSURE NO CRY & RET RET ; ; PRINT LABEL SUBR ; PRTLB: CALL LOOKU ;LOOK UP IN TABLE CC LD A,(OPND2) LD B,A SYBLD2: CALL LOOKU ;IF ALREADY IN TABLE THEN RET RET NC ; ; ADD NEW ENTRY TO SYMBOL TABLE ; ENTRYTR),HL EX DE,HL SCF ;SET DEFAULT LABEL PRINTING RET ; ; ROUTINE TO STORE LABEL IN SYMBOL TABLE ; SYSTX: PUSH AF CAHL POP HL LULP: LD A,(DE) ;IF ENTRY = 0 THEN DONE OR A SCF RET Z DEC DE DEC DE DEC DE DEC DE DEC DE LD A,(DIO JP Z,EDADC CP 4 JR C,EDLDINNRP JR Z,EDARITH CP 6 JR C,EDRETS JR Z,EDIM LD A,(OP) AND 38H CP 20H JR NC,X100 ; EDARITH: LD C,42H ;OP PTR = 'NEG' JP OCODE ; ; 01XX X011 ; EDLDINNRP: CALL SET5 LD A,(OP) LD D,A AND 3SH AF CALL OLPAR ;OUTPUT '(' POP AF CALL OUTRP ;OUTPUT REG PAIR JP ORPAR ;OUTPUT ')' ; ; OUTPUT REG PAIR ',HL' ; RNG: PUSH HL PUSH BC LD L,(HL) CALL OUTPUT POP BC POP HL INC HL DJNZ OSTRNG RET ; ; GET OP CODE SUBR ; GETOP ; GETOPND3: CALL GETOPND2 CP 4 RET NC CALL FETCH LD A,L LD (OPND3),A LD A,4 LD (QZBYTECNT),A RET ; ; CLEATO CONSOLE PUSH HL CALL QZPUTS POP HL LD HL,(QZPGMCOUNTER) ;OUTPUT DIS. ADDR LD A,H CALL PRHEX LD A,L CALL PRHEX LD HL,OP ;MOVE BYTES UP BY COUNT ADD HL,DE LD DE,OP LDIR RET ; FATERM: DB ACR,ALF,'FATAL ERROR AT - ',0 ; ; ESCAPE 'DB 0DDH' LD A,0FDH BIT 2,B JR NZ,ERROR1A ;IF IY THEN OUTPUT 'DB 0FDH' LD A,0EDH BIT 7,B JR NZ,ERROR1A ;IF EDOPS THF ;IF NOT FOUND THEN NC RET NC LD B,5 ;FOUND, PRINT LABEL SYPLP: LD A,(DE) DEC DE OR A SCF ;SET CARRY SO PGM WON- BC=ADDR ; DE=OPEN SYMBOL TABLE ENTRY ; LD A,'L' ;DEFAULT TO LABEL TYPE LXXXX LD (DE),A DEC DE LD A,B ;GET HLL HEXL ;CONVERT & STORE VALUE LD (DE),A DEC DE POP AF CALL HEXR LD (DE),A DEC DE RET ; ; SYMBOL TABLE LOOK UP DE) CP B ;IF NO MATCH THEN WASTE DEC DE JP NZ,LUNO LD A,(DE) CP C JP NZ,LUNO INC DE ;BACK UP TO ASCII PART INCEDROT LD C,10H ;OP PTR = 'LD' CALL OCODE LD A,(OP) LD HL,IAIM ;OUTPUT 'I,A' BIT 3,A JR Z,SKPR LD HL,RARM ;OUTPU0H RRCA RRCA RRCA EXX LD E,A JP D13NTR8 ; ; 011X X111 ; EDROT: LD C,46H ;OP PTR = 'RLD' CP 28H JR Z,EDROTL OUTRPHL: CALL OUTRP ;OUTPUT DEST REG PAIR CALL OCOMMA ;OUTPUT COMMA LD A,4 ;OUTPUT 'HL' JP OUTRP ; ; MESSAGE EDITOR: LD A,(QZBYTECNT) ;IF BYTECOUNT <> 0 THEN RET OR A RET NZ CALL FETCH LD A,L LD (OP),A LD A,1 LD (QZBYTECNT),A RN REMOVES (C') # BYTES FROM BUFFER & MOVES BUFFER UP ; CLEAN: EXX ;A= #BYTES USED LD A,C EXX OR A ;IF (USED == 0) RET JP 0 ; PRHEX: OR A RLA CALL PRHXDG PRHXDG: RLA RLA RLA RLA PUSH AF AND 0FH CP 10 JR C,NTALPH ADD 7 NT CAUSES OP BYTE TO BE SCRUBBED ; ESCAPE: EXX PUSH BC LD C,1 EXX CALL CLEAN EXX POP BC SET 3,B ;SET ESCAPE EN OUTPUT 'DB 0EDH' POP AF ;ELSE OUTPUT 'DB' OPCODE LD (OP),A JP PRDB ; ERROR1A: LD (OP),A CALL PRDB POP AF ;RES'T PRINT DEFAULT RET Z PUSH DE PUSH BC LD L,A CALL OUTPUT POP BC POP DE DJNZ SYPLP LD L,':' ;OUTPUT COLON AFTI ORDER CALL SYSTX ;STORE PRINTABLE HEX LD A,C ;GET LO CALL SYSTX LD A,B ;SAVE VALUE IN TABLE LD (DE),A DEC DE ROUTINE ; BC=HEX VALUE OF SYMBOL TO FIND ; (SYMTABL)= SYMBOL TABLE PTR TO SART OF TABLE TERMINATED BY NULL ; EXIT - CY=NOT FO DE INC DE INC DE INC DE INC DE OR A RET ; LUNO: DEC DE JP LULP ; ; NUMBER CONVERTERS ; HEXL: RRA ;GET LEF:0 !%)- "&*. #'+/  $(,0T DIGIT RRA RRA RRA HEXR: AND 0FH ;MASK OUT LEFT DIGIT CP 10D JR C,HEXRN ADD 7 HEXRN: ADD '0' RET ; ; I/O ROUDB 'AND ' ;4 DB 'XOR ' ;5 DB 'OR ' ;6 DB 'CP ' ;7 DB 'RST ' ;8 DB 'PUSH' ;9 DB 'POP ' ;A DB 'IY ' ;B  DB 'RES ' ;23 DB 'SET ' ;24 DB 'RLC ' ;25 DB 'RRC ' ;26 DB 'RL ' ;27 DB 'RR ' ;28 DB 'SLA ' ;29 DB 'SR DB 'OTDR' ;41 DB 'NEG ' ;42 DB 'RETN' ;43 DB 'RETI' ;44 DB 'RRD ' ;45 DB 'RLD ' ;46 DB 'IM ' ;47 DB ' qs1 ! ! C>R*͑ ͗ !~#o>g6 (@S!N#F# %#^#Vj * "$ À## [ DISULORE:WR=FOEX+HE2?2{! ɯ>2_͢:`:ZO(0 M K] :_   (! "L "b* "*b{"b*h>2!q6H#6E#6Xhͩ < !{ Kb[ͅ ='!uo>g~#fo ɍ File2!͠ڏ>2 :L(<2:c2!͠ڏ>2 >2 >28:L(<2!2:c2!͠ڏ>2 >pd (#* 6?wd (#6 . d (#* 6?wd (#6 #6 #~?  x!0 !| (#=_.:*b"W*d"Y$ ͞ *W"[[Rk *W . ~#oo s 8} "W . *[~0 0>.O. #[W{ z s *YR*b"*0     Jade DD Single density format ?TINES ; OCHAR: LD L,C OUTPUT: LD H,0 PUSH HL CALL QZOUTPUT POP HL RET ; OBYTE: LD L,A LD H,0 PUSH HL CALL QZODB 'IX ' ;C DB 'RET ' ;D DB 'EXX ' ;E DB 'JP ' ;F DB 'LD ' ;10 DB 'CALL' ;11 DB 'OUT ' ;12 DB 'IN ' ;1A ' ;2A DB 'ERR ' ;2B DB 'SRL ' ;2C DB 'UNKN' ;2D DB 'JR ' ;2E DB 'NOP ' ;2F DB 'DJNZ' ;30 DB 'ED ' ;31  ' DB ' ' ; OP: DB 0 ;OP CODE BUFFER OPND1: DB 0 ;OPERA!  Diagnostic Disk UtilityVer 2.0 (c) 1981 GRH Electronics OPTIONS: Prints this list FOrmat a disk REad :*]"]!Z4#5 Disk Error *: >( # 1 }2XO; *@ >( # 1 }2YO *> >( # 1 }2ZO *# Not Found! Hex File Error Hex Conversion Error Command Value out of Bounds! Not Enough Data! ! !   2 !2!͠ڏ>2Ï!͠ڏ>2 ͌ {*DM   !Cͷ!!LDM :O :O;,<>/2TCLSNv _>{(: < 9 _< 9 g< 9 o"R*L"PK KNB >v _>{(: < 8O_< 8Gg< 8AoKRB]$ [Rk  . oo  . _͗ #~#o>g6 [](~.L |}[]~ȹ(# ~ # ~# րOJade DD Double density format 0?UTHEX POP HL RET ; ; SHIFT FIELD INTO PROPER BITS SUBR ; ENTRY- A= BYTE TO SHIFT ; EXIT - A= NEW BYTE ; GETFLD: AND 383 DB 'EX ' ;14 DB 'DI ' ;15 DB 'EI ' ;16 DB 'HALT' ;17 DB 'RLCA' ;18 DB 'RRCA' ;19 DB 'RLA ' ;1A DB 'R DB 'LDI ' ;32 DB 'CPI ' ;33 DB 'INI ' ;34 DB 'OUTI' ;35 DB 'LDD ' ;36 DB 'CPD ' ;37 DB 'IND ' ;38 DB 'OUTND 1 OPND2: DB 0 ;OPERAND 2 OPND3: DB 0 ;OPERAND 3 ; drive @trk >sec #cnt *addr %(translate) WRite :drv @trk >sec #cnt *addr % LOad addr filename.HEX MOve first, last, dest FIll ( # 1 S[** [( # L S]*% >(>2`*b{"b*d{"d*f{"f    !"a"d"f+"b* 7"~,( L "b!a4*, # "L "d!a4*, # "L "f:a<2a[  !Cͷ!#"  * N * ~W>_* DM :͙ P* ~(#" * " >2 :O * DM :͙ : KL "PK KNB0< 8>*P< 8w#$ < 8 >v 0 Q  ?''''Gv 0 o  ?؀GWx:T  (O. $ A .  .  . Ñ ! 0 ?)))o0$! 0 8  ?))))o|p }u  8R Jade DD Disk Formatter Ver 1.0 by Girvin Herr (c) 1981 GRH Electronics, CH RRCA RRCA RRCA RET ; ; MNEMONIC TABLE ; MNETBL: DB 'ADD ' ;0 DB 'ADC ' ;1 DB 'SUB ' ;2 DB 'SBC ' ;3 RA ' ;1B DB 'DAA ' ;1C DB 'CPL ' ;1D DB 'SCF ' ;1E DB 'CCF ' ;1F DB 'INC ' ;20 DB 'DEC ' ;21 DB 'BIT ' ;22D' ;39 DB 'LDIR' ;3A DB 'CPIR' ;3B DB 'INIR' ;3C DB 'OTIR' ;3D DB 'LDDR' ;3E DB 'CPDR' ;3F DB 'INDR' ;40  first, last, data DIsplay <,last> SUbstitute addr EXit return to system Invalid command! - Re-enter. MOGFI}*b{"b*d{"dͰ O*b#}+({*Y"b*d}({*b"d *b{"b| * "s!2ͷ!ͷͽ180'!_~#fo!12ͷ#e:2!͠8>2 >2 :L(<2!>0<2* " !Cͷɷ "*ͷͽ_ (2r2A88 !ͷ7Oͣ !Yͷͽ Ƨ/( 8 @G:(:wxͷ hͰ 7 !"U>2T*U~#"U!T5[b*d:fRy7:f*bw[b*dR[fR8 *by7*f *dy70O. Y  Y****!*$*'*-upertino, CA ****** Functions List ****** 1. Format Jade Double Density 8" 2. Format Jade Single Density 8" 3. Format IBM 3;0 !%)- "&*. #'+/  $(,0740 Standard 8" 4. Format system tracks only. 5. Read system tracks image. 6. Write system tracks image. or use ctrl-C for retur>ۀ>ۀ>ۀ> !ۀ># FORMAT!D!0Pۀ>N ۀۀ>ۀ> TITLE JADE DOUBLE D DISK FORMATTER MODULE ;********************************************************* ; ; FORMAT PROGRAM ;ASCII RTNS LIBRARY ; (MAIN ?)- WITH A WORD DEFINED AS $MEMRY FOR LINK ;*******************************************************E DEFINITIONS ; TRK0: EQU 0 ;TRACK 0 TRK1: EQU 1 ;TRACK 1 TRK2: EQU 2 ;TRACK 2 TRK76: EQU 76D ;TRACK 76 IDSEC: EQU 1 ;ID SS: EQU 48D ;TRACK 1 LAST SECTOR ; ; INJECTION MODULE DEFINITIONS ; FMTEA: EQU 1700H ;FORMAT EXECUTION ADDR WDTRK: EQU 5STKSAV),SP LD HL,MSGBG ;OUTPUT MESSAGE CALL MSGOT FUNBG: LD HL,MSGFL ;OUTPUT FUNCTION LIST CALL MSGOT CALL CNSIN SUB  DW FUN1 ;'1' = DOUBLE DENSITY FORMAT DW FUN2 ;SINGLE DENSITY FORMAT DW FUN3 ;3740 FORMAT DW FUN4 ;SYSTEM TRACKS FORMAT CK # LD (TRKNO),A REPT: CALL FMTDD ;FORMAT TRACK IN DDENS JR NZ,FUN1 ;ERR LD A,(TRKNO) ;IF LAST TRACK THEN DONE CP TRIN SDEN JR NZ,FUN3 ;ERR LD A,(TRKNO) ;IF TRACK 76 THEN DONE CP TRK76 JR Z,FUN3 INC A ;ELSE DO NEXT TRACK LD (TRKNOn to main menu. Enter function number: IS NOT A VALID SELECTION Write format on drive A-D (RETURN to reselect): Read s ۀ>Nۀۀ>ۀ>ۀۀۀ~#ۀ>ۀ>ۀ>Nۀۀ>ۀ>ۀ>ۀ> (c) 1981 GRH Electronics, Cupertino, CA ; ;********************************************************* ; ; REVISIONS: ; *** SUBTTL ASSEMBLER DIRECTIVES ; CPMIOB.REL RTNS: EXTRN SELDSK,SETDMA ; BIOS.REL RTNS: EXTRN SETTRK,SETSEC,RDSEC,WRECTOR # ; ; SYSTEM TRACKS COPY DEFINITIONS ; ;TK0LP: EQU $MEMRY ;SYSTEM TRACKS BUFFER TK0FS: EQU 1 ;TRACK 0 1ST SECTOR  ;DD TRACK PORT WDDTA: EQU 7 ;DD DATA PORT XPDSH: EQU 80H ;DATA SYNC HOLD PORT ZEROS: EQU 00000000B ;ALL ZEROS BYTE ONES:'1' ;IF INVALID INPUT THEN REPEAT JR C,NOFUN CP MAXFUN JR NC,NOFUN SLA A ;OFFSET := FUNC# * 2 LD HL,FUNTAB ;BASE LDW FUN5 ;READ SYSTEM TRACKS DW FUN6 ;WRITE SYSTEM TRACKS ; MAXFUN: EQU ($ - FUNTAB) / 2 SUBTTL FUNCTION 1 - DOUBLE DENSIK76 JR Z,ID INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT ; ID: LD HL,IDSDD ;WRITE DDENS ID SECTOR CALL WRTID JR),A JR REPT3 SUBTTL FUNCTION 2 - FORMAT IN SINGLE DENSITY FUN2: LD A,(SDFLG) ;SET SDENS FLAGS LD (FFLAG),A LD HL,MSystem from drive: Write system to drive (RETURN to re-select): Transfer Incomplete Type RETURN when drive is ready. Fۀ>N?keۀ>N# !%)- "&*. #'+/  $(,0ۀ>ۀ>; 1.0 - RELEASE ; VERSION EQU '10' ;********************************************************** ; ; NOTE: THIS MODULE MUST SEC,FMTTRK,BSTDMA ; ASCII.REL RTNS: EXTRN EDITOR,CI,CO,$MEMRY ENTRY FORMTC SUBTTL DECLARATIONS LF: EQU 0AH ;LINE  TK0LS: EQU 26D ;TRACK 0 LAST SECTOR TK0NS: EQU TK0LS-TK0FS+1 ;TRACK 0 # SECTORS ;TK0LC: EQU TK0LP-128D ;TRACK 0 LOAD CONSTAN EQU 11111111B ;ALL ONES BYTE ; ; ; BIOS VECTOR DEFINITIONS ; BSRDS: EQU 0 ;BIOS READ FLAG BSWRS: EQU 1 ;BIOS WRITE FLAGD E,A LD D,0 ADD HL,DE ;PTR := BASE + OFFSET LD A,(HL) INC HL LD H,(HL) LD L,A JP (HL) ; NOFUN: LD HL,MSGSE ;ELTY FORMAT ; FUN1: LD A,(DDFLG) ;SET FORMAT FLAGS LD (FFLAG),A LD HL,MSGFD ;SELECT DRIVE CALL SELDR JR C,FUNBG ;ERR- R FUN1 ;READY FOR ANOTHER DISK SUBTTL FUNCTION 3 - FORMAT IBM 3740 ; FUN3: LD A,0 ;SET 3740 FLAGS LD (FFLAG),A LD HL,GFD ;SELECT DRIVE CALL SELDR JP C,FUNBG ;TERM. LD A,TRK0 ;SET UP FOR TRACK 0 LD (TRKNO),A CALL FMTSD ;FORMAT IN SDEORMAT!S!(ۀ>ۀ>ۀ>ۀ>ۀ>ۀ>ۀۀ>ۀ~#ۀ>ۀ> ۀ>ۀ>ۀBE LINKED TO OTHER MODULE(S). ; ; BIOS - BIOS CALL LIBRARY ; CPMIOB - CP/M IO CALLS WITH PARAMS PASSED IN BC LIB. ; ASCII - FEED CR: EQU 0DH ;CARRIAGE RETURN CTRLC: EQU 3 ;REQUEST REBOOT CPM SECSZ: EQU 128D ;128 BYTES PER SECTOR ; ; DRIVER MODULT TK0SZ: EQU 3328D ;TRACK 0 LOAD SIZE ;TK1LP: EQU TK0LP+TK0SZ ;TRACK 1 TPA LOAD ADDR TK1FS: EQU 1 ;TRACK 1 1ST SECTOR TK1L LOGVC: EQU 1 ;DRV SEL DON'T LOGON ; SUBTTL PROGRAM BEGINS FORMTC: INIT: POP HL ;SAVE RETURN ADDR LD (RETADR),HL LD (SE OUTPUT PROMPT ADD '1' ;CONVERT BACK TO ASCII LD (LTRSE),A ;STORE BAD SYMBOL CALL MSGOT JR FUNBG ;REPEAT ; FUNTAB:ESELECT LD A,TRK0 ;SET TRACK # LD (TRKNO),A CALL FMTSD ;FORMAT TRACK SDENS JR NZ,FUN1 ;ERR LD A,TRK1 ;SET NEXT TRAMSGFD ;SELECT DRIVE CALL SELDR JP C,FUNBG ;ERR LD A,TRK0 ;SET UP FOR TRACK 0 LD (TRKNO),A REPT3: CALL FMTSD ;FORMAT NS JR NZ,FUN2 ;ERR LD A,TRK1 ;SET UP FOR TRACK 1 LD (TRKNO),A CALL FMTDD ;FORMAT IN DDENS JR NZ,FUN2 ;ERR LD A,T<0 !%)- "&*. #'+/  $(,0RK2 ;SET UP FOR TRACK 2 LD (TRKNO),A REPT2: CALL FMTSD ;FORMAT TRACK IN SDENS JR C,FUN2 ;ERR LD A,(TRKNO) CP TRK76 RMAT IN SDENS JR NZ,FUN4 ;ERR LD A,TRK1 ;SET UP FOR TRACK 1 LD (TRKNO),A CALL FMTDD ;FORMAT IN DDENS JR NZ,FUN4 ;ESYSTEM TRACKS LD (RWOPV),A CALL TRNSFR JR FUN6 ;DO ANOTHER SUBTTL TEXT UTILITIES ; ; MESSAGE OUTPUT ROUTINE ; MS SETTRK LD C,IDSEC ;SET ID SECTOR CALL SETSEC CALL WRSEC OR A ;SET CONDITION CODES RET Z ;IF NO ERRORS THEN RETURN CM FLAGS TO CONTROL DENSITY LD C,A CALL SETSEC CALL FMTTRK OR A ;IF NO ERROR THEN RETURN RET Z LD HL,MSGNC ;ELSE OU) ;GET SECTOR # RRA ;SECTOR x 128 LD D,A LD A,0 RRA LD E,A LD HL,($MEMRY) ;TRACK 0 LOAD CONSTANT LD BC,-128 ;C;SET UP FOR TRACK 1 LD BC,TK0SZ ;COMPENSATE FOR EXTRN ARITH. ADD HL,BC LD (SYSWP),HL LD A,TK1FS ;SET SECTOR 1 LD (SEC LD HL,(SYSWP) LD DE,SECSZ ADD HL,DE LD (SYSWP),HL JR TK1S ;REPEAT ; BLOW: LD HL,MSGNC ;OUTPUT ERROR MSG CALL MSGOTSE),A SUB 'A' JR C,ILLG CP 4 JR C,NMBRD ;IF LEGAL THEN CONTINUE ILLG: LD HL,MSGSE ;PRINT SELECT ERROR MESSAGE CALL MSWP: DW 0 ;ADDRESS POINTER RWOPV: DB 0 ;READ OR WRITE VECTOR MSGSV: DW 0 ;MESSAGE SAVE ADDR TRKNO: DB 0 ;TRACK NUMBER HOLD Sngle density format ' ORG IDSSD+32 ; DW 26D ;SECTORS PER TRACK DB 3 ;BLOCK SHIFT FACTOR DB 7 ;BLOCK MASK DB 0 ;NUJade DD Double density format ' ORG IDSDD+20H ; DW 48D ;SECTORS PER TRK DB 4 ;BLOCK SHIFT FACTOR DB 00001111B ;BLOCK  JR Z,ID2 INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT2 ; ID2: LD HL,IDSSD ;WRITE SINGLE DENS ID SECTOR CALL WRTID RR LD HL,IDSSD ;WRITE ID SECTOR CALL WRTID JR FUN4 SUBTTL FUNCTION 5 - READ SYSTEM TRACKS ; FUN5: LD HL,MSGRS ;SELECGOT: PUSH AF ;SAVE CALLER FLAGS CALL EDITOR POP AF RET ; ; CONSOLE LINKAGE ; CNSIN: CALL CI CP CTRLC ;IF CTRL-C  LD HL,MSGNC ;ELSE OUTPUT ERROR & RETURN CALL MSGOT RET FORM SUBTTL FORMAT TRACK DRIVER LINKAGE ; ; FORMAT TRACK DRTPUT ERROR MSG CALL MSGOT RET FORM SUBTTL SYSTEM TRACKS TRANSFER SUBROUTINE ; ; SYSTEM TRACKS TRANSFER FUNCTION ; OMPENSATE FOR EXTERN ARITH. ADD HL,BC ADD HL,DE LD B,H ;HL -> BC LD C,L CALL BSTDMA LD A,(RWOPV) ;DO READ/WRITE OPENO),A LD C,TRK1 ;SET UP TRACK 1 CALL SETTRK TK1S: LD A,(SECNO) ;SET UP SECTOR LD C,A CALL SETSEC LD HL,(SYSWP) ;SET  RET ; RWOP: OR A ;IF > 0 THEN WRITE JP NZ,WRSEC JP RDSEC SUBTTL SELECT DRIVE SUBR ; ; SELECT DRIVE THRU BIOS SGOT JR REPTD ; EXITD: SCF ;SET FLAG TO CALLING RTN RET ; NMBRD: LD C,A ;SELECT DRIVE LD E,LOGVC ;SELECT DRIVE ECNO: DB 0 ;SECTOR NUMBER HOLD FFLAG: DB 0 ;FORMAT FLAG (DCM) RETADR: DW 0 ;MAIN PGM RETURN ADDR STKSAV: DW 0 ;MAIN PGM STACKLL MASK DW 242D ;DISK SIZE -1 DW 63D ;DIRECTORY MAXIMUM DB 11000000B ;ALLOC 0 DB 0 ;ALLOC 1 DW 16D ;CHECK SIZE DMASK DB 1 ;NULL MASK DW 224D ;DISK SIZE -1 DW 63D ;DIRECTORY MAXIMUM DB 10000000B ;ALLOC 0 DB 0 ;ALLOC 1 DW 16D  JR FUN2 ;DO ANOTHER SUBTTL FUNCTION 4 - FORMAT JADE SYSTEM TRACKS ONLY ; FUN4: LD A,(SDFLG) ;SET FORMAT FLAGS LD (FFLT DRIVE CALL SELDR JP C,FUNBG ;DONE LD A,BSRDS ;READ SYSTEM TRACKS LD (RWOPV),A CALL TRNSFR JP FUNBG ;DONE SUTHEN REBOOT RET NZ LD SP,(STKSAV) ;RESTORE PTRS LD HL,(RETADR) PUSH HL RET SUBTTL WRITE DISKETTE IDENTITY ; ; IVER ; FMTSD: LD HL,FT3740 ;SET INJECTION ADDR JR STDMA ; FMTDD: LD HL,FTJ48D ;SET INJECTION ADDR STDMA: LD B,H ;SETTRNSFR: LD HL,TK0SL ;SET SECTOR LIST ADDR INC HL ;BYPASS ID SECT. LD (SYSWP),HL ;SET WORK PTR LD C,TRK0 ;SET TRACK CALRATION CALL RWOP ;GO READ OR WRITE OR A ;IF ERROR THEN EXIT JR NZ,BLOW LD HL,(SYSWP) ;IF LAST SECTOR ON 0 THEN GOTO TRDMA ADDR LD B,H ;HL -> BC LD C,L CALL BSTDMA LD A,(RWOPV) ;DO READ/WRITE OPERATION CALL RWOP OR A ;IF ERROR THEN E; SELDR: LD (MSGSV),HL ;SAVE MESSAGE ADDR REPTD: LD HL,(MSGSV) ;PRINT MESSAGE CALL MSGOT CALL CNSIN ;GET INPUT AND 5FH BUT IGNORE READ ERROR CALL SELDSK LD HL,MSGXX ;PRINT TYPE CR WHEN READY MSG CALL MSGOT CALL CNSIN ;IF NOT CR THEN REPEA PTR ; ; 3740 SECTOR TRANSLATION ; TK0SL: DB 1,7,0DH,13H,19H,5 DB 0BH,11H,17H,3,9H,0FH DB 15H,2,8H,0EH,14H,1AH DB 6,W 2 ;TRACK OFFSET ; ORG IDSSD + 30H ;LOCATE DCM BLK ; DB 6 ;SECTOR STAGGER (TRNS) SDFLG: DB 00000010B ;DISKETTE FL ;CHECK SIZE DW 2 ;TRACK OFFSET ; ORG IDSDD+30H ;LOCATE DCM BLOCK ; DB 6 ;SECTOR STAGGER (TRNS) DDFLG: DB 00000110B ;AG),A LD HL,MSGFD ;SET DRIVE CALL SELDR JP C,FUNBG ;ERR LD A,TRK0 ;SET UP FOR TRACK 0 LD (TRKNO),A CALL FMTSD ;FOBTTL FUNCTION 6 - WRITE SYSTEM TRACKS ; FUN6: LD HL,MSGWS ;SELECT DRIVE CALL SELDR JP C,FUNBG ;DONE LD A,BSWRS ;WRITE WRITE ID SECTOR ; WRTID: LD B,H ;SET WRITE PTR TO ID SECTOR IMAGE LD C,L CALL BSTDMA LD C,TRK0 ;SET TRACK 0 CALL UP FOR BIOS BLOCK MOVE TO DC LD C,L CALL BSTDMA LD A,(TRKNO) ;SET TRACK # LD C,A CALL SETTRK LD A,(FFLAG) ;SET DL SETTRK TK0S: LD HL,(SYSWP) ;SET SECTOR LD C,(HL) CALL SETSEC LD HL,(SYSWP) ;SET DMA ADDR AND A ;CLR CARRY LD A,(HLK 1 LD A,(HL) CP 16H JR Z,TRK1P INC HL ;ELSE BUMP SECTOR & REPEAT LD (SYSWP),HL JR TK0S ; TRK1P: LD HL,($MEMRY) XIT JR NZ,BLOW LD A,(SECNO) ;IF LAST SECTOR THEN RETURN CP TK1LS RET Z INC A ;ELSE BUMP SECTOR & PTR LD (SECNO),A  ;INSURE UPPER CASE CP CR ;IF RETURN THEN EXIT JR Z,EXITD LD (DRLTR),A ;ELSE SAVE DRIVE LETTER & TEST FOR LEGAL LD (LTRT CP CR JR NZ,REPTD AND A ;ELSE CLEAR FLAG & RETURN RET SUBTTL DATA AREAS DATA ; ; WORKING VARIABLES ; SY0CH,12H,18H,4,0AH DB 10H,16H SUBTTL IDENTITY SECTORS ; ; JADE SINGLE DENSITY IDENTITY SECTOR ; IDSSD: DB 'Jade DD SiAGS (TYPE OF FORMAT) ; ORG IDSSD+SECSZ ;EXTEND FULL SECTOR FORM ; ; JADE DOUBLE DENSITY IDENTITY SECTOR ; IDSDD: DB 'DISKETTE FLAGS (FORMAT TYPE) ; ORG IDSDD+SECSZ ;EXTEND TO FULL SECTOR SUBTTL TEXT MESSAGES ; MSGBG: DB CR,LF,'Jade DD D=0 !%)- "&*. #'+/  $(,0isk Formatter',CR DB 'Ver 1.0 by Girvin Herr',CR DB '(c) 1981 GRH Electronics, Cupertino, CA',CR DB 0 ; MSGFL: DB CR,SGSE: DB CR,LF LTRSE: DB ' IS NOT A VALID SELECTION',0 ; MSGFD: DB CR,LF DB 'Write format on drive A-D (RETURN to reselect'3740 - FT3740 + FMTEA] LD E,26D ;SET # SECTORS BG3740: LD B,40D ;WRITE PREAMBLE: START WITH 40 FF BYTES SRPT1: IN A,XPDSH  WRITE END OF GAP 3 - 6 00H BYTES SRPT4: IN A,XPDSH LD A,ZEROS XOR C OUT WDDTA,A DJNZ SRPT4 IN A,XPDSH ;WRITE ID MARLD B,11D ;WRITE GAP 2 - START WITH 11 FFH BYTES SRPT5: IN A,XPDSH LD A,ONES XOR C OUT WDDTA,A DJNZ SRPT5 LD B,6 ;THE LD A,ONES XOR C OUT WDDTA,A DJNZ SRPT8 DEC E ;# SECTORS -1 JR NZ,RP3740 ;IF ANY LEFT THEN REPEAT LD HL,0 ;COUNT 8D: LD B,80D ;WRITE PREAMBLE: START WITH 80 4E BYTES DRPT1: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT1 LD B,12D48D: LD B,8D ;THEN WRITE END OF GAP 3 - 8 00H BYTES DRPT2: IN A,XPDSH XOR A XOR C OUT WDDTA,A DJNZ DRPT2 LD B,3 ;WRIA,0 XOR C OUT WDDTA,A IN A,XPDSH ;WRITE CRC WORD LD A,0F7H XOR C OUT WDDTA,A LD B,22D ;WRITE GAP 2 - START WITH 2IN A,XPDSH LD A,0E5H XOR C OUT WDDTA,A DJNZ DRPT7 IN A,XPDSH ;WRITE CRC WORD LD A,0F7H XOR C OUT WDDTA,A LD BD,37D,41D,45D DB 2,6,10D,14D,18D,22D,26D,30D,34D,38D,42D,46D DB 3,7,11D,15D,19D,23D,27D,31D,35D,39D,43D,47D DB 4,8D,12D,16LF,'****** Functions List ******',CR DB '1. Format Jade Double Density 8',22H,CR DB '2. Format Jade Single Density 8',22H, DB '): ',0 ; MSGRS: DB CR,LF DB 'Read system from drive: ',0 ; MSGWS: DB CR,LF DB 'Write system to drive (RETURN to r;WAIT FOR DATA REQ LD A,ONES XOR C OUT WDDTA,A ;WRITE DATA DJNZ SRPT1 LD B,6 ;THEN WRITE 6 00H BYTES SRPT2: IN A,XPK LD A,0FEH XOR C OUT WDDTA,A IN A,XPDSH ;WRITE TRACK # IN A,WDTRK OUT WDDTA,A IN A,XPDSH ;WRITE SIDE # LD A,0N WRITE 6 00H BYTES SRPT6: IN A,XPDSH LD A,ZEROS XOR C OUT WDDTA,A DJNZ SRPT6 IN A,XPDSH ;WRITE DATA MARK LD A,0FB= 0 SRPT9: IN A,XPDSH LD A,ONES ;WRITE GAP 4 UNTIL INTERRUPT XOR C OUT WDDTA,A INC HL ;COUNT GAP 4 LENGTH JR SRPT9  ;THEN WRITE 12 00H BYTES DRPT10: IN A,XPDSH XOR A XOR C OUT WDDTA,A DJNZ DRPT10 LD B,3 ;WRITE GAP C2 - 3 F6H BYTESTE GAP A1 - 3 F5H BYTES DRPT3: IN A,XPDSH LD A,0F5H XOR C OUT WDDTA,A DJNZ DRPT3 IN A,XPDSH ;WRITE ID MARK LD A,0F2 4EH BYTES DRPT4: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT4 LD B,8D ;THEN WRITE 8 00H BYTES DRPT5: IN A,XPD,24D ;WRITE GAP 3 - START WITH 24 4EH BYTES DRPT8: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT8 DEC E ;IF SECTORD,20D,24D,28D,32D,36D,40D,44D,48D ; END CR DB '3. Format IBM 3740 Standard 8',22H,CR DB '4. Format system tracks only.',CR DB '5. Read system tracks image.',CR e-select): ' DB 0 ; MSGNC: DB CR,LF DB 'Transfer Incomplete',0 ; MSGXX: DB CR,LF DB 'Type RETURN when drive ' DRLTR: DSH LD A,ZEROS XOR C OUT WDDTA,A DJNZ SRPT2 IN A,XPDSH ;WRITE INDEX MARK LD A,0FCH XOR C OUT WDDTA,A LD B,26D XOR C OUT WDDTA,A IN A,XPDSH ;WRITE SECTOR # LD A,(HL) XOR C OUT WDDTA,A INC HL IN A,XPDSH ;WRITE SECTOR SIZEH XOR C OUT WDDTA,A LD B,128D ;WRITE 128 E5 BYTES SRPT7: IN A,XPDSH LD A,0E5H XOR C OUT WDDTA,A DJNZ SRPT7 IN  ; SS3740: DB 1,2,3,4,5,6,7,8D,9D,10D,11D,12D,13D,14D,15D,16D DB 17D,18D,19D,20D,21D,22D,23D,24D,25D,26D SUBTTL DOUBLE D  DRPT11: IN A,XPDSH LD A,0F6H XOR C OUT WDDTA,A DJNZ DRPT11 IN A,XPDSH ;WRITE INDEX MARK LD A,0FCH XOR C OUT WEH XOR C OUT WDDTA,A IN A,XPDSH ;WRITE TRACK # IN A,WDTRK OUT WDDTA,A IN A,XPDSH ;WRITE SIDE # XOR A XOR C OSH XOR A XOR C OUT WDDTA,A DJNZ DRPT5 LD B,3 ;WRITE GAP A1 - 3 F5H BYTES DRPT6: IN A,XPDSH LD A,0F5H XOR C OUTS LEFT THEN REPEAT JP NZ,[RPJ48D - FTJ48D + FMTEA] LD L,E LD H,L DRPT9: IN A,XPDSH LD A,4EH ;WRITE GAP 4: 4EH BYTES UNTDB '6. Write system tracks image.',CR DB 'or use ctrl-C for return to main menu.',CR,LF DB 'Enter function number: ',0 ; MDB ' is ready. ',0 SUBTTL SINGLE DENSITY INJECTION MODULE FORMATTER FT3740: EQU $ DB 'FORMAT!' DB 'S' ; LD HL,[SS ;WRITE GAP 1 - START WITH 26 FFH BYTES SRPT3: IN A,XPDSH LD A,ONES XOR C OUT WDDTA,A DJNZ SRPT3 RP3740: LD B,6 ;THEN LD A,0 ;(128) XOR C OUT WDDTA,A IN A,XPDSH ;WRITE CRC WORD (2 BYTES WRITTEN) LD A,0F7H XOR C OUT WDDTA,A A,XPDSH ;WRITE CRC WORD LD A,0F7H XOR C OUT WDDTA,A LD B,27D ;WRITE GAP 3 - START WITH 27 FFH BYTES SRPT8: IN A,XPDSH DOUBLE DENSITY INJECTION MODULE FTJ48D: DB 'FORMAT!D' ; LD HL,[SSJ48D - FTJ48D + FMTEA] LD E,48D ;SECTOR COUNT BGJ4DDTA,A LD B,32D ;WRITE GAP 1 - START WITH 32 4EH BYTES DRPT12: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT12 RPJUT WDDTA,A IN A,XPDSH ;WRITE SECTOR # LD A,(HL) XOR C OUT WDDTA,A INC HL IN A,XPDSH ;WRITE SECTOR SIZE (128) LD  WDDTA,A DJNZ DRPT6 IN A,XPDSH ;WRITE DATA MARK LD A,0FBH XOR C OUT WDDTA,A LD B,128D ;WRITE 128 E5 BYTES DRPT7: IL INTERRUPT XOR C OUT WDDTA,A INC HL ;COUNT NUMBER OF GAP 4 BYTES JR DRPT9 ; SSJ48D: DB 1,5,9D,13D,17D,21D,25D,29D,33>0 !%)- "&*. #'+/  $(,0 TITLE DIAGNOSTIC DISK UTILITY LIST NOCOND ;************************************************************* ; ; (c) 1981 GRer data in CP/M DDT format. ; SUbstitute: Allows alteration of buffer data. ; FIll: Allows filling buffer with data ; 1.1 - Add DDT type buffer modification comands, ; Add Hex file read, limit commands to 2 chars, ; Modify source for ASMB,  ; DDISKF - THE FORMATTER ; FCBFMT - FCB FORMATTER ; UTIL - UTILITIES LIBRARY ; ASCII - ASCII ROUTINES LIBRARY ; CONVERT - 0CC00H DFDRV: EQU 0 ;INITIAL DEFAULT DRIVE FMTSZ: EQU 100H ;FORMAT BUFFER SIZE NDRVS: EQU 2 ; ; CONSTANTS ; L1K: EQU 102.REL RTNS: EXTRN BSELDK,SETTRK,SETSEC,BSTDMA,RDSEC,WRSEC,SECTRN EXTRN FMTTRK ; DDISKF.REL RTNS: EXTRN FORMTC ; UTI LD HL,OPTMSG ;OUTPUT OPTIONS CALL EDITOR MAINLP: LD BC,INBUFR ;SET UP FOR COMMAND LD (CMDPTR),BC LD A,BUFSZ LD (BC),AC HL LD A,(DE) ;IF COMMAND <> TABLE THEN MOVE ON CP (HL) JR NZ,NOMAT INC DE DJNZ CMDLP INC HL ;FOUND, GET EXECOT LAST THEN LOOP LD DE,(CMDPTR) JR NZ,NXTCMD ; ; INVALID COMMAND- ERROR ; CMDERR: LD HL,INVCM ;OUTPUT INVALID COMMAND  addr filename.HEX',CR DB 'MOve first, last, dest',CR DB 'FIll first, last, data',CR DB 'DIsplay <,last>',CR ; DB 2,'FO' ;FORMAT DW FORMTC ; DB 2,'EX' ;EXIT DW EXITC ; DB 2,'HE' ;HELP DW HELPC ; DB 1,'?' ;SAME AS HELP  FLAG JR DACCES ; ; WRITE SECTOR COMMAND ; WRITEC: LD A,TRUE ;SET WRITE COMMAND DACCES: LD (WRFLG),A CALL DSETUP DKH Electronics, CUPERTINO, CA ; ;************************************************************* ; ; Except for the CP/M vers MOve: Allows moving buffer data to new buffer location. ; LOad: Allows loading a HEX format file into buffer ; (R ; remove unused code. ; 1.2 - Try rel file linking again. ; ; 2.0 - Clean up for Disk version only. Removed most cond- ;NUMBER CONVERSION ROUTINES LIBRARY ; (CP/M VERSION:) ; CPMIOB - CP/M SYSTEM CALLS WITH PARAMS PASSED IN BC ; BIOS - CP/M BIOS4D ; BUFSZ: EQU 82 MAXSEC: EQU 48 SECSZ: EQU 128 ; ; ASCII CONSTANTS ; CTRLC EQU 3 LF: EQU 0AH FF: EQU 0CH CR: EQU 0L.REL RTNS: EXTRN MOVEM,FILLM,DISPM,SUBSM,READHX EXTRN DISTRT,DISEND ; EXTRN FCBFMT ENTRY INFCB,DEFBFR,$MEMRY ENTRY N PUSH BC LD C,'*' ;OUTPUT PROMPT CALL CO POP BC CALL RDCON LD HL,INBUFR+1 ;PUT NUL AT END OF LINE LD A,(HL) INCUTION ADDR LD E,(HL) INC HL LD D,(HL) EX DE,HL LD DE,CMDRET ;SET UP RETURN ADDR PUSH DE LD C,' ' ;SET COMMANMESSAGE CALL EDITOR JP MAINLP ; SGNONM: DB CR,LF,88H,'Diagnostic Disk Utility',83H,'Ver ' DB HIGH VERSION DB '.' DB DB 'SUbstitute addr',CR DB 'EXit return to system',CR,LF,0 ; INVCM: DB CR,LF,'Invalid command! - Re-enter.',CR,LF,LF,0 ; CDW HELPC ; ENTCNT: EQU 11 SUBTTL COMMANDS ; ; EXIT COMMAND ; EXITC: LD SP,(SYSSTK) ;RESTORE STACK JP 0 ; ; HELP COLP: LD A,(DTRAN) ;IF TRANSLATE FLAG = TRUE THEN ; TRANSLATE LD DE,SDTRAN ;SET TRANSLATION TABLE PTR OR A LD A,(DSEion relying upon the BIOS routines, ; DDISK is a stand-alone disk access program for the ; JADE DD Disk controller card. Iequires CP/M) ; REad: reads specified number of sectors into memory ; WRite: writes specified sector(s) to disk. ;  itionals & superfluous source code. PS. Rel worked! ; VERSION EQU '20' ; ;************************************************ CALLS LIBRARY ; ;************************************************************ SUBTTL DECLARATIONS TRUE EQU 1 FALSE EQU DH CTRLX: EQU 18H AESC: EQU 1BH USCORE: EQU 5FH DEL: EQU 7FH SUBTTL ASSEMBLER DIRECTIVES ; ASCII.REL RTNS: EXTRN SEUMPARS,PARAM1,PARAM2,PARAM3,OFFSET SUBTTL MAIN PROGRAM $MEMRY: DW 0 ;LOCATION FOR FREE MEMORY PTR ; ; THIS IS THE ENTRY  HL PUSH HL ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD (HL),0 POP HL CALL SKIPOH ;IGNORE SPACES JR Z,CMDERR ;OD PTR TO NEXT OPERAND PUSH HL LD HL,(CMDPTR) CALL SERCHH LD (CMDPTR),HL POP HL JP (HL) ; CMDRET: PUSH AF ;TERMINALOW VERSION DB CR,88H,'(c) 1981 GRH Electronics',CR,0 OPTMSG: DB CR,'OPTIONS:',CR DB ' Prints this list',CR DB 'MDTBL: DB ENTCNT DB 2,'MO' ;MOVE DW MOVEC ; DB 2,'FI' ;FILL DW FILLC ; DB 2,'DI' ;DISPLAY DW DISPC ; DB 2,'SU' MMAND ; HELPC: LD HL,OPTMSG CALL EDITOR OR A RET ; DATA ; SYSSTK: DW 0 CMDPTR: DW INBUFR ; INBUFR: DB BUFSZ ;COC) LD C,A LD B,0 JR Z,TRNOT CP 27D ;IF ATTEMPTING TO TRANSLATE > 26 ; SECTORS THEN JR NC,TRNOT ;NO TRANSLATION. t allows the following ; commands: ; FOrmat: allows formatting a new disk to JADE formats. ; DIsplay: Displays buff EXit: returns to system. ; ;************************************************************* ; revisions: ; 1.0 - Release ;************ ; ; NOTE: THE FOLLOWING MODULES MUST BE LINKED TOGETHER ; WITH THIS ONE IN THIS ORDER: ; ; DDISK - THIS MODULE0 CPMVERS EQU TRUE INCLUD EQU FALSE ; DEFBFR EQU 0080H BDOS EQU 0005H TPA EQU 0100H ; ; DISK CONTROLLER ; WINDOW: EQU RCHH,SKIPOH,EDITOR,CRLF ; CONVERT.REL RTNS: EXTRN GETHEX,GETDEC ; CPMIOB.REL RTNS: EXTRN OPEN,RDCON,CO,CI ; BIOSPOINT FROM THE SYSTEM: ; DDISK: LD (SYSSTK),SP ;SAVE STACK LD SP,STACK LD HL,SGNONM ;OUTPUT SIGN-ON MESSAGE CALL EDITOR OPS - NO COMMAND EX DE,HL LD (CMDPTR),DE LD HL,CMDTBL LD C,(HL) ;GET ENTRY COUNT NXTCMD: INC HL LD B,(HL) CMDLP: INTE LINE CALL CRLF POP AF JP NC,MAINLP JP CMDERR ; NOMAT: INC HL ;WASTE TABLE ENTRY DJNZ NOMAT INC HL DEC C ;IF NFOrmat a disk',CR DB 'REad :drive @trk >sec #cnt *addr %(translate)',CR DB 'WRite :drv @trk >sec #cnt *addr %',CR DB 'LOad;SUBSTITUTE DW SUBSC ; DB 2,'LO' ;LOAD HEX DW LOADHXC ; DB 2,'RE' ;READ DW READC ; DB 2,'WR' ;WRITE DW WRITEC NSOLE READ BUFFER LENGTH DB 0 ;CONSOLE CHARS READ DS BUFSZ REL ; ; READ SECTOR COMMAND ; READC: XOR A ;CLEAR WRITE CALL SECTRN LD C,L TRNOT: CALL SETSEC LD BC,(DBUFRP) CALL BSTDMA LD A,(WRFLG) OR A JR NZ,WRT CALL RDSEC JR OP?0 !%)- "&*. #'+/  $(,0DONE ; WRT: CALL WRSEC OPDONE: BIT 7,A ;IF ERROR THEN EXIT JR Z,OPOK LD HL,DSKERM CALL EDITOR OR A RET ; OPOK: LDOR COUNT ; DBUFRP: DW 0 ;DISK DATA BUFFER PTR ; WRFLG: DB FALSE ;DISK WRITE FLAG DTRAN: DB FALSE ;SECTOR TRANSLATION FLAG RKOK INC HL CALL SKIPOH PUSH HL POP BC CALL GETDEC LD A,L TRKOK: LD (DTRK),A LD C,A CALL SETTRK LD HL,(CMDPTR,'*' CALL SERCHH LD DE,($MEMRY) JR Z,BFROK PUSH DE INC HL CALL SKIPOH PUSH HL POP BC CALL GETHEX POP DE ;ADADDOFF JP C,BNDSERR LD (PARAM1),HL LD HL,(PARAM2) CALL ADDOFF JP C,BNDSERR LD (PARAM2),HL LD HL,(PARAM3) CALL AD JP C,BNDSERR RET SUBTTL DISPLAY MEMORY COMMAND ; ; DISPLAY MEMORY COMMAND - TRICKY ; ENTRY- IF PARAM1 = -1 THEN OLD  LD A,L OR H JR Z,DISP3 CALL ADDOFF ;P2 = P2 + OFFSET JR DISP4 ; DISP3: LD DE,16*16 ;ELSE P2 = P1 + 16 LINES LD HLE COMAND ; LOADHXC: LD HL,(CMDPTR) CALL SKIPOH ;IF NO OPERAND THEN ERR JP Z,DATAERR LD (CMDPTR),HL ;P1 = VALUE 1 PU INC HL LD (HL),'X' LD BC,INFCB CALL OPEN INC A JR NZ,LOAD1 LD HL,FNFMSG CALL EDITOR OR A RET ; LOAD1: LD Hex File Error',CR,0 HXCONVE: DB CR,'Hex Conversion Error',CR,0 ; BNDSM: DB CR,'Command Value out of Bounds!',CR,0 DATAM: PACE BEFORE ; EXIT - NUMPARS = ACTUAL PARAMETER COUNT (0-3) ACCEPTED ; A = NUMPARS ; PARAM1-3 = PARAMETER VALUES ; PA LD (PARAM1),HL ;SAVE P1 LD HL,NUMPARS INC (HL) GETP2: LD HL,(CMDPTR) ;GET NEXT PARAM LD C,',' CALL SERCHH RET Z IN HL,(DBUFRP) ;PTR := PTR + SECTOR SIZE LD DE,SECSZ ADD HL,DE LD (DBUFRP),HL LD HL,DSEC INC (HL) INC HL DEC (HL) ;I REL ; ; DISK PARAMETER FETCH SUBR ; DSETUP: LD HL,(CMDPTR) LD C,':' ;FETCH DRIVE # CALL SERCHH LD A,1 ;DEFAULT DR) ;FETCH SECTOR # LD C,'>' CALL SERCHH LD A,1 ;DEFAULT = 1 JR Z,SECOK1 INC HL CALL SKIPOH PUSH HL POP BC CALLD IN OFFSET ADD HL,DE EX DE,HL BFROK: LD (DBUFRP),DE LD HL,(CMDPTR) ;SET TRANSLATION FLAG LD C,'%' CALL SERCHH LD ADOFF JP C,BNDSERR LD (PARAM3),HL CALL MOVEM ;GOTO EXTERNAL SUBR JP C,BNDSERR RET SUBTTL FILL MEMORY COMMAND ; ;PARAM2 IS USED FOR PARAM1 ; IF PARAM2 = 0 THEN 16 LINES ARE OUTPUT ; DISPC: CALL GETPARMS CP 3 ;IF PARM CNT > 2 THEN ERR,(PARAM1) ADD HL,DE DISP4: LD (PARAM2),HL CALL DISPM ;EXTERNAL SUBR OR A RET SUBTTL SUBSTITUTE MEMORY COMMAND ; SH HL POP BC CALL GETHEX LD (PARAM1),HL LD HL,(CMDPTR) ;GET FILENAME LD C,' ' CALL SERCHH JP Z,DATAERR LD (CMDPTBC,(PARAM1) LD DE,(BDOS+1) CALL READHX ;EXTERNAL SUBR OR A ;IF NO ERRORS THEN RETURN RET Z AND 3 DEC A ;COMPUTE ODB CR,'Not Enough Data!',CR,0 ; DATAERR: LD HL,DATAM CALL EDITOR OR A RET ; BNDSERR: LD HL,BNDSM CALL EDITOR ORAM1 = -1 IF LEADING ',' ENCOUNTERED ; PARAM2-3 = 0 IF NO PARAMS GIVEN ; GETPARMS: LD HL,0 ;INIT VALUES LD (NUMPARS),HC HL ;PASS ',' CALL SKIPOH RET Z LD (CMDPTR),HL ;SAVE PTR PUSH HL POP BC CALL GETHEX LD (PARAM2),HL LD HL,NUMPAF COUNT = 0 THEN DONE JR NZ,DKLP RET ; DSKERM: DB CR,LF,'Disk Error',CR,LF,0 ; ; DISK ACCESS TABLE ; DATA DDRIVE: DIVE 1 JR Z,DRVOK INC HL CALL SKIPOH PUSH HL POP BC CALL GETDEC LD A,L DRVOK: LD (DDRIVE),A LD C,A LD E,0 ;LO GETDEC LD A,L SECOK1: LD (DSEC),A LD C,A CALL SETSEC LD HL,(CMDPTR) LD C,'#' CALL SERCHH LD DE,1 JR Z,CNTOK ,FALSE JR Z,NOTRN LD A,TRUE NOTRN: LD (DTRAN),A RET SUBTTL MOVE MEMORY COMMAND ; ; MOVE COMAND ; MOVEC: CALL GETP FILL COMAND ; FILLC: CALL GETPARMS JP C,DATAERR ;IF PARM CNT < 3 THEN ERR CP 3 JP C,DATAERR LD HL,(PARAM1) CALL ADD JP NC,DATAERR LD C,A LD HL,(PARAM1) INC HL ;IF P1 <> -1 THEN LD A,L OR H DEC HL JR Z,DISP1 CALL ADDOFF ;P1 ; SUBSTITUTE MEMORY COMMAND ; SUBSC: CALL GETPARMS JP C,DATAERR CP 2 ;IF COUNT > 1 THEN ERR JP NC,DATAERR LD HL,(PARAR),HL LD HL,(PARAM1) ;ADD OFFSET CALL ADDOFF JP C,BNDSERR LD (PARAM1),HL LD HL,(CMDPTR) LD DE,INFCB CALL FCBFMT FFSET SLA A LD HL,ERRMTBL ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD A,(HL) INC HL LD H,(HL) LD L,A CALL EDR A RET ; ; 3740 FORMAT PARAMETERS **** CP/M SINGLE DENSITY **** ; SDTRAN: DB 1,7,13,19,25,5,11,17,23,3,9,15,21 DB 2,8L LD (PARAM2),HL LD (PARAM3),HL DEC HL ;P1 = -1 LD (PARAM1),HL LD HL,(CMDPTR) ;SKIP LEADING SPACES CALL SKIPOH SCRS ;CNT = CNT + 1 INC (HL) GETP3: LD HL,(CMDPTR) LD C,',' CALL SERCHH RET Z INC HL CALL SKIPOH RET Z LD (CMDPTRB 0 ;DISK DRIVE DTRK: DB 1 ;TRACK # ; *** THESE TWO MUST BE IN THIS ORDER TO WORK *** DSEC: DB 1 ;SECTOR # DSCNT: DW 1 ;SECTGON VECTOR := FULL LOGON CALL BSELDK LD HL,(CMDPTR) LD C,'@' ;FETCH TRACK # CALL SERCHH LD A,1 ;DEFAULT = 1 JR Z,TINC HL CALL SKIPOH PUSH HL POP BC CALL GETDEC EX DE,HL CNTOK: LD (DSCNT),DE LD HL,(CMDPTR) ;FETCH BUFFER PTR LD CARMS ;GET PARAMS JP C,DATAERR ;IF NO OPERANDS THEN RETURN CP 3 JP C,DATAERR LD HL,(PARAM1) ;ADD OFFSET TO PARAMS CALL OFF JP C,BNDSERR LD (PARAM1),HL LD HL,(PARAM2) CALL ADDOFF JP C,BNDSERR LD (PARAM2),HL CALL FILLM ;GOTO EXT SUBR = P1 + OFFSET JR DISP2 ; DISP1: LD HL,(DISEND) ;ELSE P1 = LAST END DISP2: LD (PARAM1),HL LD HL,(PARAM2) ;IF P2 <> 0 THEN M1) CALL ADDOFF JP C,BNDSERR LD (PARAM1),HL JP SUBSM ;EXTERNAL SUBR SUBTTL LOAD HEX FILE COMMAND ; ; LOAD HEX FILLD A,0 ;FUDGE UNTIL NEW FCBFMT PROM BURNED LD (INRECD),A LD HL,INTYPE LD (HL),'H' ;MAKE HEX FILE INC HL LD (HL),'E' ITOR OR A RET ; ERRMTBL: DW HXFILER DW HXCONVE DW BNDSM ; FNFMSG: DB CR,'File Not Found!',CR,0 HXFILER: DB CR,',14,20,26,6,12,18,24,4,10,16,22 SUBTTL SUBROUTINES ; ; GET PARAMETERS SUBR ; ENTRY- (CMDPTR) = POINTER TO 1ST PARAM OR SF RET Z LD (CMDPTR),HL LD A,(HL) ;IF CHAR = ',' THEN SKIP TO 2ND CP ',' JR Z,GETP2 PUSH HL POP BC CALL GETHEX ),HL PUSH HL POP BC CALL GETHEX LD (PARAM3),HL LD A,(NUMPARS) ;CNT = CNT + 1 INC A LD (NUMPARS),A RET ; ; ADD @0 !%)- "&*. #'+/  $(,0OFFSET SUBR ; ENTRY- HL = VALUE TO BE OFFSET ; EXIT - HL = NEW VALUE ; DE = MODIFIED ; CF = OVERFLOW ; ADDOFF: LDISK (INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)ABORTED$BAD PARAMETER$INVALID USER NUMBER$RECORD TOO LONG$INVALID DIGIT$END OF FILE, CTL-Z?$CHECKSUM ERROR$CORRECT ERROR, TYPE R221@:2!o6+6+6!6#6!6#6:G*o .!N6:^*M^!K6!6!6+6' :$HHͯ :^!w:<2:0}:@E}:!S!W6: z!]6:cm!c6:_z!_6l!p+q* !q*& *M *M !p+q*!!p+q*"!p+q*$!6  "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{& :2!q: " *M n :c4 *M n :2!c:Q !c:2: !:cw>!n !5 Y : { !6!q/H:_2:!q:A/>Z!/H8: 2::=O>m:W!Q} Hmd>9>!6:2*M!E DE,(OFFSET) ADD HL,DE RET ;OVERFLOW ERROR ; DATA NUMPARS DB 0 ;NUBER OF PARAMETERS ENTERED PARAM1 DW 0 ;1ST PARAM E(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)ETURN OR CTL-Z$INVALID FORMAT$HEX$$$$NO DIRECTORY SPACE$NO FILE$COM$START NOT FOUND$QUIT NOT FOUND$CANNOT CLOSE DESTINATION FILE::=2K  :ʤ\:ҷ\x'Ͳ:!\͢  :͈'!  ::,: HHҰͯ : 2ó:E:1:2v!q!*8!*6: > !kp+q*j> >ڪ Þ !qp+q/ *pDM9: :M2r:N!r !:r *r& N!r4 !6: :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*M:!lwҙ  â :0O !q:O| :O| !6:]2l:o'2o:n'2n:m'2m*mMͣ *nMͣ *oMͣ :] ^#V͎ڗO **~2*#"m2m͖ 2m!6m!6m!6 m2mNTERED PARAM2 DW 0 ;2ND PARAM ENTERED PARAM3 DW 0 ;3RD PARAM ENTERED OFFSET EQU $MEMRY ;POINTER TO DATA BUFFER ; INFCB: D COPYRIGHT (C) 1979, DIGITAL RESEARCH, PIP VERS 1.5$$$ SUB =.:,<> _[]INPIRDPTRUR1UR2RDROUTLPTUL1PRNLSTPTPUP1UP2PU$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$$$$$$$NOT FOUND$COPYING -$REQUIRES CP/M 2.0 OR NEWER FOR OPERATION.$UNRECOGNI:$: $͈Ͳ!N6' :!Cwͯ !6:^͢c!6{:/>!/H{ͯ :<2ͦ>ͦ!q:_  !p+q.*   !q*&!p+q*2͔: :ͳ.!ws+p+q+p+q:w=2wN *s*u w*s#"s*u#"u' !"*M^7 !x6:!xھ **DM͆ ! ^#V͎ * :w*#" = = = = = ͯ  *M !6q  !6q  !6q  *& !:   *}2D" * * *&"!q:UY: Y:ҩ: ʩ:_2ʘ:€!6<ͯ m!62m!62m!62m!62m'2:2:TҒ:2S 9 INTYPE: DS 3 DS INFCB + 36 - $ INRECD EQU INFCB + 32 ;FUDGE UNTIL NEW PROM BURNED! DS 128 ; STACK: EQU $ ; END DDNTTYCRTUC1CONNULEOFDISK READ ERROR$DISK WRITE ERROR$VERIFY ERROR$NOT A CHARACTER SINK$READER STOPPING $NOT A CHARACTER SOURCE$ZED DESTINATION$CANNOT WRITE$INVALID PIP FORMAT$CANNOT READ$INVALID SEPARATOR$1 :2L> ̈́M9 Š ::=HҮͯ !6:Ҿ:2 !6::/H͈;!6:> !/>!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*2yʭ :yʗ ͯ *"*6:2x÷ *"!x4d !"/ !j}=2| !"*KM^'_ !z6:|!z1 *6à  !6 à  !60à  *& !6  !6  !6  *& . 1 4 7 : = F P [ f q  :<2!ژ!6 >!]Ҥ; !6:Q::H: !6*M : !6!q:a/>z!!6*ME:2::Ҳ:<22ý: 2:} >ͯ :i:2:d*M:[ A0 !%)- "&*. #'+/  $(,0*M:>!(:=2%> >>!F!5+N! ~2!4<2T>>!b}*bMͭz:b2!b6:<2é>!*M8):[ͱ!N5!6ñ:5!6#6>!ڰ!6:<2O>/:!O!T *M͡H~K:÷:S:QHI:N<22: H@"2Í202O> c!6Í202O> ڍ*&O*-:>>!p+q:,!6*DM9:<!6:z 2W!6D*&L :w:<2Ov*:>=2*">!b!ͯ >!`0ͯ !q:E:24J!46*}a!44EJ *KM^'́:‚:H:H"!6!4:_jYO jM*"S*" 3@bl*M1͓!""DM!  ::=H-\:N2O_og_{ozg^#V))) _{ozg^#V) d^#V|g}o n_{o 'XOR!', 'NOT!', 'MOD!', ERNAL!', 'STRUCTURE!', 'REENTRANT!',  'MINUS!', 'EOF!', */ '*'); /* LISTAFTNPTR,FILENAM,ACCESS,ECHOAFTN,STATS) EXTERNAL; DECLARE (AFTNPTR,FILENAM,ACCESS,ECHOAFTN,STATS) ADDRESS; END OPEN; READ`ҥ*`MͭҞ!`6!6> :é:(!q:!wO! ~2*& :w>!:!4!6>:N<2N!¡!6[–ͱ!N5:2:2!4=:[¼ͱ4:!6:.2O8: :* ͇g& !sc*&P :w:·>!ұͯ :22:_!6=!6>'!E!4!p+q*0 !20O> ڒ:0:AO>Ҥ::A }}Hͬ!wͻO`idͻV[2O>2:!X!6:! !36'n::0:f9OY#9.3'ͳ.:020' 'ͳ'7 6'7 *M^͆ \͔!":͎H*#"ͧÝ/ :>͛9ͯ .*#":_!zgO{ozgi`N#Fogo&og H ©=¨ 'DECLARE!', 'BYTE!', 'ADDRESS!',  'PUBLIC!', 'AT!', 'INTERRUPT!',  IS TERMINATED BY '*' */ $EJECT /**********************************************************/ /* : /* GET 'CNT' BYTES FROM A FILE THAT HAS BEEN OPENED */ PROCEDURE(AFTN,BUFR,CNT,ACT,STATS) EXTERNAL; DECLARE (AFTN,BUFR> *N& N2 !p+q!6!6+6 !6: S: M!6g8:N2M*M8p!6!6!6>!:[ ͱ!N5!6:%:<2*6 * 6å!q!6> !d*&I :]>!4A>:<2O* :w:?†r+s+p+q*~$7*>*>H&>*#"*#"> 2:R͎:!6!6=2:ʙ!6:“H:=O!L NE!4 E E:/.*&L 6$L9k9.Xͯ *KM^020!j>A+!s!"@͓1!"<**"͓n "Dn"":!Q2҂' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M 'LITERALLY!', 'INITIAL!', 'DATA!',  'ENABLE!', 'DISABLE!', /* 'HALT!',  */ /* EXTERNAL SUBRS */ /* ,CNT,ACT,STATS) ADDRESS; END READ; WRITE: /* OUTPUT 'CNT' BYTES TO FILE */ PROCEDURE(AFTN,BUFR,CNT,STATS) EXTERNAL; ڕ*&P 6!4z!6!6#6#6!6*M8:ھ:*͇g2ê::¿::,͡A<2O>!6!q!6?!:ҠgÐ!q*&*~!6:22: :]Hں:A2O>: 2ͯ 9Ž>!6-e!6ͻ2=2ʺ-é:>>"ͻ2:!!5ͻ2ͬ!\ :020:121'ͳ':²ͯ !G6!"!"7 *M^n/ :a/:H!6:ͯ !&6:X!Wғä:ڤ*MEÓ:ұ@@:O2Mc;!6#6>!)*&P ~"::H:H!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈* 'BASED!', 'PROCEDURE!', 'EXT 'GOTO!', 'GO!', 'PLUS!',  */ /**********************************************************/ OPEN: /* OPEN A FILE */ PROCEDURE(DECLARE (AFTN,BUFR,CNT,STATS) ADDRESS; END WRITE; CLOSE: /* CLOSE A FILE THAT IS OPEN */ PROCEDURE(AFTN,STATS) EXTERNAL;B0 !%)- "&*. #'+/  $(,0 DECLARE (AFTN,STATS) ADDRESS; END CLOSE; ERROR: /* REPORT NON-FATAL ERRORS TO CONSOLE DEVICE */ PROCEDURE(ERRNUM) E********************************************************/ FORMAT$ERROR: /* INDICATE ERROR AND RETURN TO ISIS */ PROCEDURE DECLARE (ASCII$NUM BASED BUFLOC)(1) BYTE; /* CHAR BUFFER */ DECLARE DIGCNT BYTE; /* COUNTER FOR DIGITS */ DO DIGCNT=********************************/ IN$ALPHA: /* DETERMINE IF A CHAR IS ALPHA-NUMERIC OR '$' */ PROCEDURE(CHAR) BYTE; D'9' AND CHAR >= '0'; END IN$DIGITS; /************************************/ STRING$COMP: /* COMPARE TWO STRINGS */ PRO$COMP; /***********************************/ LOAD$RESWORD: /* STORE A RESERVED WORD INTO RESLIST */ PROCEDURE; D********************/ LOAD$RESLIST: /* LOAD DEFAULT RESERVED WORD LIST INTO RESLIST */ PROCEDURE; DECLARE I BYTE; IDN'T MATCH */ THEN CALL FORMAT$ERROR(.ERR2,LENGTH(ERR2)); LIST$PTR= DEFAULT$LIST(I).LIST$LOC; /* COPY RESERVED WORD **************************/ OVSTR: /* SET UP RESLIST FOR OVERSTRUCK CHARACTERS */ PROCEDURE; DECLARE DELIM BYTE; /*SERVED WORD TO RESLIST */ ELSE IF TXTBUF(TXT$INDX) = '*' THEN CALL LOAD$RESLIST; /* ADD A DEFAULT LIST TO RESLIZE LINECNT FOR CONVERSION */ DO WHILE IN$DIGITS(TXTBUF(TXT$INDX+1)); /* GET DIGITS FROM CMD LINE */ LINECNT= LINECNT*); REPCNT= REPCNT*10 + (TXTBUF(TXT$INDX+1) - '0'); TXT$INDX= TXT$INDX+1; END; END REPT; /*****************XTERNAL; DECLARE ERRNUM ADDRESS; END ERROR; EXIT: /* RETURN TO ISIS */ PROCEDURE EXTERNAL; END EXIT; $EJECT /****(ERRMSG,LEN); DECLARE (ERRMSG,LEN) ADDRESS; CALL WRITE(0,.('***ERROR: '),11,.ERRS); CALL WRITE(0,ERRMSG,LEN,.ERRS 0 TO 3; /* BLANK BUFFER IN CASE NUM IS ZERO */ ASCII$NUM(DIGCNT)= ' '; END; /* DIGCNT IS NOW EQUAL TO 4 */ AECLARE CHAR BYTE; /* CHAR TO TEST */ RETURN (CHAR <= 'Z' AND CHAR >= 'A') OR (CHAR <= 'z' AND CHAR >= 'a') OR CEDURE(STRLOC1,STRLOC2,LEN) BYTE; DECLARE (STRLOC1,STRLOC2,LEN) ADDRESS; DECLARE (STRING1 BASED STRLOC1)(1) BYTE; /* FIRO WHILE IN$ALPHA(TXTBUF(TXT$INDX)); RESLIST(RESLIST$INDX)= TXTBUF(TXT$INDX); TXT$INDX= TXT$INDX+1; IF RESLI DECLARE LIST$PTR ADDRESS; DECLARE (LIST BASED LIST$PTR)(1) BYTE; DECLARE INDX ADDRESS; TXT$INDX= TXT$INDX+1; /* ULIST */ INDX= 0; DO WHILE LIST(INDX) <> '*'; /* '*' IS LIST TERMINATOR */ RESLIST(RESLIST$INDX)= LIST(INDX);  HOLDS DELIMITER FOR MATCHING */ OVERSTRIKE= TRUE; /* SET OVERSTRIKE FLAG */ TXT$INDX= TXT$INDX+1; /* POINT TO DELIMITST */ ELSE IF TXTBUF(TXT$INDX) = CR THEN CALL FORMAT$ERROR(.ERR1,LENGTH(ERR1)); /* SCREW-UP */ ELSE TXT$10 + (TXTBUF(TXT$INDX+1) - '0'); /* DIGIT TO NUMBER */ TXT$INDX= TXT$INDX + 1; END; IF LINECNT = 0 /* SET DEFAUL*************************/ GETHEAD: /* CONSTRUCT HEADER BUFFER AND SET FLAG 'HEADER' TO TRUE. */ PROCEDURE; DECLARE T********************************************************/ /* */ /* ); CALL WRITE(0,.(CR,LF,LF),3,.ERRS); CALL EXIT; /* RETURN TO ISIS */ END FORMAT$ERROR; /***************************SCII$NUM(DIGCNT)= '0'; /* PUT '0' IN ONE'S DIGIT */ DO WHILE NUM <> 0; /* NOW CONVERT NUMBER IN NUM */ ASCII$NUM(DI (CHAR <= '9' AND CHAR >= '0') OR CHAR = '$'; END IN$ALPHA; /***********************************/ IN$ST STRING */ DECLARE (STRING2 BASED STRLOC2)(1) BYTE; /* SECOND STRING */ DECLARE INDX ADDRESS; /* STRING LENGTH COUNTERST$INDX < MAXLEN-1 THEN RESLIST$INDX= RESLIST$INDX+1; ELSE CALL FORMAT$ERROR(.ERR3,LENGTH(ERR3)); END; PDATE GLOBAL POINTER TO COMMAND BUFFER */ I= 0; /* START LOOKING THRU POSSIBLE RESERVED WORD LISTS */ DO WHILE I < DEFAU INDX= INDX+1; IF RESLIST$INDX < MAXLEN THEN RESLIST$INDX= RESLIST$INDX+1; ELSE CALL FORMAT$ERROR(ER */ DELIM= TXTBUF(TXT$INDX); TXT$INDX= TXT$INDX+1; /* NOW PICK OUT LIST OF RESERVED WORDS */ DO WHILE TXTBUF(TXT$INDX= TXT$INDX+1; /* ASSUME ANYTHING ELSE IS A SPACE */ END; RESLIST(RESLIST$INDX)= '*'; END OVSTR; /***************T IF NO NUMBER WAS INPUT */ THEN LINECNT= 60; END LISTCNT; /************************************************/ REPTPTR ADDRESS, /* POINTS TO WHERE TEXT TO FILL HEADER COMES FROM */ HINDX BYTE, /* INDEX INTO HEADER BUFFER */  LOCAL SUBRS */ /* */ /***********/ CNVRT: /* CONVERT 16 BIT INTEGER TO 5 CHAR ASCII */ PROCEDURE (NUM,BUFLOC); DECLARE (NUM,BUFLOC) ADDRESS; GCNT)= (NUM MOD 10) + '0'; /* START WITH ONES DIGIT */ DIGCNT= DIGCNT-1; NUM= NUM/10; END; END CNVRT; /***DIGITS: /* SIMPLE PROCEDURE TO TEST IF CHAR IS A DIGIT */ PROCEDURE(CHAR) BYTE; DECLARE CHAR BYTE; RETURN CHAR <=  */ DO INDX= 0 TO LEN-1; IF STRING1(INDX) <> STRING2(INDX) THEN RETURN FALSE; END; RETURN TRUE; END STRING RESLIST(RESLIST$INDX)= '!'; /* WORD TERMINATOR */ RESLIST$INDX= RESLIST$INDX+1; END LOAD$RESWORD; /******************LTS AND NOT STRING$COMP(.TXTBUF(TXT$INDX),.DEFAULT$LIST(I).NAME,5); I= I+1; END; IF I = DEFAULTS /* THEN STRING D.ERR3,LENGTH(ERR3)); END; TXT$INDX= TXT$INDX+5; /* POINT TO NEXT SET OF CHARS */ END LOAD$RESLIST; /****************INDX) <> DELIM; /* TERMINATED WITH DELIMITER */ IF IN$ALPHA(TXTBUF(TXT$INDX)) THEN CALL LOAD$RESWORD; /* ADD RE*************************/ LISTCNT: /* GET # OF LINES PER PAGE (DEFAULT = 60) */ PROCEDURE; LINECNT= 0; /* INITIALI: /* SET UP REPEAT COUNT AND FLAG */ PROCEDURE; REPCNT=0; /* DEFAULT CASE */ DO WHILE IN$DIGITS(TXTBUF(TXT$INDX+1) INDX BYTE, /* COUNTER */ DELIM BYTE; /* DELIMITER FOR TEXT STRING */ DECLARE TCHAR BASED TPTR BYC0 !%)- "&*. #'+/  $(,0TE; /* CHARACTER TO GO INTO HEADER BUFFER */ TPTR= .('File '); /* PUT THIS INTO HEADER FIRST */ DO HINDX= 0 TO 4; TXT$INDX+1) <> ' ' AND TXTBUF(TXT$INDX+1) <> CR AND TXTBUF(TXT$INDX+1) <> ';' THEN DO; /* COPY TEXT INTO HEADBUF */ AMOUNT OF TEXT WE CAN COPY */ THEN HINDX= HINDX+1; TXT$INDX= TXT$INDX+1; END; /**************/ GETCHAR: /* GET 1 CHAR FROM DISC BUFFER & READ IN NEW BUF IF NECESSARY */ PROCEDURE(CHAR$ADD) BYTE; DET BUFFER INDEX */ END; /* OF BUFFER UPDATE */ CHAR= DISCBUF(DISCBUF$INDX); /* GET CHAR */ DISCBUF$INDX= DISCBUF$HE TEXT STRING AND CC IS SET TO WHAT CARRIAGE CONTROL IS IMPLIED BY THE TERMINATOR. FOR LF, THIS IS 1 ARE (BUFFER BASED BUFLOC)(1) BYTE; /* RECORD RETURNED HERE */ DECLARE CC BASED CCLOC BYTE; /* CARRIAGE CONTROL RET THEN DO; FILL= (I AND 0F8H) + 7; /* SET FILL TO NEXT TAB STOP */ DO I= I TO FILL; /* STORE BLAF THEN CC= DOUBLE; /* FOR LF, SET ACCORDING TO DOUBLE SPACE FLAG */ ELSE CC= 0; /* CR MEANS NO CARRIAGE CONTRF HEADER /* THEN OUTPUT THE HEADER */ THEN DO; CALL CNVRT(PAGENUM,.HEADBUF(75)); /* STICK PAGE N ARE SUPPRESSED. */ PROCEDURE(BUFLOC,CC); DECLARE BUFLOC ADDRESS; /* LOCATION OF TEXT */ DECLARE CC BYTE; /* CARRIAGTBUF(CNT-1) <= ' ' AND CNT > 0; /* NOW BACK UP TILL TEXT STARTS */ CNT= CNT - 1; END; OUTBUF(CNT)= CR; /* PUT IN  HEADBUF(HINDX)= TCHAR; TPTR= TPTR+1; END; TPTR= .FNAM; /* NOW LOAD IN FILE NAME STRING */ DO INDX=  TXT$INDX= TXT$INDX+1; /* POINT TO DELIMITER */ DELIM= TXTBUF(TXT$INDX); TXT$INDX=TXT$INDX+1; * EXIT WITH TXT$INDX POINTING AT RIGHT DELIMITER */ END; DO HINDX= HINDX TO 69; /* PAD REST OF TITLE FIELD */ ECLARE CHAR$ADD ADDRESS; DECLARE CHAR BASED CHAR$ADD BYTE; IF DISCBUF$INDX = BUFLEN /* END OF CURRENT BUFFER */ INDX+1; RETURN TRUE; END GETCHAR; /***********************************************/ READREC: /* THIS ROUTINE FORMATS (SINGLE SPACE) OR 2 (DOUBLE SPACE). FOR FF, THIS IS -1 FOR CR, CC = 0 THIS INSURES THATURNED HERE */ CHAR= 0; I= -1; /* INITIALIZE BUFFER POINTER */ DO WHILE CHAR <> LF AND CHAR <> CR AND CHAR <> FFNKS */ BUFFER(I)= ' '; END; I= FILL; /* POINTS TO LAST FILLED LOCATION */ OL */ BUFFER(I)= CR; /* TERMINATE RECORD WITH CR */ RETURN TRUE; END READREC; /********************************UMBER INTO HEADER */ CALL WRITE(AFNLP,.HEADBUF,80,.ERRS); CALL WRITE(AFNLP,.(CR,LF,LF),3,.ERRS);E CONTROL, # OF LFS TO OUTPUT (CC => 0) */ DECLARE (CNT,I) BYTE; DECLARE (BUFFER BASED BUFLOC)(1) BYTE; DECLARE OUTBNEW CR */ IF CNT > 0 /* PRINT OUT TEXT IF ANY */ THEN DO; NEWPAGE= FALSE; IF WIDE /* STICK A MARG1 TO FLEN; HEADBUF(HINDX)= TCHAR; HINDX= HINDX+1; TPTR= TPTR+1; END; DO HINDX= HINDX TO 25; /* PA DO WHILE TXTBUF(TXT$INDX) <> DELIM; IF TXTBUF(TXT$INDX) = CR /* NO MATCHING RIGHT DELIMITER */ T HEADBUF(HINDX)= ' '; END; TPTR= .(' Page'); /* LOAD LAST ITEM INTO HEADBUF */ DO HINDX= HINDX TO 75; HEADBU THEN DO; /* GET NEW BUFFER FROM AFN1 (ASSUMES FILE IS OPEN) */ CALL READ(AFN1,.DISCBUF,LENGTH(DISCBUF),.BUFLEN,.ERRS)DATA OFF THE DISK INTO RECORDS. A RECORD IS DEFINED AS , CC. TEXT IS READ FROM THE  CARRIAGE CONTROL CHARACTERS IN THE FILE WILL BE CORRECTLY HANDLED AS NULL RECORDS. */ PROCEDURE(BUFL; /* SCAN FILE UNTIL TERMINATOR IS FOUND */ IF NOT GETCHAR(.CHAR) /* WE HAVE EOF (NO BYTES SENT) */ THEN RETURNEND; ELSE BUFFER(I)= CHAR; /* IF NOT A TAB, JUST STORE IN BUFFER */ END; /* AT THIS POINT A TERMINATOR HAS BEEN R********/ NXTPG: /* OUTPUT A TOP OF FORM AND HEADER, IF REQUIRED */ PROCEDURE; IF NOT NEWPAGE THEN DO; /* S LINE$NUM= 3; END; ELSE LINE$NUM= 1; END; END NXTPG; /*********************UF(132) BYTE; /* OUTPUT BUFFER FOR TEXT */ CNT= 0; /* INITIALIZE CHAR COUNT */ DO WHILE BUFFER(CNT) <> CR; /* LOCATE IN ON THE OUTPUT */ THEN CALL WRITE(AFNLP,.MARGIN,LENGTH(MARGIN),.ERRS); CALL WRITE(AFNLP,.OUTBUF,CNT+1,.D OUT TO TITLE FIELD */ HEADBUF(HINDX)= ' '; END; /* NOW LOOK TO SEE IF THERE IS A TITLE STRING */ IF TXTBUF(HEN CALL FORMAT$ERROR(.ERR1,LENGTH(ERR1)); HEADBUF(HINDX)= TXTBUF(TXT$INDX); IF HINDX <= 69 /* LIMIT F(HINDX)= TCHAR; TPTR= TPTR+1; END; HEADER= TRUE; RETURN; END GETHEAD; /*********************************; IF BUFLEN = 0 /* THIS MEANS END OF FILE */ THEN RETURN FALSE; ELSE DISCBUF$INDX= 0; /* RES DISK BUFFER UNTIL A TERMINATOR (CR, LF, OR FF) IS READ. ONCE THE TERMINATOR HAS BEEN READ, A CR IS APPENDED TO TOC,CCLOC) BYTE; /* READREC = FALSE IF EOF OCCURS */ DECLARE (BUFLOC,CCLOC) ADDRESS; DECLARE (CHAR,I,FILL) BYTE; DECL FALSE; I= I+1; /* POINT TO NEXT AVAILABLE SPACE IN BUFFER */ IF CHAR = TAB /* EXPAND CHAR IF IT IS A TAB */ ECEIVED */ IF BUFFER(I) = FF /* SET CARRIAGE CONTROL IMPLIED BY TERMINATOR */ THEN CC= -1; ELSE IF BUFFER(I)= LTART A NEW PAGE */ NEWPAGE= TRUE; CALL WRITE(AFNLP,.(FF),1,.ERRS); PAGENUM= PAGENUM+1; I************************/ LPOUT: /* OUTPUT A TEXT RECORD TO :LP:. RECORD IS TERMINATED WITH CR */ /* TRAILING BLANKSEND OF LINE */ OUTBUF(CNT)= BUFFER(CNT); /* COPY TEXT INTO OUTPUT BUFFER */ CNT= CNT + 1; END; DO WHILE OUERRS); /* OUTPUT TEXT BUFFER */ END; IF CC = -1 /* NOW DO CARRIAGE CONTROL */ THEN CALL NXTPG; /* OUTPUT AD0 !%)- "&*. #'+/  $(,0 TOP OF FORM */ ELSE DO I= 1 TO CC; /* IF CC >= 0, OUTPUT APPROPRIATE NUMBER OF LF's */ LINE$NUM= LINE$NUM+1;  THOSE RESERVED WORDS LISTED IN 'RESLIST'. */ PROCEDURE(BUFLOC); DECLARE BUFLOC ADDRESS; /* TEXT TO BE MODIFIED */ > CR; BUFFER(P1)= ' '; /* BLANK COMMENT */ P1= P1 + 1; END; IF BUFFER(NTER INTO RESERVED WORD LIST */ /* LOOK THRU RESERVED WORDS TO MATCH TEXT AT P1 */ DO WHILE RESL /* COMPARE BYTE BY BYTE */ P2= P2 + 1; P3= P3 + 1; END;  START AT NEXT WORD */ END; END; IF RESLIST(P3) = '*' /* THEN NO MATCH */  END SEARCH; $EJECT /*******************************************************/ /* HIS WILL GO ALONG THE COMMAND STRING */ DO WHILE TXTBUF(TXT$INDX) = ' '; /* SKIP BLANKS */ TXT$INDX= TXT$INDX + 1; SETTINGS */ RESLIST$INDX= 0; /* RESET POINTER TO RESERVED WORDS */ WIDE= FALSE; /* NO MARGIN */ REPCNT= 1;  DO WHILE TXTBUF(TXT$INDX) <> CR AND TXTBUF(TXT$INDX) <> ';'; IF TXTBUF(TXT$INDX) <> ' ' THEN /* CHECK POSS THEN SPACE= TRUE; ELSE IF TXTBUF(TXT$INDX) = 'H' /* PRINT HEADER */ THEN CALL GETHEAD; RESS= TRUE; ELSE CALL FORMAT$ERROR(.ERR4,LENGTH(ERR4)); TXT$INDX= TXT$INDX + 1; END; CALL OPEN(.AF IF LINENUM > LINECNT AND LINECNT > 0 /* THEN PAGING IS REQUIRED. */ THEN CALL NXTPG; ELSE DO; DECLARE (P1,P2,P3) ADDRESS; /* POINTERS TO TEXT STRINGS */ DECLARE (BUFFER BASED BUFLOC)(1) BYTE; P1= 0; DO WHP1)= CR THEN RETURN; /* WHOLE BUFFER IS A COMMENT */ ELSE COMMENT= FALSE; /* END OF COMMENT--TUIST(P3) <> '*' AND RESLIST(P3) <> '!'; /* A '*' IS THE END OF THE LIST. (NO MATCH) */ /* A /* IF WE HAD NO MATCH P3 WON'T POINT TO '!' */ IF RESLIST(P3) <> '!' OR IN$ALPHA(BUFFER(P2))  THEN DO WHILE IN$ALPHA(BUFFER(P1)); /* BLANK OUT WORD */ BUFFER(P */ /* MAIN PROG */ /* * END; FLEN= 0; /* THIS WILL GO ALONG FILE NAME STRING */ DO WHILE TXTBUF(TXT$INDX) <> ' ' AND TXTBUF(TXT$INDX) <> CR AN /* PRINT ONCE */ LINECNT= 0; /* NO PAGING REQUESTED */ DOUBLE= 1; /* SINGLE SPACE */ HEADER= FALSE; /*IBLE VALUES */ IF TXTBUF(TXT$INDX) = 'W' /* WIDE MARGINS */ THEN WIDE= TRUE; EL ELSE IF TXTBUF(TXT$INDX) = 'O' /* OVERSTRIKING */ THEN CALL OVSTR; ELSE IF TXTBUF(TXT$INDXNLP,.(':LP: '),2,0,.ERRS); /* OPEN :LP: FOR PRINT */ /* GO THROUGH PRINT LOOP FOR EACH PRINTING OF FILE */ DO LOOPCNT= NEWPAGE= FALSE; CALL WRITE(AFNLP,.(LF),1,.ERRS); END; END; END LPOUT; /***ILE BUFFER(P1) <> CR; /* OPERATE ON BUFFER UNTIL TERMINATOR (CR) */ IF COMMENT /* SEE IF END OF COMMENT IS IN THIS BUFFRN FLAG OFF & CONT */ END; IF BUFFER(P1) = '/' AND BUFFER(P1+1) = '*' /* BEGINNING OF COMMENT */ THEN '!' SIGNIFIES A MATCH */ P2= P1; /* USE P1 TO HOLD STARTING POINT */ /* TEST FOR '!' SINC THEN DO; DO WHILE RESLIST(P3) <> '!'; /* LOOK FOR NEX1)= ' '; P1= P1 + 1; END; ELSE P1= P2; /* SKIP OVER RESERVED WORD *// /*******************************************************/ CALL WRITE(0,.SIGNON,LENGTH(SIGNON),.ERRS); /* IDENTIFY PROGD TXTBUF(TXT$INDX) <> ';'; FNAM(FLEN)= TXTBUF(TXT$INDX); /* COPY UNTIL SPACE OR END OF COMMAND BUFFER */ TXT$INDX= NO HEADER */ PAGE= FALSE; /* NO PAGE EJECT */ SPACE= FALSE; /* NO SPACING */ SUPPRESS= FALSE; /* ISSUE FF ATSE IF TXTBUF(TXT$INDX) = 'D' /* DOUBLE SPACING */ THEN DOUBLE= 2; ELSE IF TXTBUF(TXT$INDX) = 'P' ) = 'R' /* REPEAT PRINT */ THEN CALL REPT; ELSE IF TXTBUF(TXT$INDX) = 'L' /* PAGELENGTH */  1 TO REPCNT; /* OPEN FILE AND PRINT */ CALL OPEN(.AFN1,.FNAM,1,0,.ERRS); /* IDENTIFY COMMON OPEN ERRORS */ **************************************************/ SEARCH: /* THIS ROUTINE BLANKS OUT ALL TEXT IN A BUFFER EXCEPT FOR ER */ THEN DO; DO WHILE (BUFFER(P1) <> '*' OR BUFFER(P1+1) <> '/') AND BUFFER(P1) < COMMENT= TRUE; ELSE IF IN$ALPHA(BUFFER(P1)) THEN DO; /* FOUND SOME TEXT */ P3= 0; /* POIE THIS IS USED TO TERMINATE WORD */ DO WHILE BUFFER(P2) = RESLIST(P3) AND BUFFER(P2) <> '!'; T RESERVED WORD */ P3= P3 + 1; END; P3= P3 + 1; /* END; ELSE DO; BUFFER(P1)= ' '; P1= P1 + 1; END; END;RAM */ /* GET FILENAME FROM COMMAND BUFFER */ CALL READ(1,.TXTBUF,LENGTH(TXTBUF),.BUFLEN,.ERRS); TXT$INDX= 0; /* T TXT$INDX + 1; FLEN= FLEN + 1; END; FNAM(FLEN)= ' '; /* TERMINATE NAME WITH BLANK */ /* SET DEFAULT SWITCH  START OF LISTING */ OVERSTRIKE= FALSE; /* NO OVERSTRIKING */ /* LOOK FOR LEGAL SWITCHES IN REST OF COMMAND BUFFER */ /* PAGE EJECT */ THEN PAGE= TRUE; ELSE IF TXTBUF(TXT$INDX) = 'S' /* SPACE EJECT */  THEN CALL LISTCNT; ELSE IF TXTBUF(TXT$INDX) = 'K' /* SUPPRESS FORM FEEDS */ THEN SUPP IF ERRS = 4 THEN CALL FORMAT$ERROR(.OPEN$ERR4,LENGTH(OPEN$ERR4)); ELSE IF ERRS = 5 THEN CALL FORMAT$E0 !%)- "&*. #'+/  $(,0ERROR(.OPEN$ERR5,LENGTH(OPEN$ERR5)); ELSE IF ERRS = 13 THEN CALL FORMAT$ERROR(.OPEN$ERR13,LENGTH(OPEN$ERR13)); RS TO FILE BUFFER */ BUFLEN= 0; /* TO FORCE THE FIRST READ */ PAGENUM= 0; NEWPAGE= SUPPRESS; /* FORCEALL SEARCH(.TXTBUF); /* SCREEN OUT NON-RESERVED WORDS */ END; CALL LPOUT(.TXTBUF,CCFLAG); /* PRINT BUFFES FOR OUTPUT */ IF LOOPCNT = 2 /* GET A LITTLE FANCY WITH THE OUTPUT HERE... */ THEN DO PCNT= 0 TO 2;  TITLE CP/M SYSTEM GENERATOR UTILITY 28 FEB 81 11:20 ;************************************************************* ; ; CCPM ; has been executed. ; A prompt for a BIOS file is implemented, where the file ; CBIOS.HEX may be loaded & saved on the s ;BDOS ENTRY DEFBFR EQU 0080H ;DEFAULT DISK BUFFER TPA: EQU 0100H SECSIZ EQU 128 ;DISK SECTOR SIZE (BYTES) CI: EQU 1 ;SETS BIOSNT: EQU 0001H ;LOCATION OF BIOS START ADDRESS WBOOTV EQU 0 ;WARM BOOT CSTSV EQU 1 ;CONSOLE STATUS CIV EQU 2 ;E FORMV EQU 16 ;FORMAT TRACK SYBUFR: EQU 0900H ;START OF SYSTEM IMAGE BUFFER SYSIZE EQU 1600H ;CPM SIZE IN BYTES (CCP + TABLE CAN BE MODIFIED FOR SKEW FACTORS (NOT FOR JADE DD) ; TABLE MUST TERMINATE WITH 0 SECTBL: EQU $ SECX: DB 1,2,3,4,5,6 HEX' ;CHANGE TO FILE DESIRED REPT 5 ;FILL WITH 0 DB 0,0,0,0 ENDM FILSIZ EQU $ - BIOSFILE SUBTTL SUBROUTINES ; LF: LD A,CR CALL CONOUT LD A,LF JR CONOUT ; ED1 DOES CR-LF BEFORE EDITOR ED1: PUSH HL CALL CRLF POP HL ; ED ELSE IF ERRS = 22 THEN CALL FORMAT$ERROR(.OPEN$ERR22,LENGTH(OPEN$ERR22)); ELSE IF ERRS = 23 TH A FORM FEED AT START OF LISTING */ CALL NXTPG; COMMENT= FALSE; /* START OFF WITH NO COMMENT */ DO WHILEER (SECOND TIME IF OVERSTRUCK) */ END; IF PAGE THEN CALL WRITE(AFNLP,.(FF),1,.ERRS); /* PUT PAGE BETWEEN COPY(18+PCNT)= PLURAL(PCNT); /* CHANGE "copy" TO "copies" */ END; CALL WRITE(0,.COPY,LENGTH(COPY),.ERRS)P/M SYSGEN UTILITY FOR JADE FORMAT DISKS ; (c) 1981 GRH Electronics, Cupertino, CA ; By Girvin Herr ; ;***************ystem track 0. ; ;************************************************************* ; ; REVISIONS: ; 1.0 - RELEASE ; 1.1 -CONSOLE INPUT SYSTEM CALL CO: EQU 2 ;CONSOLE OUTPUT SYSTEM CALL BDSD EQU 14 ;SELECT DISK SYSTEM CALL OPEN: EQU 15 ;OPEN FICONSOLE INPUT COV EQU 3 ;CONSOLE OUTPUT LSTOV EQU 4 ;LIST OUTPUT PUNV EQU 5 ;PUNCH OUTPUT RDRV EQU 6 ;READER INPUT HOMEBDOS) SYSECS EQU SYSIZE/128 ;# SECTORS TO WRITE BIOSST EQU 1F80H ;START OF BIOS IMAGE BIOSEC EQU 13 ;1ST SECTOR OF BIOS IMA,7,8D,9D,10D,11D,12D,13D,14D,15D,16D DB 17D,18D,19D,20D,21D,22D,23D,24D,25D,26D,27D,28D DB 29D,30D,31D,32D,33D,34D,35D,36D,3 AX128 MULTIPLIES VALUE IN A BY 128D & FORMS WORD VALUE AX128: LD L,A LD H,0 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HITOR OUTPUTS STRING EDITOR: LD A,(HL) ;GET CHAR OR A ;IF CHAR = 0 THEN EXIT RET Z PUSH HL CALL CONOUT POP HL INEN CALL FORMAT$ERROR(.OPEN$ERR23,LENGTH(OPEN$ERR23)); ELSE IF ERRS <> 0 THEN DO; CALL ERROR(ERRS); READREC(.TXTBUF,.CCFLAG); /* KEEP READING BUFFERS TILL EOF */ IF OVERSTRIKE /* PRINT BUFFER THEN OVERSTRIKE RESERVED  FILES */ IF SPACE THEN CALL WRITE(AFNLP,.(CR,LF,LF,LF,LF,LF),6,.ERRS); /* PUT 5 LINES BETWEEN FILES */ ; END; CALL WRITE(0,.(LF),1,.ERRS); /* FINAL LINE FEED TO CONSOLE */ CALL EXIT; END PRT; ********************************************** ; ; This utility generates CP/M system on track 1 in Double ; Density from t Include BIOS loader. Loads CBIOS.HEX file into BIOS area of ; disk. ; VERSN EQU '11' ;***********************************LE SYSTEM CALL READ: EQU 20 ;READ FILE SYSTEM CALL SETDMAC EQU 26 ;SET DMA SYSTEM CALL ; DEFAULT FILE CONTROL BLOCK IN V EQU 7 ;HOME DISK HEAD SLDRV EQU 8 ;SELECT DRIVE STTRKV EQU 9 ;SET TRACK STSECV EQU 10 ;SET SECTOR STADDV EQU 11 ;SET GE BIOSRS EQU 14 ;# RESERVED SECTORS FOR BIOS ; ASCII CONSTANTS LF: EQU 0AH CR: EQU 0DH SUBTTL CONSTANTS ; CO7D,38D,39D,40D DB 41D,42D,43D,44D,45D,46D,47D,48D,0 ; POSITION CODE DS SECTBL + 53 - $ ;ALLOW SPACE FOR 52 SECTORS MAXL ADD HL,HL ADD HL,HL ADD HL,HL RET ; CONSOLE INPUT CONIN: LD C,CI ;GET CHAR CALL BDOS CP 'a' ;IF LC THEN MC HL JR EDITOR ; BIOS ENTRY POINT CALCULATOR BIOSA: LD C,A ;VALUE IN A BIOSE: LD HL,(BIOSNT) ;COMPUTE VECTOR LD D, CALL EXIT; END; /* INITIALIZE COUNTERS AND SUCH */ DISCBUF$INDX= 0; /* INITIALIZE POINTEWORDS */ THEN DO; CALL LPOUT(.TXTBUF,0); /* PRINT FIRST LINE BY ITSELF FOR NOW */ CCALL CLOSE(AFN1,.ERRS); /* CLOSE TEXT FILE (TO BE RE-OPENED IF REPEAT) */ CALL CNVRT(LOOPCNT,.COPY(9)); /* LOAD # OF COPIhe memory image at 0900H to 2100H (CCP & BDOS + SOME) is ; saved on track 1. This is the location of the CCP & BDOS after a MOV*************************** SUBTTL DECLARATIONS ; CP/M SYSTEM DFLTDK EQU 0004H ;DEFAULT DISK LOCATION BDOS: EQU 0005HPAGE 0 DEFFCB: EQU 005CH ;DEFAULT FCB ADDR FCBCR: EQU DEFFCB+32 INFCB EQU DEFFCB ;PATCH FOR READHEX ; BIOS ENTRY OFFADDRESS RSECTV EQU 12 ;READ SECTOR WSECTV EQU 13 ;WRITE SECTOR LSTSTV EQU 14 ;LIST STATUS SECTXV EQU 15 ;SECTOR TRANSLATDE START ORG TPA JP START ;JUMP VECTOR TO ENTRY POINT ; DISK CONSTANTS LASTRK: DB 1 LSTSEC: DB 48D ; SECTOR  + NULL ; BIOS FILENAME TO READ FROM DEFAULT DISK BIOSFILE: DB 1 ;CHANGE TO DISK TO READ FROM IF DESIRED DB 'CBIOS AKE UC RET C CP '{' RET NC AND 5FH RET ; CONSOLE OUTPUT CONOUT: LD E,A LD C,CO JP BDOS ; CR - LF CR0 ADD HL,DE ADD HL,DE ADD HL,DE LD DE,0 ;REQ'D BY SELECT DISK (LOGON VECTOR) JP (HL) ; BDOS SELECT DISK SELDSF0 !%)- "&*. #'+/  $(,0K: LD E,A ;SET DISK # LD C,BDSD JP BDOS ; BDOS READ FILE SECTOR RDSEQ: PUSH BC ;PATCH FOR READHEX POP DE READF: C (HL) CP (HL) RET Z LD E,(HL) LD D,0 LD HL,SECTBL ;SET SECTOR TABLE PTR LD B,(HL) ADD HL,DE LD C,(HL) PUSH BCT RETURN THEN EXIT CP CR JP NZ,EXIT CALL CRLF ;ELSE CONTINUE JR NXTSEC RETOK: INC A ;RETRIES := RETRIES +1 LD (RE**************************************************** ; ; HEX FILE READ LIBRARY ROUTINE ; ; ENTRY- BC = BUFFER PTR ; TTED & OPENED) ; ; NAME RDHEX ; EXTRN DEFBFR,SETDMA,RDSEQ,INFCB ; ENTRY READHX,BYTE,GETCH ; ;*****************************,0 ;CHECKSUM = 0 CALL BYTE ;IF RECORD LENGTH = 0 THEN RETURN JP C,HXERR ;FILE EMPTY AND A RET Z LD E,A ;RECORDRD: CALL GETCH ;FETCH CHARACTER OF FILE LD E,A LD A,1 RET C ;FILE EMPTY LD A,E OR A ;IF CHAR = NULL THEN IGNORE JR) ;COMPUTE NEW PTR ADD HL,BC LD (HEXPTR),HL LD C,E ;IF PTR + COUNT > BFR TOP THEN LD B,0 ADD HL,BC LD BC,(BFRTOP) DD D JP Z,HEXRD ; HXERR: EQU $ LD A,2 ;IF ERROR THEN TELL SO RET ; ; BYTE SUBR CONVERTS 2 ASCII-HEX CHARS TO BINARY B,A ;COMPUTE CHECKSUM ADD D LD D,A LD A,B OR A ;CLEAR FLAG RET ; ; GET CHARACTER SUBR ; ENTRY- FCB FORMATTED POP BC POP DE GC1: LD HL,(DBPTR) ;GET CHAR FROM BFR LD A,(HL) INC HL LD (DBPTR),HL LD HL,BFRCNT ;COUNT = COUNT - 1V JR GETSRC ; SET1: ADD 'A' ;RESTORE DRIVE & PUT INTO MSG LD (SRCDK),A SUB 'A' ;SELECT DRIVE CALL SELDSK CALL CRLFLD C,READ JP BDOS ; BDOS OPEN FILE OPENF: LD C,OPEN JP BDOS ; BDOS SET DMA SETDMA: PUSH BC POP DE LD C,SE LD E,STSECV CALL BIOSE POP BC ;COMPUTE DELTA LD A,C SUB B CALL AX128 EX DE,HL LD HL,(BFRPTR) ;COMPUTE PTR ADTRYS),A LD A,(OPNFLG) ;IF FLAG = 0 THEN READ OR A JR Z,RD1 LD E,WSECTV CALL BIOSE ;ELSE WRITE JR ERRCHK RD1: LD  DE = TOP OF BUFFER ; EXIT - A = ERROR CODE: ; 0 = NO ERRORS ; 1 = FILE ERROR (EMPTY) ; 2 = HEX CONVERSION ERROR ******************************* ; ; READHX: XOR A ;SET UP BUFFER FOR 1ST READ LD (BFRCNT),A LD (BFRPTR),BC LD (BFRTO COUNT = BYTE CALL BYTE ;GET ADDRESS JP C,HXERR LD H,A CALL BYTE JP C,HXERR LD L,A LD (HEXBASE),HL ;SAVE BASE ADDR Z,HEXRD CP ':' ;IF CHAR <> COLON THEN IGNORE JR NZ,HEXRD LD D,0 ;CHECKSUM = 0 CALL BYTE JR C,HXERR ;FILE EMPTY  INC BC OR A SBC HL,BC JR NC,HEXMER ;ERROR ; GETREC: CALL BYTE ;GET RECORD TYPE JR C,HXERR ;FILE EMPTY OR A  ; BYTE: CALL GETCH ;GET 1ST DIGIT RET C SUB '0' ;IF DIGIT NOT HEX THEN ERR RET C CP 10D JP C,CVOK SUB 7 CP 10D  AT FCB ; EXIT - CHAR FROM FILE IN A ; CF = EOF ; GETCH: PUSH HL LD A,(BFRCNT) ;IF BUFFER EMPTY THEN READ OR  DEC (HL) POP HL OR A ;INSURE NC RET ; FEMPTY: POP BC ;RESTORE STACK POP DE POP HL RET SUBTTL MAIN PGM  LD HL,SRCDKP ;OUTPUT SOURCE DRV MSG CALL EDITOR CALL CONIN ;IF INPUT <> RETURN THEN RE-BOOT CP CR JP NZ,EXIT CALL TDMAC JP BDOS ; DO SYSTEM TRACK DOIT: LD HL,SYBUFR ;SET PTR LD (BFRPTR),HL DOTRK: LD C,1 ;SET TRACK LD E,STTRKV D HL,DE LD B,H LD C,L LD E,STADDV ;SET ADDRESS CALL BIOSE XOR A LD (RETRYS),A ;CLEAR RETRIES RETRY: LD A,(RETRYS) ;E,RSECTV ;READ CALL BIOSE ERRCHK: OR A ;IF NO ERRORS THEN CONTINUE JR Z,NXTSEC JR RETRY ; MOVE FILE NAME TO DEFFCB ; 3 = MEMORY BOUNDS ERROR (FILE TOO BIG) ; ;************************************************************ ; EXTERNALS: ; DP),DE HEXRD1: CALL GETCH ;FETCH CHARACTER OF FILE LD E,A ;SAVE CHAR 1ST LD A,1 ;IF (FILE EMPTY) RETURN 1 RET C LD A,R LD HL,(BFRPTR) ;INIT LOAD PTR TO START OF BFR LD (HEXPTR),HL LD C,E ;IF LOAD PTR + COUNT <= LAST THEN LD B,0 AAND A ;IF RECORD LENGTH = 0 THEN RETURN 0 RET Z LD E,A ;RECORD COUNT = BYTE CALL BYTE ;GET ADDRESS JR C,HXERR LD  ;IF RECORD TYPE <> 0 THEN RETURN LD A,2 RET NZ LD HL,(HEXPTR) ;INIT PTR LOOP: CALL BYTE ;INPUT DATA JR C,HXERR LD ( RET C CP 16D CCF RET C CVOK: SLA A ;MOVE OVER 1 NIBBLE SLA A SLA A SLA A LD B,A CALL GETCH ;GET 2ND DIGIT RA JP NZ,GC1 PUSH DE ;READ SECTOR INTO DEFAULT BUFFER PUSH BC LD BC,DEFBFR CALL SETDMA LD BC,INFCB CALL RDSEQSTART: LD SP,STACK LD HL,SGNON ;OUTPUT SIGN-ON MSG CALL EDITOR GETSRC: LD HL,SRCDKM ;OUTPUT SOURCE DRV MSG CALL ED1 CCRLF XOR A LD (OPNFLG),A ;SELECT READ OPERATION CALL DOIT LD HL,FNCCM ;OUTPUT FUNCTION COMPLETE MSG CALL EDITOR GET CALL BIOSE LD A,-1 ;SET UP SECTOR CNT LD (SECTOR),A NXTSEC: LD A,(LSTSEC) ;IF LAST SECTOR THEN RETURN LD HL,SECTOR INIF RETRIES <10 THEN GO TO IT CP 10D JR C,RETOK LD HL,ERRM ;ELSE OUTPUT ERROR MSG CALL EDITOR CALL CONIN ;IF INPUT NO MOVFIL: LD HL,BIOSFILE ;SET UP FOR MOVE LD DE,DEFFCB LD BC,FILSIZ LDIR RET SUBTTL HEX FILE READ SUBR ;********EFBFR: DEFAULT DISK SECTOR BUFFER (0080H) ; SETDMA: CP/M CALL ; RDSEC: CP/M CALL ; INFCB: INPUT FCB ADDR (ALREADY FORMAE ;RESTORE CHAR OR A ;IF CHAR = NULL THEN IGNORE JR Z,HEXRD1 CP ':' ;IF CHAR <> COLON THEN IGNORE JR NZ,HEXRD1 LD DDD HL,BC LD BC,(BFRTOP) INC BC OR A SBC HL,BC JP C,GETREC ; GO GET DATA HEXMER: LD A,3 ;ELSE RETURN 3 RET ; HEXH,A CALL BYTE JR C,HXERR LD L,A LD BC,(HEXBASE) ;IF NEW ADDR BELOW 1ST THEN ERR SBC HL,BC JP C,HEXMER LD BC,(BFRPTHL),A INC HL DEC E ;IF (COUNT = COUNT -1) = <> 0 THEN LOOP JP NZ,LOOP CALL BYTE ;CHECK CHECKSUM JR C,HXERR XOR A AET C SUB '0' RET C CP 10D JP C,CVOK2 SUB 7 CP 10D RET C CP 16D CCF RET C CVOK2: ADD B ;ADD 2ND TO 1ST LD OR A ;IF FILE EMPTY THEN RETURN CF SCF JR NZ,FEMPTY LD HL,DEFBFR LD (DBPTR),HL ;SET VARS LD A,128D LD (BFRCNT),AALL CONIN CP CR ;IF RETURN THEN NO READ JR Z,GETDST SUB 'A' ;IF NOT 'A'-'C' THEN RESTART CP 4 JR C,SET1 CALL INVDRDST: LD HL,DSTDKM ;OUTPUT DEST DRV MSG CALL ED1 CALL CONIN ;IF INPUT = RETURN THEN REBOOT CP CR JP Z,EXIT SUB 'A' ;IG0 !%)- "&*. #'+/  $(,0F NOT 'A'-'C' THEN RESTART CP 4 JR C,DESTOK CALL INVDRV JR GETDST DESTOK: ADD 'A' ;PUT DRV INTO MSG LD (DSTDK),A BIOS.HEX FILE JR NZ,WBIOS CALL MOVFIL ;MOVE FILE NAME TO DEFAULT FCB LD DE,DEFFCB CALL OPENF INC A ;IF ERROR THEN ABDSTDK) ;SET DISK SUB 'A' CALL SELDSK LD A,BIOSEC ;SET SECTOR TO START LD (SECTOR),A LD A,BIOSRS ;SET SECTOR COUNT LDIF CNT > 0 THEN GOTO WLOOP DEC A LD (CNT),A JR NZ,WLOOP COMPLT: LD HL,FNCCM ;OUTPUT FUNCTION COMPLETE MSG CALL EDITOR ',0 SRCDKM: DB 'Source drive name (or RETURN to skip)',0 SRCDKP: DB 'Source on ' SRCDK: DB 9D DB ' - Then type RETURN',ss RETURN.' DB CR,LF,'To write Bios image in memory, press space bar...',0 OPNERM: DB CR,LF,LF,'CBIOS.HEX file not present S COUNT WPTR DW BIOSST ;PTR TO BIOS MEMORY IMAGE FOR WRITING CNT DB 1 ;BIOS SECTOR WRITE COUNT BFRTOP: DW 0 ;LAST BYTE Od0  !"#$%&'()*+,-./0 CBIOS HEXo&)))))))a{__> s> ?''''G*0 # ?؀GWx:Qͱ\ͥ7 !">2*~#"!51$!͇!͂e (6A8ip)Source on - Then type RETURNDestination drive name (or RETURN to reboot)Destination on - Then type RETURNPERMANENT ER SUB 'A' ;SET DRIVE CALL SELDSK LD HL,DSTDKP ;OUTPUT DEST PROMPT CALL ED1 CALL CONIN CP CR ;IF INPUT NOT RETURN THENORT WITH MSG JR NZ,OPENOK LD HL,OPNERM CALL EDITOR JP GETDST ;RECOVER OPENOK: LD BC,BIOSST ;PASS IN PARAMS TO READ (CNT),A LD HL,BIOSST ;SET PTR LD (WPTR),HL WLOOP: PUSH HL POP BC ;SET WRITE ADDR LD E,STADDV CALL BIOSE LD A,(S JP GETDST WERR: LD HL,WERRM ;OUTPUT WRITE ERROR CALL EDITOR JP GETDST ;RECOVER EXIT: LD A,(DFLTDK) ;RESTORE TO DEFAU0 DSTDKM: DB 'Destination drive name (or RETURN to reboot)',0 DSTDKP: DB 'Destination on ' DSTDK: DB 9D DB ' - Then typon default disk...' DB 'Aborting Bios write function!',0 WERRM: DB CR,LF,LF,'Bios write ERROR...Aborting function!',0 HEF LOAD BUFFER HEXPTR: DW 0 ;LOAD PTR HEXBASE:DW 0 ;FIRST LOAD ADDR OF FILE ; BFRCNT: DB 0 ;READ BUFFER COUNT DBPTR: DW Dy~s#O*_! " ͓>2:!4^!FN ͓yZ*DM ͓2: 8!͔A2A͟y!͇e †y2͸!͇!#͂e ʆA8͔A2_A͟!P͂e †y!6͸!͇e ({L *-ROR, Type RETURN to ignoreFunction complete INVALID DRIVE NAME (Use A,B,C or D) To load CBIOS.HEX file, press "L". To skip RE-BOOT JP NZ,EXIT CALL CRLF LD HL,OPNFLG ;SET WRITE OPERATION LD (HL),1 CALL DOIT LD HL,BIOSM ;OUTPUT BIOS PROMPT HEX LD DE,(BDOS+1) CALL READHX ;READ HEX FILE INTO BIOS AREA OR A ;IF NO ERRORS THEN CONTINUE JR Z,WBIOS LD HL,HEXERECTOR) ;SET SECTOR LD E,STSECV CALL BIOSA LD E,WSECTV CALL BIOSE ;WRITE IT OR A ;IF ERROR THEN EXIT JR NZ,WERR LLT DRIVE AND 0FH CALL SELDSK CALL CRLF JP 0 ; INVDRV: LD HL,INVDKM ;OUTPUT INVALID DRV MSG JP ED1 SUBTTL MESSAGEe RETURN',0 ERRM: DB 'PERMANENT ERROR, Type RETURN to ignore',0 FNCCM: DB 'Function complete ',0 INVDKM: DB 'INVALID DRXERM: DB CR,LF,LF,'Hex file error...Aborting read operation!',0 SUBTTL VARIABLES TRACK: DB 0FFH ;TRACK # SECTOR: DB 0FFEFBFR ;DEFAULT (READ) BUFFER PTR ; DS 32 STACK: EQU $ END t͇e †y<2:( ͓ ͓(!:\ ɯ2CS*_>{(: _go"*"K K\ͬ< !N͇ð[9(!͇ ͓:_A͟> 2>2!" ͓: ͒ ͓ !4*":=2 !͇ð! Bios write, press RETURN. To write Bios image in memory, press space bar... CBIOS.HEX file not present on default disk...Ab CALL EDITOR CALL CONIN ;GET USER INPUT CP CR ;IF RETURN THEN SKIP BIOS WRITE JR Z,COMPLT CP 'L' ;IF 'L' THEN LOAD CM ;ELSE OUTPUT ERROR CALL EDITOR JR GETDST ;ALLOW RESTART WBIOS: LD C,0 ;TRACK = 0 LD E,STTRKV CALL BIOSE LD A,(D HL,SECTOR ;SECTOR += 1 INC (HL) LD HL,(WPTR) ;PTR += SECTOR SIZE LD DE,SECSIZ ADD HL,DE LD (WPTR),HL LD A,(CNT) ;S SGNON: DB CR,LF,LF DB 'Jade DD SYSGEN Ver ',HIGH VERSN,'.',LOW VERSN,CR,LF DB '(c) 1981 GRH Electronics, Cupertino, CAIVE NAME (Use A,B,C or D)',0 BIOSM: DB CR,LF,LF DB 'To load CBIOS.HEX file, press "L".' DB CR,LF,'To skip Bios write, preH ;SECTOR # OPNFLG: DB 0 ;OPERATION FLAG (0=READ, 1=WRITE) BFRPTR: DW SYBUFR ;RD/WR BUFFER PTR RETRYS: DB 0 ;RD/WR RETRIEB>*_>{(: 8O_8Gg8AoKBڅK "K KB08>*8w#8ʈ>*0  ͇ð:͟y! Jade DD SYSGEN Ver 1.1 (c) 1981 GRH Electronics, Cupertino, CASource drive name (or RETURN to skorting Bios write function! Bios write ERROR...Aborting function! Hex file error...Aborting read operation! H0 !%)- "&*. #'+/  $(,0); break; case 6: puts("\nPremature end-of-file encountered"); break; case 7: h user Ram"); break; default: puts("\nProgram error"); } printf("! %d\n",errno); /* <<< CALL GETCH ;GET SELECTION CP CTRLC ;IF CHAR = CTRL-C THEN RETURN TO MAIN RET Z CP 'H' ;IF HELP THEN RESTART JR Z,REW DIGITZ ; ; CONFIDENCE TEST ; CONFID: LD A,1 SHL PPG ;OUTPUT PROGRAM GATE BIT TO READ DATA REG. OUT PRMCMD,A LD C,PDATA PUSH HL CALL OCODE JP CBOUTREG ;******************************** ; ; OP CODES 0 THRU 3FH ; MISCELANEOUS OPS ; ;**A JR Z,DIS142 INC C DIS142: CALL OCODE LD A,(OP) CALL GETFLD JP OUTREG8 ;********************** ; ; 00XX X011  LD A,(OP) CP 18H ;IF UNCONDITIONAL THEN EXIT JR Z,JRUNC CALL OUTRCC ;OUTPUT CONDITION CODE CALL OCOMMA ;OUTPUT COM2: LD HL,OP BIT 3,(HL) JR NZ,DIS121 LD C,10H ;'LD' CALL OCODE CALL SET5 ;SET BIT 5 OF STATUS LD A,(OP) CALL GETFOURCE REG PAIR JP OUTRP ;********************** ; ; 00XX X010 ; ;********************** DIS13: LD A,(OP) BIT 5,A 'LD' CALL OCODE LD HL,AIBCM ;OUTPUT 'A,(BC)' LD A,(OP) BIT 4,A JR Z,NOTAIDE LD HL,AIDEM ;OUTPUT 'A,(DE)' NOTAIDE:  ;IF NOT 36H THEN ERR CP 36H JP NZ,ERROR1 CALL GETOPND2 LD A,(OP) ;OUTPUT REGISTER CALL GETFLD CALL OUTREG8 CALL GETFLD PUSH AF RES 0,A CP 6 ;CHANGE AF TO SP CALL Z,SET5 POP AF JP OUTRP ;******************** ; ; 01XX X00X puts("\nInvalid record format"); break; case 8: puts("\nIllegal record type"); break; <<<<<<<< diag */ exit(0); } #ifdef diag_mode /* temporary disline */ disline(){ output(fetch()); returSTRT CP '?' JR Z,RESTRT SUB A,'0' ;CHECK FOR LEGAL COMMAND LD BC,CMDERM ;SET UP FOR ERROR JR C,CMDLP CP MAXCMD + 1  ;SET UP DATA PORT # LD E,0 ;TEST FOR ALL 0S CALL REGCMP JR NZ,CONFER LD E,0FFH ;NEXT USE ALL 1S CALL REGCMP JR N****************************** MISCOPS: AND 7 JP Z,DIS11 CP 1 JP Z,DIS12 CP 2 JP Z,DIS13 CP 6 JP C,DIS14  ; ;********************** DIS141: BIT 3,A JR Z,DIS143 INC C DIS143: CALL OCODE CALL SET5 ;SET BIT 5 OF STATUS LD A,MA JRUNC: CALL GETOPND1 ;OUTPUT DISPLACEMENT EXX INC C EXX LD A,(OPND1) JP COMPADDR ; NOPOP: LD C,2FH ;OP PTR = 'NLD ;COMPUTE & OUTPUT REG PAIR CALL OUTRP EXX INC C INC C EXX CALL GETOPND2 CALL OCOMMA ;',' LD HL,OPND1 JP O JR Z,DIS131 EXX LD E,4 BIT 4,A JR Z,D13NTR8 LD E,7 D13NTR8: EXX LD C,10H ;OP PTR = 'LD' CALL OCODE EXX IN BIT 3,A JR NZ,D13REV INC HL INC HL D13REV: LD B,6 JP OSTRNG ;********************************* ; ; 00XX X110 (LOCOMMA ;OUTPUT COMMA LD A,(OPND2) JP OUTSNGL ;OUTPUT N VALUE ;********************************** ; ; 01XX X010 (ED  ; ;******************** EDIO: LD C,12H ;OP PTR = 'OUT' CP 1 JR Z,EDIN INC C ;CHANGE TO 'IN' CALL OCODE LD A,(OP) case 9: puts("\nIllegal HEX digit"); break; case 10: puts("\nDisk full"); bn 1; } #endif  JR NC,CMDLP LD HL,CMDTBL ;COMPUTE COMMAND VECTOR ADD A,A ;MULT BY 2 LD E,A LD D,0 ADD HL,DE LD A,(HL) INC HL Z,CONFER LD E,1 ;WALKING 1 LD B,8 WALKLP: CALL REGCMP JR NZ,CONFER SLA E ;WALK BIT LEFT DJNZ WALKLP CALL GETAD ; JP Z,DIS15 LD A,(OP) ;OP CODE CALL GETFLD ADD 18H LD C,A JP OCODE ;************************** ; ; 00XX X01(OP) CALL GETFLD JP OUTRP ;********************* ; ; 00XX X000 ; ;********************* DIS11: LD A,(OP) OR A ;OP' JP OCODE ; DJNZOP: LD C,30H ;OP PTR = 'DJNZ' CALL OCODE JP JRUNC ; EXAFAFOP: LD C,14H ;OP PTR = 'EX AF,AF'' UT16B ;******************** ; ; 00XX 1001 ; ;******************** DIS121: LD C,0 ;OP PTR = 'ADD' CALL OCODE LD A,C C INC C EXX LD HL,OP BIT 3,(HL) JP Z,OUTINX CALL SELREG ;OUTPUT REG PAIR CALL OCOMMA ;OUTPUT COMMA CALL GETOD R,N) ; ;********************************* DIS15: LD C,10H ;'LD' CALL OCODE EXX INC C LD A,B EXX AND 6 JR NOPS) ; ;********************************** EDADC: LD A,(OP) AND 38H LD C,03H ;OP PTR = 'SBC' BIT 3,A JR Z,EDSBC DE CALL GETFLD CALL OUTREG8 CALL OCOMMA LD HL,CINDM ;OUTPUT '(C)' LD B,3 JP OSTRNG ; EDIN: CALL OCODE LD HL,CINDM reak; case 11: puts("\nCannot close output file"); break; case 12: puts("\nNot enougOG: RESTRT: LD BC,SIGNON ;OUTPUT SIGN-ON MESSAGE CMDLP: CALL EDITOR LD C,'-' ;OUTPUT PROMPT CALL CO LD C,' ' CALL CO  LD H,(HL) LD L,A JP (HL) ;GOTO COMMAND ; CMDTBL: DW CONFID DW TIMING DW FREE DW ONESHT DW ADDREG DW STATST DINPUT A/D DATA LD BC,EOCERM JP C,CMDLP OR A ;IF 0 THEN ERR LD BC,AD0ERM JP Z,CMDLP INC A ;IF -1 THEN ERR LD BC,A1 ; 00XX X100 ; 00XX X101 ; ;************************* DIS14: LD A,(OP) LD C,20H ;'INC' BIT 2,A JR Z,DIS141 BIT 0,IF 0 THEN EXIT JR Z,NOPOP CP 10H ;IF <= 10H THEN EXIT JR C,EXAFAFOP JR Z,DJNZOP LD C,2EH ;OP PTR = 'JR' CALL OCODECALL OCODE LD HL,AFAFM ;OUTPUT 'AF,AF'' JP OEDITR ;********************* ; ; 00XX X001 ; ;********************* DIS14 ;OUTPUT 'HL' CALL OUTRP CALL OCOMMA ;OUTPUT COMMA CALL SET5 ;SET BIT 5 OF STATUS LD A,(OP) CALL GETFLD ;OUTPUT SPND2 ;OUTPUT '(nn)' VALUE JP OUTCONT ;******************** ; ; 000X X010 ; ;******************** DIS131: LD C,10H ;Z,D15IR LD A,(OP) CALL GETFLD CALL OUTREG8 CALL OCOMMA CALL GETOPND1 LD A,(OPND1) JP OUTSNGL ; D15IR: LD A,(OP) C C ;MAKE 'ADC' DEC C EDSBC: CALL OCODE LD A,4 ;FORCE 'HL,' CALL OUTRP CALL OCOMMA ;OUTPUT COMMA LD A,(OP) CALL  LD B,3 CALL OSTRNG CALL OCOMMA LD A,(OP) CALL GETFLD JP OUTREG8 ; EDOPS: CALL GETOPND1 ;SPLIT 2BYTE FROM GARBAI0 !%)- "&*. #'+/  $(,0GE LD A,(OPND1) CP 0A0H JR C,EDLTA0 BIT 2,A ;IF BIT 2 = 1 THEN NOT ED OP JP NZ,PRDB CP 0BCH ;IF > BBH THEN NOT ED  7,B ;SET ED FLAG FOR ERROR1 EXX CALL GETOP LD A,(OP) ;********************* ; ; 01XX XXXX ; ;*********************************** ; ; 01XX X101 ; ;********************* EDRETS: LD C,44H ;OP PTR = 'RETI' LD A,(OP) AND 38H CP 8 ******************** EDROT: LD C,46H ;OP PTR = 'RLD' CP 28H JR Z,EDROTL DEC C ;OP PTR = 'RRD' EDROTL: JP OCODE ;* = OP OFFSET ; OCODE: LD L,C LD H,0 ADD HL,HL ;COMPUTE TABLE ENTRY ADD HL,HL LD BC,MNETBL ADD HL,BC LD B,4 ;CO L,'B' CALL OUTCH CALL OUTTAB ;TAB TO OPERAND FIELD LD A,(OP) ;OUTPUT VALUE ; ; OUTPUT SINGLE BYTE VALUE & ASCII CH LD L,''' JP OUTCH ; OUTINX: CALL GETOPND2 ;OUTPUT '(nn)' CALL OUTCONT CALL OCOMMA ;OUTPUT COMMA ; ; SELECTENTRY- HL = BYTE PTR TO CODE ; EXIT - HL = VALUE ; ; OUT16B: ;OUTPUT HI BYTE 1ST LD E,(HL) INC HL LD D,(HL) PUSH ,A ;SIGN EXTEND JP Z,COMP1 LD B,-1 COMP1: ADD HL,BC ;COMPUTE ADDRESS PUSH HL ;SAVE VALUE PUSH HL POP BC ;BUILD SY POP BC LD A,C ;THEN OUTPUT VALUE CALL OBYTE CALL OUTH POP BC RET ; ; OUTPUT RIGHT BRACKET ; ORPAR: LD L,')'ON RRA RRA PUSH HL LD HL,CONDTBL ;TABLE PTR ADD L ;COMPUTE ENTRY ADDR LD L,A JP NC,HOK INC H HOK: LD B,2 CALZ,R8IX BIT 2,A ;IF IY THEN EXIT JR NZ,R8IY LD HL,IHLM ;OUTPUT '(HL)' JP OEDITR ; R8IX: LD HL,IIXM ;OUTPUT '(IX' OP JP NC,PRDB AND 7 ;COMPUTE OP TABLE ENTRY LD C,A LD A,(OPND1) AND 18H RRCA ADD C ADD 32H LD C,A EXX ;BU*** EDOLT80: AND 7 CP 2 JP C,EDIO JP Z,EDADC CP 4 JR C,EDLDINNRP JR Z,EDARITH CP 6 JR C,EDRETS JR Z,EDIM JP Z,OCODE DEC C ;'RETN' JP OCODE ;********************* ; ; 01XX X100 ; ;********************* EDARITH: LD C,4******************** ; ; 01XX X110 ; ;********************* EDIM: LD C,47H ;OP PTR = 'IM' CALL OCODE LD A,(OP) AND 3UNT = 4 OMNEM: PUSH BC PUSH HL LD A,(HL) OR A JR Z,OCDN LD L,A PUSH AF ;SAVE FOR DONE TEST CALL OUTCH ;OUTPUT MEQU IF ASCIISW SET ; OUTSNGL: EXX ;SAVE VALUE LD L,A EXX CALL OBYTE CALL OUTH LD A,(SWITCH) ;IF ASCIISW TRUE THE REG OR REG PAIR SUBR ; ENTRY - E = CODE ; SELREG: EXX LD A,E EXX CP 7 JP NZ,OUTRP JP OUTREG8 ; ; OUTPUT LOCADE CALL OUT2HE CALL OUTH POP HL RET ; ; ; OUTPUT ADDRESS VALUE SUBR ; ; OUTADDR: CALL SYBLD ;ADD VALUE TO SMBOL TABLE CALL SYBLD2 SYMBOL: LD L,'L' ;OUTPUT SYMBOL CALL OUTCH CALL OUT2HE POP HL RET ; ; ; OUTPUT DISPLAC JP OUTCH ; ; OUTPUT LEFT BRACKET ; OLPAR: LD L,'(' JP OUTCH ; ; SPACE OUTPUT ; OSPACE: LD L,' ' JP OUTCH L OSTRNG POP HL RET ; ; OUTPUT REGISTER SUBR ; ENTRY - A = CODE ; EXIT - HL = SAVED ; OUTREG8: AND 7 ;INSURE MOR8I: CALL OEDITR CALL GETOPND1 ;OUTPUT DISPLACEMENT EXX INC C EXX LD A,(OPND1) CALL OUTDISP JP ORPAR ;OUTPUT ')' MP BYTE COUNT INC C EXX JP OCODE ; EDLTA0: LD HL,EDOPSTBL ;VERIFY OP IN TABLE LD B,NUMEDOPS EDOPLP: CP (HL) JR Z,EDLD A,(OP) AND 38H CP 20H JR NC,EDROT LD C,10H ;OP PTR = 'LD' CALL OCODE LD A,(OP) LD HL,IAIM ;OUTPUT 'I,A' BIT2H ;OP PTR = 'NEG' JP OCODE ;********************* ; ; 01XX X011 ; ;********************* EDLDINNRP: CALL SET5 8H CP 8 JR C,EDIM0 RRCA RRCA RRCA DEC A EDIM0: ADD '0' LD L,A JP OUTCH SUBTTL SUBROUTINES ; ; COMPUTE MNEMONEMONIC POP AF OCDN: POP HL POP BC INC HL JP Z,OUTTAB ;IF CHAR = NUL THEN DONE DJNZ OMNEM JP OUTTAB ;TAB TO OPERANN OUTPUT ASCII EQUIV. AND ASCIISW RET NZ EXX ;IF NOT PRINTABLE THEN RETURN LD A,L EXX CP ' ' RET C CP 7FH RETION ADDR VALUE - '(nn)' ; OUTCONT: CALL OLPAR ;OUTPUT '(' CALL OUTADDR ;OUTPUT VALUE JP ORPAR ;OUTPUT ')' ; ; YMBOL TABLE PUSH BC ;SAVE VALUE FOR SYMBOL JP SYMBOL ; ; ; COMPUTE DISPLACEMENT ADDRESS FOR SYMBOL ; ENTRY- A= DISPEMENT VALUE SUBR ; ENTRY- A = VALUE ; EXIT - BC = SAVED ; ; OUTDISP: PUSH BC LD B,'+' ;ASSUME POSITIVE LD C,A BIT  ; ; COMMA OUTPUT ; OCOMMA: LD L,',' JP OUTCH ; OUTH: LD L,'H' JP OUTCH ; ; OUTPUT CONDITION CODE SUBR ;D 8 CP 6 ;IF M THEN EXIT JR Z,INDREG PUSH HL LD HL,RTAB ;COMPUTE REGISTER TABLE ENTRY ADD L LD L,A JP NC,OUTREG8 ; R8IY: LD HL,IIYM ;OUTPUT '(IY' JP R8I ; ; OUTPUT REG PAIR SUBR ; ENTRY- A = CODE ; EXIT - HL = SAVED ; OUTRP:OPOK INC HL DJNZ EDOPLP ;IF NOT DONE THEN LOOP JP PRDB ;ELSE TREAT AS DB ; EDOPOK: CALL ESCAPE EXX INC C SET 3,A JR Z,SKPR LD HL,RARM ;OUTPUT 'R,A' SKPR: BIT 4,A JR Z,EDREV INC HL INC HL EDREV: LD B,3 JP OSTRNG ;****LD A,(OP) LD D,A AND 30H RRCA RRCA RRCA EXX LD E,A JP D13NTR8 ;********************* ; ; 011X X111 ; ;*NIC TABLE ELEMENT SUBR ; ENTRY - A = CODE ; OPSELCT: CALL GETFLD LD C,A ; ; OUTPUT CODE & MNEMONIC SUBR ; ENTRY- CD FIELD ; ; OUTPUT 'DB' OPTION OR ON ERROR ; PRDB: EXX ;SET UP 1 BYTE USED LD C,1 EXX LD L,'D' CALL OUTCH LDT NC LD L,A PUSH HL CALL OUTTAB ;TAB TO COMMENT FIELD LD L,';' CALL OUTCH LD L,''' CALL OUTCH POP HL CALL OUTSET BIT 5 OF STATUS BYTE SUBR ; EXIT - HL = SAVED ; SET5: EXX SET 5,B EXX RET ; ; ; OUTPUT 16 BIT VALUE SUBR ; LACEMENT BYTE VALUE ; ; COMPADDR: LD C,A LD B,0 LD HL,(PGMCOU) ;ADD 2 FOR THIS JR INSTRUCTION INC HL INC HL BIT 77,A ;IF NEGATIVE THEN USE '-' JP Z,DISPOS LD B,'-' NEG LD C,A DISPOS: LD L,B ;OUTPUT SIGN 1ST PUSH BC CALL OUTCH  ENTRY- A = CODE ; EXIT - HL = SAVED ; OUTRCC: SUB 20H ;CORRECTION FACTOR FOR JRs ; OUTCC: AND 38H ;PLACE FIELD IN POSITIA INC H OUTREG8A: LD L,(HL) CALL OUTCH POP HL RET ; INDREG: EXX LD A,B EXX BIT 1,A ;IF IX THEN EXIT JP N PUSH HL BIT 2,A JR NZ,RPNOTSTD RPALLSET: RES 0,A LD HL,RPTAB ;COMPUTE TABLE ENTRY ADD L LD L,A JP NC,RPHOK INCJ0 !%)- "&*. #'+/  $(,0 H RPHOK: LD B,2 ;OUTPUT REGISTER PAIR CALL OSTRNG POP HL RET RPNOTSTD: BIT 1,A JR NZ,RPNOTI EXX ;IF IX THEN XIT LD A,(OPND1) CP 0CBH JR Z,LKATCB PUSH HL LD HL,XDOPTBL LD B,XDOPS LKALP: CP (HL) JR Z,LKAFND INC HL DJNZ PAIR CALL OCOMMA ;OUTPUT COMMA LD A,4 ;OUTPUT 'HL' JP OUTRP ; ; MESSAGE EDITOR TO OUTPUT FILE SUBR ; ENTRY- HL = T <> 0 THEN RET OR A RET NZ CALL FETCH_ LD A,L LD (OP),A LD A,1 LD (BYTECNT),A RET ; GETOPND1: LD A,(BYTS FROM BUFFER & MOVES BUFFER UP ; CLEAN: EXX ;A= #BYTES USED LD A,C EXX OR A ;IF (USED == 0) RETURN RET Z CP 4 ;LL PRHXDG PRHXDG: RLA RLA RLA RLA PUSH AF AND 0FH CP 10 JR C,NTALPH ADD 7 NTALPH: ADD '0' PUSH HL PUSH DE  ; ESCAPE: EXX PUSH BC LD C,1 EXX CALL CLEAN EXX POP BC SET 3,B ;SET ESCAPE USED FLAG FOR DISRTN EXX RAF ;ELSE OUTPUT 'DB' OPCODE LD (OP),A JP PRDB ; ERROR1A: LD (OP),A CALL PRDB POP AF ;RESTORE OP LD (OP),A EXX  RET Z PUSH DE PUSH BC LD L,A CALL OUTCH POP BC POP DE DJNZ SYPLP LD L,':' ;OUTPUT COLON AFTER LABEL CALL OUT SYSTX ;STORE PRINTABLE HEX LD A,C ;GET LO CALL SYSTX LD A,B ;SAVE VALUE IN TABLE LD (DE),A DEC DE LD A,C LD (D ; BC=HEX VALUE OF SYMBOL TO FIND ; (SYMTABL)= SYMBOL TABLE PTR TO SART OF TABLE TERMINATED BY NULL ; EXIT - CY=NOT FOUND, DE=E INC DE INC DE INC DE OR A RET LUNO: DEC DE JP LULP ; ; NUMBER CONVERTERS ; HEXL: RRA ;GET LEFT DIGIT EXIT BIT 1,B EXX JR NZ,RPIX EXX ;IF IY THEN EXIT BIT 2,B EXX JR Z,RPALLSET LD A,10 ;'IY' JP RPALLSET ; RPLKALP SCF ;NOT FOUND IN TABLE, ERR LKAFND: POP HL RET LKATCB: CALL GETOPND3 ;SKIP OFFSET BYTE FOR OPCODE LD A,(OPNMSG PTR (POINTING TO CNT BYTE) ; OEDITR: PUSH BC LD B,(HL) ;GET COUNT INC HL CALL OSTRNG ;OUTPUT STRING POP BC RETECNT) CP 2 RET NC CALL FETCH_ LD A,L LD (OPND1),A LD A,2 LD (BYTECNT),A RET ; GETOPND2: CALL GETOPND1 ;GIF (USED > 3) { JP C,CLNOTALL XOR A ; COUNT = 0 LD (BYTECNT),A RET ; RETURN } ; CLNOTALL: LD E,A ;SAVE USED  ;OUTPUT TO CONSOLE USING DIRECT BDOS CALL LD E,A LD C,2 CALL BDOS POP DE POP HL POP AF RET ; CLEAN1: LD (BYTECNET ; ; ERROR HANDLER SUBR OUTPUTS DBs TO GET IN SYNC AGAIN ; ERROR1: LD A,(OP) ;SAVE CURRENT OP PUSH AF EXX ;IF N ;SET CLEAN HOLD BIT FOR RETURN LD B,40H EXX RET ; ; ROUTINE TO BUILD & ACCESS THE SYMBOL TABLE ; SYMBO: CALL SYBCH SCF RET ; ; SYMBOL TABLE BUILD ; SYBLD: CALL GETOPND2 ;FETCH DATA SYBLD1: LD A,(OPND1) LD C,A LD A,(OPND2) E),A XOR A ;RESTORE END OF TABLE FLAG DEC DE LD (DE),A EX DE,HL ;UPDATE BOTTOM OF TABLE PTR LD (SYMPTR),HL EX DE,HOPEN LOCATION ; NC=FOUND, DE=PTR TO SYMBOL ; HL RESTORED ; LOOKU: PUSH HL LD HL,(SYMTAB) EX DE,HL POP HL RRA RRA RRA HEXR: AND 0FH ;MASK OUT LEFT DIGIT CP 10D JR C,HEXRN ADD 7 HEXRN: ADD '0' RET ; ; I/O ROUTINEIX: LD A,8 ;'IX' JP RPALLSET ; RPNOTI: EXX ;IF NOT LD SP,HL THEN EXIT BIT 5,B EXX JR Z,RPALLSET LD A,0CH ;'SP' D3) AND 7 CP 6 RET Z SCF RET ; ; OUTPUT REG PAIR SUBR ; OUTIRP: PUSH AF CALL OLPAR ;OUTPUT '(' POP AF C ; ; MESSAGE EDITOR W/CNT SUPPLIED SUBR ; ENTRY- HL = PTR TO STRING ; B = COUNT ; OSTRNG: PUSH HL PUSH BC LD L,(HET OPND1 FIRST CP 3 RET NC CALL FETCH_ LD A,L LD (OPND2),A LD A,3 LD (BYTECNT),A RET ; GETOPND3: CALL GE LD A,(BYTECNT) ;IF (USED > COUNT) ERROR SUB E JP NC,CLEAN1 FATERR: LD DE,FATERM ;OUTPUT ERR MSG TO CONSOLE LD C,9 CALT),A RET Z ;IF (COUNT == 0) RETURN LD A,4 ;MOVECNT = 4 - USED SUB E RET Z ;IF (MOVECNT == 0) RETURN LD C,A LD B,0OT IX PENDING THEN IY LD A,B EXX LD B,A BIT 1,B LD A,0DDH JR NZ,ERROR1A ;IF IX THEN OUTPUT 'DB 0DDH' LD A,0FDH BLD OR A ;INSURE NO CRY & RET RET ; ; PRINT LABEL SUBR ; PRTLB: CALL LOOKU ;LOOK UP IN TABLE CCF ;IF NOT FOUND  LD B,A SYBLD2: CALL LOOKU ;IF ALREADY IN TABLE THEN RET RET NC ; ; ADD NEW ENTRY TO SYMBOL TABLE ; ENTRY- BC=ADDR ; L SCF ;SET DEFAULT LABEL PRINTING RET ; ; ROUTINE TO STORE LABEL IN SYMBOL TABLE ; SYSTX: PUSH AF CALL HEXL ;CO LULP: LD A,(DE) ;IF ENTRY = 0 THEN DONE OR A SCF RET Z DEC DE DEC DE DEC DE DEC DE DEC DE LD A,(DE) CP B S ; OCHAR: LD L,C OUTCH: LD H,0 PUSH HL CALL OUTPUT POP HL RET ; OBYTE: LD L,A LD H,0 PUSH HL CALL OUTHEX JP RPALLSET ; ; ; DD/FD OPS LOOK AHEAD SUBR ; EXIT - CF : ILLEGAL OPERAND ; ; LKAHEAD: CALL GETOPND1 ;IF CB THEN EALL OUTRP ;OUTPUT REG PAIR JP ORPAR ;OUTPUT ')' ; ; OUTPUT REG PAIR ',HL' ; OUTRPHL: CALL OUTRP ;OUTPUT DEST REG L) CALL OUTCH POP BC POP HL INC HL DJNZ OSTRNG RET ; ; GET OP CODE SUBR ; GETOP: LD A,(BYTECNT) ;IF BYTECOUNTOPND2 CP 4 RET NC CALL FETCH_ LD A,L LD (OPND3),A LD A,4 LD (BYTECNT),A RET ; ; CLEAN REMOVES (C') # BYTEL BDOS POP HL LD HL,(PGMCOU) ;OUTPUT DIS. ADDR LD A,H CALL PRHEX LD A,L CALL PRHEX JP 0 ; PRHEX: OR A RLA CA LD D,B LD HL,OP ;MOVE BYTES UP BY COUNT ADD HL,DE LD DE,OP LDIR RET ; ; ESCAPE CAUSES OP BYTE TO BE SCRUBBEDIT 2,B JR NZ,ERROR1A ;IF IY THEN OUTPUT 'DB 0FDH' LD A,0EDH BIT 7,B JR NZ,ERROR1A ;IF EDOPS THEN OUTPUT 'DB 0EDH' POP THEN NC RET NC LD B,5 ;FOUND, PRINT LABEL SYPLP: LD A,(DE) DEC DE OR A SCF ;SET CARRY SO PGM WON'T PRINT DEFAULT  DE=OPEN SYMBOL TABLE ENTRY ; LD A,'L' ;DEFAULT TO LABEL TYPE LXXXX LD (DE),A DEC DE LD A,B ;GET HI ORDER CALLNVERT & STORE VALUE LD (DE),A DEC DE POP AF CALL HEXR LD (DE),A DEC DE RET ; ; SYMBOL TABLE LOOK UP ROUTINE  ;IF NO MATCH THEN WASTE DEC DE JP NZ,LUNO LD A,(DE) CP C JP NZ,LUNO INC DE ;BACK UP TO ASCII PART INC DE INC D POP HL RET ; ; SHIFT FIELD INTO PROPER BITS SUBR ; ENTRY- A= BYTE TO SHIFT ; EXIT - A= NEW BYTE ; GETFLD: AND 38HK0 !%)- "&*. #'+/  $(,0 RRCA RRCA RRCA RET SUBTTL TEXTS SPINDM: DB 5,'(SP),' DEXXM: DB 3,'DE,' IHLM: DB 4,'(HL)' IIXM: DB 3,'(IX' IIYM: H,23H,29H,2AH,2BH,34H,35H,36H,39H DB 46H,4EH,56H,5EH,66H,6EH,70H,71H,72H,73H,74H DB 75H,77H,7EH,86H,8EH,96H,9EH,0A6H,0AEH,0B ;1 DB 'SUB',0 ;2 DB 'SBC',0 ;3 DB 'AND',0 ;4 DB 'XOR',0 ;5 DB 'OR',0,0 ;6 DB 'CP',0,0 ;7 DB 'RST',0 ;8 DB 'CCF',0 ;1F DB 'INC',0 ;20 DB 'DEC',0 ;21 DB 'BIT',0 ;22 DB 'RES',0 ;23 DB 'SET',0 ;24 DB 'RLC',0 ;25 DB 'R DB 'INIR' ;3C DB 'OTIR' ;3D DB 'LDDR' ;3E DB 'CPDR' ;3F DB 'INDR' ;40 DB 'OTDR' ;41 DB 'NEG',0 ;42 DB 'RETDB 3,'(IY' AFAFM: DB 6,'AF,AF''' AIBCM: DB 'A,(BC),' AIDEM: DB 'A,(DE),' DB 'A' CINDM: DB '(C)' IAIM: DB 'I,A,I' RARM: D6H DB 0BEH,0E1H,0E3H,0E5H,0E9H,0F9H XDOPS EQU $-XDOPTBL ; ; LEGAL ED EXTENDED OP CODES TABLE ; EDOPSTBL: DB 40H,41H,4'PUSH' ;9 DB 'POP',0 ;A DB 'IY',0,0 ;B DB 'IX',0,0 ;C DB 'RET',0 ;D DB 'EXX',0 ;E DB 'JP',0,0 ;F DB 'LD',0,0 ;RC',0 ;26 DB 'RL',0,0 ;27 DB 'RR',0,0 ;28 DB 'SLA',0 ;29 DB 'SRA',0 ;2A DB 'ERR',0 ;2B DB 'SRL',0 ;2C DB 'UNKN' ;43 DB 'RETI' ;44 DB 'RRD',0 ;45 DB 'RLD',0 ;46 DB 'IM',0,0 ;47 DB 0,0,0,0 ;WAS A BUNCH OF SPACES?? DB 0,0,0B 'R,A,R' FATERM: DB CR,LF,'FATAL ERROR AT - $' SUBTTL TABLES CONDTBL: DB 'NZ ZNC CPOPE P M' ;CONDITION CODES RTAB: DB 'B2H,43H,44H,45H,46H,47H,48H,49H,4AH DB 4BH,4DH,4FH,50H,51H,52H,53H,56H,57H,58H,59H DB 5AH,5BH,5EH,5FH,60H,61H,62H,67H,68H,69H10 DB 'CALL' ;11 DB 'OUT',0 ;12 DB 'IN',0,0 ;13 DB 'EX',0,0 ;14 DB 'DI',0,0 ;15 DB 'EI',0,0 ;16 DB 'HALT' ;17 N' ;2D DB 'JR',0,0 ;2E DB 'NOP',0 ;2F DB 'DJNZ' ;30 DB 'ED',0,0 ;31 DB 'LDI',0 ;32 DB 'CPI',0 ;33 DB 'INI',0 ,0 ; " " " " " SUBTTL DATA STORAGE AREA DATA OP: DB 0 ;OP CODE BUFFER OPND1: DB 0 ;OPERAND 1 OPND2: DB 0 ;OCDEHLMA' ;REGISTERS RPTAB: DB 'BCDEHLAFIXIYSP' ;REGISTER PAIRS ; ; LEGAL EXTENDED OPS TABLE ; XDOPTBL: DB 9,19H,21H,22,6AH DB 6FH,72H,73H,78H,79H,7AH,7BH NUMEDOPS EQU $-EDOPSTBL ; ; MNEMONIC TABLE ; MNETBL: DB 'ADD',0 ;0 DB 'ADC',0  DB 'RLCA' ;18 DB 'RRCA' ;19 DB 'RLA',0 ;1A DB 'RRA',0 ;1B DB 'DAA',0 ;1C DB 'CPL',0 ;1D DB 'SCF',0 ;1E DB  ;34 DB 'OUTI' ;35 DB 'LDD',0 ;36 DB 'CPD',0 ;37 DB 'IND',0 ;38 DB 'OUTD' ;39 DB 'LDIR' ;3A DB 'CPIR' ;3B PERAND 2 OPND3: DB 0 ;OPERAND 3 BYTECNT: DB 0 ;COUNT OF BYTES USED ; REL END L0 !%)- "&*. #'+/  $(,0