IMD 1.17: 4/01/2010 17:35:08 programmer's utility diskette morrow designs micro-decision 64k cp/m vers 2.2 rev 2.1 1983 >2!9^#V!1 Not a SYSTEM Diskette. (^ >2!9^#V!1 Not a SYSTEM Diskette. ASM COM@DDT COM&DUMP ASM! DUMP COM ED COM4 LOAD COMCBOOT MAC CBIOS MACV 1*" COPYRIGHT(C) 1978, DIGITAL RESEARCH á 4êü /L9ASMPRNHEX!)ͼ !ͼ :5͡ :6:6͡ :7͡ :\ ʻ 24!dͮ 25ͮ 27ͮ 26!8 ( ʃ !Y 1  :7ʞ !z 8  !"2D2X2#! 8 !ͼ z{* ! !"!8 w#  +6# *#"~!ͼ G:6QxJQS*!w#"! 1 !"!Y~~# …¡z!ͼ wʹ* ! w#" ! 8 !" ! zz_O4:  :6y:! G~#x=2> > ! >x6 #='G! ~ p( O*}O>4?:7w:#ĸ*"!͸* }w>ͪg( ʆ1 Y :7ʗ8 z !<ͼ CP/M ASSEMBLER - VER 2.0 NO SOURCE FILE PRESENT NO DIRECTORY SPACE SOURCE FILE NAME ERROR SOURCE FILE READ ERROR OUTPUT FILE WRITE ERROR CANNOT CLOSE FILES END OF ASSEMBLY G:7xʘ!#~ʄl͸Ä**!O {zʊ͸*"!!#^4!$wͯͯWƐ'@'ê>:ͪ!#^Ww*!{͚|͚}͚͚{!$~#͚͚> ͪ> ͪ{zA"*![N![ N#Fr+sq#p/>G=#w#w3#w#w!JSYMBOL TABLE OVERFLOW G*##~w*##~͎*_###s#r^#V`à 4 Wm ()*+,-/ABCDEHLMDBDIDSDWEIIFINORSPACIADCADDADIANAANDANICMACMCCMPCPIDAADADDCRDCXENDEQUHLTINRINXJMPLDALXIMODMOVMVINOPNOTORAORGORIOUTPOPPSWRALRARRETRLCRRCRSTSBBSBISETSHLSHRSTASTCSUBSUIXORXRAXRICALLENDMLDAXLHLDPCHLPUSHSHLDSPHLSTAXXCHGXTHLENDIFMACROTITLE  PF FP! ( 2/?'  v:P@< !  PP27 ( *"  NZZ NCC POPEP M x_BH!œ#¶ ¦{KÈCÈ<:JCR:  !6 s!#  ɯ<:O=_Z!F!V#fjQ̓E!^#Vo&)~#FxGyѯ<àn8!~ڢͅ6~44O! s#r!~ ڿ6ͅ^4!mw!wp!~ͅ!55N! N#fio&)^#fk!4w_#~ ʸ A:4~~# ¼ > \ ?ʻ w# !ͼ ? !ͼ @2 0 0:x0_<2! wI2 2> 2 >2ɯ22 !~@_6^4#: w~$w: 0 q: A: A͋q: a{_2  2 - !ɯ2I:  ;*:  ͭͷ ͭ͋>9q>9: '!2 >9 7:! 6 >2>2: 2 Qͭ:Ğ! :lj<͖<j<|<: OʊQ>ÖH >2 2 û: B­>ôD> ¸!52 !"!N#~#A07O! ~*!) " :  '<ͭ'<>V$>O$:Ğà\ÞØ`rÍÖ![w#w#b!"!F#v2[G*##~w*##~<*}q!~ڬ6![^![^#fk"͎͘!G#*####*^#Vû!^*"*z'{ͅ>ɯo>g"k!m6ů{_zW5>)D*kOxGd !m?FDM!xGyOڂÃ)sn55)=â|g}o=î--#zg{ozg{ozg{oÓ:: ;,!ɯ22=2l!"]!~H5_!m~0:ą:  *":  :‰:̅ԅ!^#=ʅVq”*qͦ1& O:lµ̅>2ly:_!w~!s!m~ùy !~=w_!m~ ͅͰ>2lyPLnR>UX:l̅2l͓*>E2C!" """ :ʼ:*1 |R|ͦ0FIL: R  R* } *" :¿::¿üX!C^#fk[@ :Œ:=ʌG!ʆF#H vÛc*| EH ͺ,^1 ͦ *""1 EH DH ͺ,1 ͦ :  1:  " > 2 =COPYRIGHT (C) 1980, DIGITAL RESEARCH DDT VERS 2.2$10 !~=W!xe ~#Xbxʇ {z~#o}o҃i.2_!fp+q*e2_2_!hp+q*g!jp+q*i!lp+q*k!np+q*m2_!pp+q*oÃO$*sy͏ , $  ͌ 9!z6 # L!zw͌j# X:z 0 ͘=N#Fy}80*z{¯#z+++ ¥ z#½# · 9!`͠ y9!rͷ y=!z{w# % w!P͠ y͓}*w#"͌ @.@<!Eͷ~P !ͷ’P͌Q!ͷªP}QxQ!ͷ͓G@Q! ͷ y͓Gþ!ͷ ͓Q!ͷ͓Q͌Q!.ͷ6y#G͙Qà!2ͷQ͓͌Q!>ͷq eg͙Q:zJEËC–EQyQxQRQ** {zҷ*~#" <AOGƐ'@'OxƐ'@'ON# ͓ !" >- Ͷ Aګ ҫ _!7^#V~  \p Z z ů2[\͓͢ ҫ ͐ =« f " ͓ ҫ ͐ ʻf " =ʻf "=« ý> 2͐ f "]=f =« *]}o"_  *]"a. ~ #E }"]*a 6 *]}#|#*]E ͐ « f f f {zA|« W}d ͐ f f f DMʡڏ"=ʡͲ=ʡYPͲ1**!O~4#~#F#x~#s#r#w>͐ « f f  . ᯕo>g. 2|2\  !]w# ʫ .&  0 6 #& .K !e K w# ʫ : U 6 #K 6AW w#] !e~H#~E#~X*}|́ "!́ ͐ !ʬ =« f kʫ j \͢F w# ͋ t ʫ : W& _& & O { `i"F & & w# & ͋ « t Y t Y GтWx ͢!o ~Z #N  *. *.  NEXT PC͐ =« f  . ~ Ͷ ʻ .͓ =« f |« }w#Ä >2L͐ ! =« f }ʫ +"MD Å D  !  #:|: |Ë  |*" ͩ !6="1 :  1}1:n:>BʋSSͦSSxS 1:  1"" ͦ 1 |R >O U!" 1 1!|_!^#fk $8AP`ixH ñññ81Ľ y0îH ñGîG  ñH ñ(Ľ yîH ñîîĽ y0îîH ñG 1: :,; c*| } 8OĽ y0G G t :):,.>C :|: Jü;r :R: ʼʋ!ʼR!ʼʋ>SR{ozg!~4ʧͦ !6 ! **̈́**̈́\iͩ !w#H USE FACTOR !* "z{*"* "I !" :1 R O*UR X* G:xl :  *̩ : l x͖ *#"EH DH 0:~ ! ^4! w͆ Æ *! 6z͖ {͖ 4>R>V>D >P >L >Nz8O!B N#N ¾SP.* |} !9":q!"28!"9:] !í 1 ë «   Ͷ ͐ =« f xY |« }ҫ gA>S Ag}S S i |« }!w s#r:[ʔ _!~ʦ ![4ç \͢¦ 2[ 7 >?  e͢!g"c> _͢a_!f~> 5*c~#"c 0 7   > >  ͢| } @ >. *_}o| , 0 ë ^#V#!Y ))))o P q s#r#!V4 !V6# ,® >2Vñ m ͅ m ͅ m ͅ « Vʫ ! XN!~  ! _^! ^#V~ x+ >= = !~  . !   #x f L L ͓ͅ ҆ *" !6ï +"_*~ #E گ ʫ ^#V. ï ~ CZMEIABDHSP!"M"+"!91*~!O~6=G#^#V#~x (#"!N#FW( *J>7Å*M|N+"M N:LHͅÅD Å >* *͓ b" . *"] !/~##ʁtZ*F#n!Is!^#V&&##&))::^#V#*^#V>+)x-8_EA (RESTORED AT FINIS) LXI SP,STKTOP ; READ AND PRINT SUCCESSIVE BUFFERS CALL SETUP ;SET UP INPUT FILE CPI 255 ;255 IF FILE NOT PRESENT JNZ OPENOK ;SKIP IF OPEN IS OK ; ; FILE NOT THERE, GIVE ERROR MESSAGE AND RETURN LXI D,OPNMSG CALL ERR JMP FINIS ;TO RETURN ; OPENOK: ;OPEN OPERATION OK, SET BUFFER INDEX TO END MVI A,80H STA IBP ;SET BUFFER POINTER TO 80H ; HL CONTAINS NEXT ADDRESS TO PRINT LXI H,0 ;START WITH 0000 ; GLOOP: PUSH H ;SAVE LINE POSITION CALL GNB POP H ;RECALL LINE POSITION JC FINIS ;CARRY SET BY GNB IF END FILE MOV B,A ; PRINT HEX VALUES ; CHECK FOR LINE FOLD MOV A,L ANI 0FH ;CHECK LOW 4 BITS JNZ NONUM ; PRINT LINE NUMBER CALL CRLF ; ; CHECK FOR BREAK KEY CALL BREAK ; ACCUM LSB = 1 IF CHARACTER READY RRC ;INTO CARRY JC FINIS ;DON'T PRINT ANY MORE ; MOV A,H CALL PHEX MOV A,L CALL PHEX NONUM: INX H ;TO NEXT LINE NUMBER MVI A,' ' CALL PCHAR MOV A,B CALL PHEX JMP GLOOP ; FINIS: ; END OF DUMP, RETURN TO CCP ; (NOTE )*)þ))>+><7"9.Yͯ * M^2U :2:2ͳ:_³ͯ !6! @!!BH @@ABH B! "BHI$$BI$BI $ HI D$HD$$ H B!$D$"$B$DA!ABI$H B$I $HI$H$! $I $I$$A !A@$I$"!$H$I$I "! $A$  HHAA"I @BB $A"$$$I$$H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!I$I$I$UUU$$A$ x (#"!N#FW( *J>7Å*M|N+"M N:LHͅÅD Å >* *͓ b" . *"] !/~##ʁtZ*F#n!Is!^#V&&##&))::^#V#*^#V>+)x-8_; FILE DUMP PROGRAM, READS AN INPUT FILE AND PRINTS IN HEX ; ; COPYRIGHT (C) 1975, 1976, 1977, 1978 ; DIGITAL RESEARCH ; BOX 579, PACIFIC GROVE ; CALIFORNIA, 93950 ; ORG 100H BDOS EQU 0005H ;DOS ENTRY POINT CONS EQU 1 ;READ CONSOLE TYPEF EQU 2 ;TYPE FUNCTION PRINTF EQU 9 ;BUFFER PRINT ENTRY BRKF EQU 11 ;BREAK KEY FUNCTION (TRUE IF CHAR READY) OPENF EQU 15 ;FILE OPEN READF EQU 20 ;READ FUNCTION ; FCB EQU 5CH ;FILE CONTROL BLOCK ADDRESS BUFF EQU 80H ;INPUT DISK BUFFER ADDRESS ; ; NON GRAPHIC CHARACTERS CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED ; ; FILE CONTROL BLOCK DEFINITIONS FCBDN EQU FCB+0 ;DISK NAME FCBFN EQU FCB+1 ;FILE NAME FCBFT EQU FCB+9 ;DISK FILE TYPE (3 CHARACTERS) FCBRL EQU FCB+12 ;FILE'S CURRENT REEL NUMBER FCBRC EQU FCB+15 ;FILE'S RECORD COUNT (0 TO 128) FCBCR EQU FCB+32 ;CURRENT (NEXT) RECORD NUMBER (0 TO 127) FCBLN EQU FCB+33 ;FCB LENGTH ; ; SET UP STACK LXI H,0 DAD SP ; ENTRY STACK POINTER IN HL FROM THE CCP SHLD OLDSP ; SET SP TO LOCAL STACK ARTHAT A JMP TO 0000H REBOOTS) CALL CRLF LHLD OLDSP SPHL ; STACK POINTER CONTAINS CCP'S STACK LOCATION RET ;TO THE CCP ; ; ; SUBROUTINES ; BREAK: ;CHECK BREAK KEY (ACTUALLY ANY KEY WILL DO) PUSH H! PUSH D! PUSH B; ENVIRONMENT SAVED MVI C,BRKF CALL BDOS POP B! POP D! POP H; ENVIRONMENT RESTORED RET ; PCHAR: ;PRINT A CHARACTER PUSH H! PUSH D! PUSH B; SAVED MVI C,TYPEF MOV E,A CALL BDOS POP B! POP D! POP H; RESTORED RET ; CRLF: MVI A,CR CALL PCHAR MVI A,LF CALL PCHAR RET ; ; PNIB: ;PRINT NIBBLE IN REG A ANI 0FH ;LOW 4 BITS CPI 10 JNC P10 ; LESS THAN OR EQUAL TO 9 ADI '0' JMP PRN ; ; GREATER OR EQUAL TO 10 P10: ADI 'A' - 10 PRN: CALL PCHAR RET ; PHEX: ;PRINT HEX CHAR IN REG A PUSH PSW RRC RRC RRC RRC CALL PNIB ;PRINT NIBBLE POP PSW CALL PNIB RET ; ERR: ;PRINT ERROR MESSAGE ; D,E ADDRESSES MESSAGE ENDING WITH "$" MVI C,PRINTF ;PRINT BUFFER FUNCTION CALL BDOS RET ; ; GNB: ;GET NEXT BYTE LDA IBP CPI 80H JNZ G0  ; STACK AREA DS 64 ;RESERVE 32 LEVEL STACK STKTOP: ; END ARRY SET FOR EOF STC RET ; G0: ;READ THE BYTE AT BUFF+REG A MOV E,A ;LS BYTE OF BUFFER INDEX MVI D,0 ;DOUBLE PRECISION INDEX TO DE INR A ;INDEX=INDEX+1 STA IBP ;BACK TO MEMORY ; POINTER IS INCREMENTED ; SAVE THE CURRENT FILE ADDRESS LXI H,BUFF DAD D ; ABSOLUTE CHARACTER ADDRESS IS IN HL MOV A,M ; BYTE IS IN THE ACCUMULATOR ORA A ;RESET CARRY BIT RET ; SETUP: ;SET UP FILE ; OPEN THE FILE FOR INPUT XRA A ;ZERO TO ACCUM STA FCBCR ;CLEAR CURRENT RECORD ; LXI D,FCB MVI C,OPENF CALL BDOS ; 255 IN ACCUM IF OPEN ERROR RET ; DISKR: ;READ DISK FILE RECORD PUSH H! PUSH D! PUSH B LXI D,FCB MVI C,READF CALL BDOS POP B! POP D! POP H RET ; ; FIXED MESSAGE AREA SIGNON: DB 'FILE DUMP VERSION 1.4$' OPNMSG: DB CR,LF,'NO INPUT FILE PRESENT ON DISK$' ; VARIABLE AREA IBP: DS 2 ;INPUT BUFFER POINTER OLDSP: DS 2 ;ENTRY SP VALUE FROM CCP ;!9"1W͜Q>2!͢QG}DrYQ|͏}͏#> ex͏#r* _> e> e ҉0Ë7e}} :³ʳ7_<2!~ɯ2|\\FILE DUMP VERSION 1.4$ NO INPUT FILE PRESENT ON DISK$!Y , <    *$A!6 # T!w $r# *`: 0 *A*! ~ ʰxkb))))_y‘BK{ͅ*!66!"80*{#z+++ # ; READ ANOTHER BUFFER ; ; CALL DISKR ORA A ;ZERO VALUE IF READ OK JZ G0 ;FOR ANOTHER BYTE ; END OF DATA, RETURN WITH CARRY SET FOR EOF STC RET ; G0: ;READ THE BYTE AT BUFF+REG A MOV E,A ;LS BYTE OF BUFFER INDEX MVI D,0 ;DOUBLE PRECISION INDEX TO DE INR A ;INDEX=INDEX+1 STA IBP ;BACK TO MEMORY ; POINTER IS INCREMENTED ; SAVE THE CURRENT FILE ADDRESS LXI H,BUFF DAD D ; ABSOLUTE CHARACTER ADDRESS IS IN HL MOV A,M ; BYTE IS IN THE ACCUMULATOR ORA A ;RESET CARRY BIT RET ; SETUP: ;SET UP FILE ; OPEN THE FILE FOR INPUT XRA A ;ZERO TO ACCUM STA FCBCR ;CLEAR CURRENT RECORD ; LXI D,FCB MVI C,OPENF CALL BDOS ; 255 IN ACCUM IF OPEN ERROR RET ; DISKR: ;READ DISK FILE RECORD PUSH H! PUSH D! PUSH B LXI D,FCB MVI C,READF CALL BDOS POP B! POP D! POP H RET ; ; FIXED MESSAGE AREA SIGNON: DB 'FILE DUMP VERSION 1.4$' OPNMSG: DB CR,LF,'NO INPUT FILE PRESENT ON DISK$' ; VARIABLE AREA IBP: DS 2 ;INPUT BUFFER POINTER OLDSP: DS 2 ;ENTRY SP VALUE FROM CCP ;!!6e*!M͛ /$^L:!@OL:! 2͑e:b:! L:h<2hb:! b:hO>!hw:! pX:! …!!6  LÊ!!6ûô:!ʛ͑:! ҩ OҸû:!R†!6G>!!!6 :2.t -? >!!6!6s, !6:xB!6OU2!SB!G6:҃!6:G҃*G& ~2!:G<2G_ Qқ=e  b:!-®! 6:!#¿͇;J:!:!!6Lv:!:Jv: *#"͎! 6:!B)! >w!"&*o"(R :!C:eR :!DKeX :!K\ͷX :!Lj^ :!Pš͎҇! 6F×͢җ:Ç :!T¨F :!U¾: 2 :!V͎"$DMͩ/ *oDMͩ : 2 :! (::H%^bF : ͎H :!Ay! 6*""&*o"(R͎an͢na! 6R :!F”͢ґ Ä :!J $:2$͢ :=2:<2!*& ~2!ü*""I*M*o/!:":7 e !p+q*DM  =? ) !p+q.*DMF -L *9"`!"b!h6!j6!|6.!=\ -x !e:dʥ *eM \R :xʥ @ *dM \, :x \͕ :x - V :e _ :f w : =e !e:d*eM =e : =e =͕ !]6:x>- !"!76!6!6!66*dM  *dM !6:8!*`*;DM \u 2xʻ>!xҨ- *`*;6:82*`"`:<2w!"`9`h*`*;~2*`#"`:*eM !b+!s{!f!6:!b*b*^DM =ͅ N- *b"b:<2)f!"b!q9bڀ*b*^:w*b#"b!q:6ڶZͅ ʱ- !66*6& :w:6<26!J6*b}:J<2Jm=? :x- : ;*dM .=\ -=ͨ ;: *eM =ͨ .M= -C!q:Y*M !q:a/>z!/H!q*MaҎ:_:!q:ҥ*My:!p+q!'"!6>**ͪ{2**ͪ"*! ͪ":!! COPYRIGHT (C) 1979, DIGITAL RESEARCH DISK OR DIRECTORY FULL$FILE EXISTS, ERASE IT$NEW FILE$** FILE IS READ/ONLY **$"SYSTEM" FILE NOT ACCESSIBLE$BAK$$$BAK$$$-(Y/N)?$NO MEMORY$BREAK "$" AT $1mM"m +!8s~1m!f6 *M  *!M 1m! 6!6! 6: 2Ebͽ!e:d\::eH2 H҆ͽ:e2!:d2e:!2dû :!I¬!: :H2 ҮX:h2iҐ:!ʍ:!:!H:!H,!"! 6#~ F)ͷX:! X):i!h)9 e:!:h2jO>F L>!":i!jHҼ*"+M ~ ʼͲ!f6!h6!"! 6F!f6:h2k!iҠ:i2k:j2h:k!hҶ9 æ:h2j!!6:j2he:! >"Ͳ*"M ~2!O :! *+""&! 6R*I""ë :!M:H| ! 6>F ͛e: <2 O! Hqy d F : 2! 6*#s#r :!N ͢ *o/ Ҧ Ͷn! 6!"&R! 6o$ Î Ç :!S0 $͢- :2"+s#r!:* *& ~2!:<2 :!W> v :!X³ Z͎\ Ee ð :7/҃ E!76e ͕ :xƒ - ͷ*&"K(Kڰ *KM N͔*K"KҌ :!Z ͎  ͢ : :!  'v!gq:f *g&!lq:l $ !h4:l 1 !h6*lM :hB     !h55!mq:m :hO>H2ny} !m6 !o6:n!oښ *mM !o4‚ !pq:p ڪ >:p :p H:p H!qq*qM͛  ^W :q@2q*qMW   !sp+q*r !up+q *tDM !wp+q*v !zp+q*y2x!|p+q*{2x!~p+q*}2x!p+q*!p+q*!p+q*!p+q*2x!p+q*!6   >>! q* &!p+q*6:0O  ú!p+q:/(*DMͩ:  : I N* *DM:aO>!Һ x!: ڦ> ʡ* +" >¡! 6: <2 =O! N͒:  O͒: ! 6:h!o$O* ͸ ! 6 !h6!: 2 3* & 6 : <2 =O! N͒*dM  :sGsu n>!6:<2=O! N͒!">!"͎/Ҵ*+">>!": *#"*""*!".+",*$"**o".!",!36:3{.*22*,**"0M ~ H3*0"**+"*+">23:2/k!36,*+s#rx:3x*0"*: “**"&*"+"(á*$#"&**#"(*"#""*$#"$*"+""*$+"$*#"!4qM*"*$: *(y"$DM}|C#~ *#"*&DMyxC 1*+":4?w+"$""ͷR: —*$"("҈!"&Ô""&*""&$mڸ*o"(**$"($"O26͛*"M :6w͢:6 *FM8 *FM   Oy2F :FY5>>:!02HO> /!";u*)))*) *H& "PҘ! 6+s#ré! 6"DM!>))덑o|g =±^#V) ^#V|g}o _{ozgi`N#Fogo&og_{_z#W H = LIBX$$$$$$$LIB$:2*o/*!My:<2=O!s Hq**DMͷ! 6: e!"*""?k*&"?*?+M ~2A :hHҏ *&"?(?:A ½8*#" ҽ*?M ~2AO *?"?ҕ!"*"*"^: 2B! 6F:B2 o(>&H6͛9!C6>!Ca R>:C<2C?! 6!"͇͢Ґq"ڊ͛Íq!!6 !!6 !6*!Ma2D*!M͒2!:D/!+w!6e2!͢!Eq!E:!:H:H!Fq@ COPYRIGHT (C) 1978, DIGITAL RESEARCH ERROR: $, LOAD ADDRESS $DISK READ$INVERTED LOAD ADDRESS$DISK WRITE$LOAD ADDRESS $ERROR ADDRESS $BYTES READ:$INVALID HEX DIGIT$CHECK SUM ERROR $FIRST ADDRESS $LAST ADDRESS $BYTES READ $RECORDS WRITTEN $HEXCANNOT OPEN SOURCE$COMNO MORE DIRECTORY SPACE$CANNOT CLOSE FILE$*!9"!e !" !" \!""͊: ƒde"\\\͊: ²d\͝: )d;! q* &f  ! q> ! : A O: 0O! q: O: O! p+q* |O* }O! p+q*  f! p+q* DMB! p+q)R* DMB1B* DM+;! p+q* i2 ! p+q* i2 ! p+q* i2 i2 !" p+q*! f!$ p+q*# i!& p+q*% i!( p+q*' i2 !* p+q*) f!/ s+p+q+p+q:/ =2/ X*+ *- w*+ #"+ *- #"- 1* #" ͖r*   ~!" ! ͸×* " x20 º*   DM":0 Ad*   6!" Ç!" : !"6 "8 ": }2< !"4 "= ! !7q:*7M͒:7o$+͛ͪ*$M ~28Om:8 I͇͢u$oqo͛rP! 6!"&*$"(R͎ҔM͢ҡÔ($ҵ! 6R͇vͶ2!*!Mm$"*"M :!w͢:! e2!:! : /HH/Q:! @!!6 R!!6 :!KR$*& :!w:<2dn!:s+q*$";!>6:>/;oH*;#"(";:92=*=& *(M !::=2>/H:=<2=*(#"(æÀ:>*(+"(R:>!6$:2*o/*!My:<2=O!s Hq**DMͷ! 6: e!"*""?k*&"?*?+M ~2A :hHҏ *&"?(?:A ½8*#" ҽ*?M ~2AO *?"?ҕ!"*"*"^: 2B! 6F:B2 o(>&H6͛9!C6>!Ca R>:C<2C?! 6!"͇͢Ґq"ڊ͛Íq!!6 !!6 !6*!Ma2D*!M͒2!:D/!+w!6e2!͢!Eq!E:!:H:H!Fq 6Y: !2 6=21 á:1 : r+s#r==_HL"4 " >6 ͪS* "6 =23 :1 =21 v=O* #" Y8  ͝҉* +"8 .!2 ʞR̀* "4 4 = ͝* #" çR*6 DM+R*8 DM+R*: DM+R*< M!? q=  ͝Kd*= ! ͸p!@ 6>!@ X*= }O!< *@ & w*= #"= !@ 4)!< 4\mad* }O!< :? wlR*4 DM+{R* DM+R 4 ͝*4 }¿= 4 ͝< N*4 #"4  å;*4 DM+: Y2A 0O> :A 0:A AO>&R̀:A A H.2B !2 w:B !D s+q*C &͍:D _og_{ozg^#V) _{ozgi`N#Fogo&og_{_z#W6FH DB 3 DB 5 DB 28 DB 0FFH ; DW 40 DB 4 DB 15 DB 1 DW 94 DW 127 DB 0C0H DB 0 DW 32 DW 2 DB 0EFH ; REVERR: LD DE,RVMSG CALL MESG JP BTERR ; RVMSG: DB CR,LF,'Wrong revision of ROM. This version of CP/M requires ROM Rev. 2.2',CR,LF,0 ; END  ;Sector must be read if = 1. ; READOP EQU 3 ;Read if = 1. Write if = 0. ; HNDSHK EQU 4 ;Handshake with DSR and CTS if 1, just CTS if 0. ; LSTMAP EQU 5 ;1=>Cent. is LST:, SER2 is PUN: ;0=>SER2 is LST:, Cent. is PUN: ; IMS EQU 6 ;In Memory Submit flag. ;I.M.S. in-active if = 0. ;I.M.S. active if = 1. ; IMSBUF EQU 7 ;In Memory Submit buffer empty flag. ;I.M.S. buffer is empty if = 0. ;I.M.S. buffer is not empty if = 1. ; ; ROMCTL EQU 0F6H ; DPHOFF EQU 10 ; BDFM EQU 5 NRDY EQU 6 SIZMSK EQU 18H DSM EQU 2 ; ; WRALL EQU 0 WRDIR EQU 1 WRUAL EQU 2 ; ; S1STAT EQU 0FDH S1DATA EQU 0FCH ; S2DATA EQU 0FEH S2STAT EQU 0FFH ; CSTAT EQU 0F5H CTCSEL EQU 0F3H ; CHANNEL SELECT PORT FOR CTC CH1DIV EQU 0F1H ; PORT FOR SETTING BAUD RATE OF 1st SERIAL PORT CH2DIV EQU 0F2H ; PORT FOR SETTING BAUD RATE OF 2nd SERIAL PORT DFLT1 EQU 06h ; default baud rate for 1st serial port DFLT2 EQU 03h ; default baud rate for 2nd serial port ; CR EQU 0DH LF EQU 0AH ASC0 EQU 30H ; ; MICRO-DECSION ; BOOT LOADER REV 1.4 ; COPYRIGHT 1982 ; MORROW DESIGNS, INC. ; 05/26/83 ; BOOT EQU 0FE00H ; .Z80 .PHASE BOOT ; ; REVNUM EQU 22H ; MEMSIZE EQU 64 ; CPM EQU (MEMSIZE-9)*1024 BIOS EQU CPM+1600H ; MTOFF EQU 26 ; REVADD EQU 7FDH ; HSTSEC EQU 2 HSTTRK EQU 1 HSTBUF EQU 5 SECCNT EQU 3 ERFLAG EQU 7 SECSIZ EQU 12 ; ROM EQU 0 ; RDHST EQU ROM+9 BTERR EQU ROM+18H MESG EQU ROM+3 ; CR EQU 0DH LF EQU 0AH ; START: LD A,(REVADD) CP REVNUM JP NZ,REVERR ; PUSH IY ;CALC. MTAB POSITION POP HL LD DE,MTOFF ADD HL,DE ; EX DE,HL ;MOVE MTAB INTO RAMDATY LD HL,BTAB LD BC,9 LDIR ; LD (IX+HSTSEC),2 LD (IX+SECCNT),8 LD (IX+SECSIZ+1),81H LD (IX+HSTBUF+1),HIGH CPM ; CALL RDHST ; LD A,(IX+ERFLAG) OR A JP NZ,BTERR ; LD (IX+HSTSEC),1 LD (IX+HSTTRK),1 LD (IX+SECCNT),9 LD (IX+HSTBUF+1),HIGH CPM + 16 ; CALL RDHST ; LD A,(IX+ERFLAG) OR A JP NZ,BTERR ; JP BIOS ; DS (BOOT+80H-$),0 ; BTAB: DB 1 DB 0D8H DB 88 DB 5 DB ; MICRO-DECISION ; CP/M 2.2 ; BIOS REV 2.1 ; COPYRIGHT 1982,1983 ; MORROW DESIGNS, INC. ; SAN LEANDRO, CA. ; ; 05/26/83 ; ;*********************************************************************** ; SINGLE SIDED ;*********************************************************************** ; .Z80 ; MEMSIZE EQU 64 ; REV EQU 21H ; CPM EQU (MEMSIZE-9)*1024 BDOS EQU CPM+806H BIOS EQU CPM+1600H ; .PHASE BIOS ; ; ROM EQU 0 ; HMRM EQU ROM+6 WRHSRM EQU ROM+0CH RDHSRM EQU ROM+9 DISRM EQU ROM+0FH BTERM EQU ROM+18H ROMDATX EQU ROM+1BH MSGRM EQU ROM+3 CENTDRV EQU ROM+1DH ;ROM ENTRY POINT FOR CENTRONICS DRIVER RDLSEC EQU ROM+20H WRTLSEC EQU ROM+23H ; ; CONTROL BITS WITHIN DFLAG BYTE HSTACT EQU 0 ;Host buffer active flag. ;Buffer contains nothing if = 0. ;Buffer contains a sector if = 1. ; HSTWRT EQU 1 ;Host buffer dirty flag. ;Buffer has not been written to if = 0. ;Buffer has been written to if = 1. ; RSFLAG EQU 2 ;Read sector flag. ;Sector need not be read if = 0.  START: JP BOOT WBOT: JP WBOOT JP CONST JP CONIN CNOUT: JP CONOUT JP LST JP PUN JP PTR JP HOME JP SELDSK JP SETTRK JP SETSEC JP SETDMA JP READ JP WRITE JP LISTST JP SECTRAN ; JP CVMSG ;CHANGE VIRTUAL DRIVE MESG. ; JP RDBLK ;DIRECT DISK READ JP WRBLK ;DIRECT DISK WR JP DISCIO ;DIRECT DISK I/O ; DB REV DW RAMDATX DW RAMDATY DW MTAB DW XLTAB ; ETBLPTR:DW ESCTBL CTBLPTR:DW CTRLTBL EVCTPTR:DW ESCVECT CVCTPTR:DW CTVECT DW DCASTRT ; JP INITCTC ;CTC init routine ; WBOOT: LD SP,STACK LD DE,DSKBUF PUSH DE POP IX LD BC,DATXLN OUT (ROMCTL),A ;TURN ON ROM LD HL,(ROMDATX) LDIR ; LD IY,RAMDATY ; LD (IX+HSTSEC),2 LD (IX+SECCNT),8 LD (IX+SECSIZ+1),81H LD (IX+HSTBUF+1),HIGH CPM ; CALL RDHST ; LD A,(IX+ERFLAG) OR A JP NZ,BTERR ; LD (IX+HSTSEC),1 LD (IX+HSTTRK),1 LD (IX+SECCNT),3 LD (IX+HSTBUF+1),HIGH CPM + 16 ; CALL RDHST ; LD A,(IX+ERFLAG) OR A JP NZ,BTERR ; LD HL,CPM+3 ; GOCPM: LD BC,80H CALL SETDMA ; HL,BAUDTBL ; POINT TO BASE OF TABLE LD B,0 ADD HL,BC ADD HL,BC ; HL NOW POINTS TO DIVISOR FOR SELECTED BAUD RATE RET ; SETBAUD: ; OUTPUT THE VALUES POINTED TO BY HL TO THE ; PORT SELECTED IN REG. C. LD A,(HL) ; GET LOW BYTE OF DIVISOR OUT (C),A ; OUTPUT IT INC HL ; POINT TO HIGH BYTE LD A,(HL) ; GET THE HIGH BYTE OF DIVISOR OUT (C),A ; OUTPUT IT RET ; baudtbl: ; DIVISOR TABLE FOR BAUD RATES ; DW 1136 ;110 DW 417 ;300 DW 208 ;600 DW 104 ;1200 DW 52 ;2400 DW 26 ;4800 DW 13 ;9600 ; ; CONST: IN A,(S1STAT) ;CONSOLE STATUS ROUTINE AND 2 ;SEE IF RDY RET Z ;RETURN WITH 0 IF NOT RDY LD A,0FFH ;RETURN WITH FF IF RDY RET ; CONIN: LD A,(RAMDATY+DFLAG) ;GET DFLAG AND 0C0H ;MASK OUT IMS FLAGS CP 0C0H ;CHECK IF IMS ACTIVE JR Z,SUBMT ;JMP IF SUBMIT ACTIVE ; CNIN: IN A,(S1STAT) ;CONSOLE INPUT ROUTINE BIT 1,A ;SEE IF RDY JR Z,CNIN ;JMP IF NOT RDY ; IN A,(S1DATA) ;GET CHARACTER CHRET: AND 7FH ;MASK OFF PARITY RET ; ; SUBMT locatesHL),E INC HL ; LD A,E ;SEE IF LAST CHAR. OR D LD A,(RAMDATY+DFLAG) JR NZ,SKP1 ;JMP IF NOT LAST CHAR. ; RES IMSBUF,A ;CLEAR IMSBUF FLAG ; SKP1: BIT PARITY,(HL) ;CHECK PARITY BIT OF CHAR. JR Z,SKP2 ;JMP IF PARITY = 0 ; RES IMS,A ;DE-ACTIVATE IMS ; SKP2: LD (RAMDATY+DFLAG),A ;SAVE DFLAG ; LD A,(HL) ;GET CHAR. LD (HL),D ;FINISH UPDATING IMS BLOCK HEADER JR CHRET ;RETURN TO CP/M ; ; FIND searches BIOS ram area starting from HL for the block ; header contained in A. ; FIND: CP (HL) ;SEE IF HEADER CODE MATCHES INC HL ;INCREMENT POINTER ; LD E,(HL) ;GET OFFSET TO NEXT BLOCK INC HL LD D,(HL) ; RET Z ;RETURN IF BLOCK FOUND ; INC HL ;SET POINTER TO NEXT BLOCK ADD HL,DE JR FIND ;KEEP LOOKING ; ; ; On entry to XLATE, register C contains the character to be output. ; A test is made to see if the system is in the process of outputing ; a multiple character escape sequence, or if the character is a ; Morrow Standars Control Code. If neither test is true, than  LD A,0C3H LD (0),A LD (5),A ; XOR A LD (3),A ; PUSH HL LD HL,WBOT LD (1),HL ; LD HL,BDOS LD (6),HL ; LD HL,(VNUMB) LD (8),HL ; LD A,(IY+DFLAG) AND 0B0H ;MASK IMSBUF FLAG, DON'T CHANGE BITS 4 OR 5 SET IMS,A ;ACTIVATE IMS LD (IY+DFLAG),A ; LD (IY+UNACNT),0 ; LD A,(4) LD C,A ; POP HL JP (HL) ; BTERR: OUT (ROMCTL),A JP BTERM ; ; INITCTC: ; SET BAUD RATES FOR BOTH SERIAL PORTS LD A,07EH ; SELECT CTC CHANNEL 1 OUT (CTCSEL),A LD A,(SER1BAUD) ; GET BAUD RATE FOR 1st SERIAL PORT LD C,A CALL GETVAL ; POINT TO DIVISOR LD C,CH1DIV ; SET UP TO LOAD DIVISOR FOR CHANNEL 1 CALL SETBAUD ; SET BAUD RATE FOR 1st SERIAL PORT LD A,0BEH ; SELECT CTC CHANNEL 2 OUT (CTCSEL),A LD A,(SER2BAUD) ; GET BAUD RATE FOR 2nd SERIAL PORT LD C,A CALL GETVAL ; POINT TO DIVISOR LD C,CH2DIV ; SET UP TO LOAD DIVISOR FOR CHANNEL 2 CALL SETBAUD ; SET IT RET ; GETVAL: ; SET HL TO POINT TO DIVISOR FOR SELECTED ; BAUD RATE. C IS OFFSET FROM BASE ON ENTRY LD  the submit string block within the BIOS ram area, ; the next character is taken from the buffer and passed to CP/M. ; The free block and submit string block pointers are updated. ; If this was the last character in the buffer, then the IMSBUF ; bit in dflag is cleared. ; If the parity bit is set on the character, then the IMS bit in ; dflag is cleared, which de-activates IMS until the next warm ; boot. ; ; PARITY EQU 7 ; SUBMT: IN A,(S1STAT) ;SEE IF CHAR. READY BIT 1,A JR Z,SUBGO ;JMP IF NO INPUT ; IN A,(S1DATA) ;GET CHAR. CP 3 ;SEE IF CNTL-C JR NZ,SUBGO ;JMP IF NOT ; LD A,(RAMDATY+DFLAG) ;DE-ACTIVATE IMS RES IMSBUF,A LD (RAMDATY+DFLAG),A ; LD A,18H RET ; SUBGO: LD HL,XLTAB ;POINTER TO RAM AREA LD A,0FFH ;FREE SPACE CODE CALL FIND ;FIND FREE SPACE ; INC DE ;UPDATE FREE SPACE POINTER LD (HL),D DEC HL LD (HL),E ; ADD HL,DE ;SET HL ==> IMS BUFFER INC HL INC HL ; LD E,(HL) ;UPDATE IMS BUFFER HEADER LD (HL),0FDH INC HL LD D,(HL) DEC DE LD ( the ; character is output. ; If the character is part of a multiple character escape sequence, ; then the character is passed to the ESCAPE routine. If the ; character is a MSCC, then it is converted to the appropriate ; sequence, and output. ; esc equ 1bh ; conout: ld a,(esc_lvl) ; test escape flag or a ; check if flag is set jr nz,ESCAPE ; if escape sequence, jump ld a,1fh ; test if MSCC cp c jp c,cout ; if not, then xmit it ld a,esc ; check if esc char cp c ; jp nz,notesc ; if not, jump ld a,1 ; otherwise, set escape ld (esc_lvl),a ; level to 1st stage ret ; and return notesc: ld hl,(ctblptr) ; set to search control table call lookup ; and lookup character in table or a ; see if char found jp z,cout ; if not, output char ld hl,(cvctptr) ; calculate string location ; ; subroutine: outstr ; ; This routine outputs a string of characters to the console. ; It is used by the translate program to output a terminal ; specific string in order to implement a sign, ; then two more characters will be accepted, after-which a string ; will be output for positioning the cursor. ; escape: ld a,(esc_lvl) ; get current escape level cp 1 ; level 1? jr z,seq1 ; then process 1st part cp 2 ; level 2? jr z,seq2 ; then process 2nd level jr seq3 ; it must be level 3 ; seq1: ld a,'=' ; equal sign? cp c ; if char is =, then DCA started jr z,set ; else, could be character to xlate xor a ; clear escape level ld (esc_lvl),a ld hl,(etblptr) ; point to xlate table call lookup ; lookup character or a ; see if char found jr nz,down ; if found, jump to output push bc ld c,esc ; else, send escape, then char call cout ; send escape pop bc ; get original character jp cout ; send it ; down: ld hl,(evctptr) ; calculate string location jr outstr ; output the string set: ld a,2 ; otherwise, set for level 2 ld (esc_lvl),a ; processing ret ; and return ; seq2: ld a,c ld (first),a ; this is the first char ld a,3 ; set char to output ld c,a pop af call nz,ascout ; call ascii if flag set call cout ; output char ; outend: ld hl,dcaend ; point to dca terminator jp loop ; ; ; subroutine: lookup ; ; This routine is entered with the HL register pair pointing to ; the base of a table to be searched. Register C contains the ; character to search for. Upon return, The accumulator will ; contain 0 if the character was not found, and ffh if it was found. ; If the character was found in the table, then bc will contain ; the offset into the table, multiplied by 2. i.e BC / 2 = location ; of character in table. The maximum number of values in the table is ; 20 h. ; lookup: ld b,0 ; init offset nmtch: ld a,(hl) ; get value from table cp 0ffh ; see if end of table jr z,nochar ; jmp if end ; cp c ; see if char matches jr z,mtch ; jmp if match ; inc hl ; inc table pointer inc b ; inc offset inc b ; " " jr nmtch ; continue search ; mtch: ld c,b ; put offset in bc ld b,0 ld a,0control sequence. ; When entered, the HL register pair points to the base of ; the string table, and the BC register pair is the offset ; to the string. Characters are output starting with the ; first character until a byte value of ffH is detected. ; outstr: add hl,bc ; add offset to base ld e,(hl) ; get location of string inc hl ld d,(hl) ex de,hl ; move address of string to hl loop: ld a,(hl) ; get a char cp 0ffh ; see if done ( ffh==>done) ret z ld c,a ; if not, get char call cout ; xmit it inc hl jr loop ; until end of string ; ; This routine is used to create a string for direct ; cursor addressing, or to translate character codes. ; Upon receipt of an Escape code from ; a program, the esc_lvl is set to indicate an escape ; sequence is being output. When the next character is ; received, it is tested to see if it is an equals sign (=). ; If it is not, than an escape character is output, followed ; by the character received. If the character is the equal for level 3 ld (esc_lvl),a ret ; seq3: ld a,(offset2) ; get offset for 2nd char add a,c ; add to 2nd char ld (second),a ; save 2nd char ; ld a,0 ld (esc_lvl),a ; clear escape sequence ; ld de,first ; pointer to 1st char ; ld a,(de) ; get 1st char ld c,a ; save in c ld a,(offset1) ; get offset for 1st char add a,c ; add to 1st char ld (de),a ; save 1st char ; ld a,(order) push af rra sbc a,a ; 0==>1-2 : FF==>2-1 ld b,a ; save order in b ; ld a,e ; use order to adjust de sub b ld e,a ; de points to 1st char to output ; ld hl,dcastrt ; pointer to dca prefix sting call loop ; output string ; ld a,(de) ; get 1st char to output ld c,a pop af bit 1,a ; see if ascii push af call nz,ascout ; call ascii if nz call cout ; output char ; ld hl,dcamid ; pointer to seperator string call loop ; output string ; ld a,e ; use order to adjust de add a,b inc b add a,b ld e,a ; de points to 2nd char to output ; ld a,(de) ; get  ffh ; set a to success ret ; nochar: xor a ; set a to failure ret ; ; ; ASCOUT takes a binary value in C and output its decimal ascii ; equivalent. ; ascout: push bc ld a,c ld c,'0' ;init to ascii 0 ; tens: sub 10 ;subtract 10 from value jr c,ones ;jmp if underflow inc c ;inc ascii tens value jr tens ;loop ; ones: ld b,a ;save intermediate value ld a,'0' ;a = ascii 0 cp c ;see if tens value is 0 call nz,cout ;output tens value if not 0 ; ld a,3ah ;ascii 0 plus 10 add a,b ;add to produce ones value pop bc ld c,a ;get ready for output ret ; ; COUT: IN A,(S1STAT) ;CONSOLE OUTPUT ROUTINE BIT 0,A ;SEE IF RDY JR Z,COUT ;JMP IF NOT RDY ; LD A,C ;OUTPUT CHARACTER OUT (S1DATA),A RET ; ;XON/XOFF PROTOCOL HANDLER FOR MICRO DECISION CBIOS ; LST: LD A,(RAMDATY+DFLAG) ; GET FLAG BYTE TO CHECK WHICH OUTPUT DRIVER BIT 5,A ; SEE IF CENTRONICS BIT SET JR NZ,CENTOUT ; IF SO, USE CENTRONICS DRIVER ; ELSE, USE SERIAL PORT DRIVER LSTDRV: CALL SSTAT ;  FLAG CP 05h ; SET FLAGS ON STATUS OF TBRE STAT: LD A,0 ; SET NOT READY STATUS JR NZ,LSTRET ; JMP IF NOT READY DEC A ; SET READY STATUS RET ; AND RETURN IT. ; ; RDRSTAT: IN A,(S2STAT) ; GET STATUS AND 2 RET Z ; RETURN IF NO CHAR IN A,(S2DATA) ; ELSE, GET CHAR AND 7FH ; MASK PARITY SCF ; SET FLAG RET ; CENTSTAT: IN A,(CSTAT) ; CHECK CENTRONICS RDY STATUS BIT 4,A LD A,0 RET NZ DEC A RET ; ; PTR: CALL RDRSTAT ;GET STATUS OR CHAR. JR NC,PTR ;LOOP IF NO CHAR. RET ; PUN: LD A,(RAMDATY+DFLAG) ;CHECK IF CENT. OR SERIAL BIT 5,A JR Z,CENTOUT ;IF ZERO, THEN USE CENTRONICS JR LSTDRV ; USE SERIAL PORT DRIVER CENTOUT: CALL MSTK ; SAVE STACK OUT (ROMCTL),A ; TURN ON ROM CALL CENTDRV ; USE ROM CENTRONICS DRIVER IN A,(ROMCTL) ; TURN OFF ROM POP HL ; RESTORE STACK LD SP,HL RET ; HOME: CALL MSTK ;FIX STACK ; PUSH IX ;SAVE IX & IY PUSH IY ; LD IX,RAMDATX ;INIT IX & IY LD IY,RAMDATY ; OUT (ROMCTL),A ;TURN ON ROM ; CAL) ;X-OR TABLE VALUE INTO PARITY CHECK BYTE LD D,A ;SAVE PARITY CHECK BYTE OR E ;OR IN 0-CHECK BYTE LD E,A ;SAVE 0-CHECK BYTE LD A,D ;RESTORE PARIY CHECK BYTE DJNZ CHKLP ;DEC TABLE LENGTH & LOOP TIL DONE INC HL ;HL=>DSKDEF1 ; OR A ;A=0 IF TABLE OK LD A,E ;A = 0-CHECK BYTE LD DE,SDPB ;POINTER TO S.S. DPB JR NZ,SSIDE ;ASSUME S.S. IF INVALID TABLE ; OR A ;CHECK 0-CHECK BYTE JR Z,SSIDE ;INVALID TABLE IF ZERO ; DSKTDB EQU DSKBUF+80H+9 LD DE,DSKTDB ;POINTER TO DPB IN BOOT ; BIT DSM,(HL) ;SEE IF D.S. MEDIA JR Z,SSIDE ;JP IF S.S. ; POP HL ;GET DSKDEF POINTER SET DSM,(HL) ;SET FOR D.S. MEDIA JR DSIDE ; SSIDE: POP HL RES DSM,(HL) ;SET FOR S.S. MEDIA ; DSIDE: XOR A ;SET Z FLAG SKPST1: LD H,0 ;CALC. DPB POINTER LD L,C ; ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ; LD BC,DPBASE ADD HL,BC ;HL=DPB POINTER ; PUSH HL ;SAVE DPB POINTER PUSH DE ;SAVE NEW DPB POINTER LD DE,DPHOFF ;OFFSET TO DPH POINTER ADD HL,DE ;GET POINTER TO DPH LD E,(HL) ISTATUS OF LSTFLG JR Z,LSTDRV ; IF NOT READY, LOOP OVER: LD A,C ; ELSE, GET CHAR OUT (S2DATA),A ; XMIT IT RET ; ; LISTST: LD A,(RAMDATY+DFLAG) ; GET PORT MAPPING BIT 5,A ; SEE IF CENTRONICS PORT JR NZ,CENTSTAT ; IF CENTRONICS, CHECK IT'S STATUS SSTAT: CALL RDRSTAT ; GET A CHARACTER, OR NULL CP 13H ; IF XOFF R'CVD... JR NZ,NXTCHK ; IF NOT, CHECK IF XON XOR A ; SET FLAG TO NOT RDY LD (LSTFLG),A RET ; RETURN NOT RDY NXTCHK: CP 11H ; IF XON, THEN IT MIGHT BE READY JR NZ,CHKFLG ; ELSE, STATE NOT CHANGING LD A,0FFH LD (LSTFLG),A ; SET FLAG TO RDY CHKFLG: LD A,(LSTFLG) ; GET STATUS FLAG LSTRET: OR A ; SET FLAGS RET Z ; IF ZERO, THEN XOFF PENDING LD A,(RAMDATY+DFLAG) ;SEE IF HRDWR HNDSHKNG ENABLED BIT 4,A JR Z,CTS ; IF 0, THEN USE ONLY CTS HANDSHAKING IN A,(S2STAT) ; GET STATUS AND 85H ; CHECK IF XMIT READY CP 85H ; SET FLAGS ON STATUS OF TBRE AND DSR JR STAT ; JUMP TO STATUS TEST CTS: IN A,(S2STAT) ; TEST STATUS, IGNORE DSR BIT AND 05h ; GET TBREL HMRM ;CALL ROM ; CRETN: IN A,(ROMCTL) ;TURN OFF ROM POP IY ;RESTORE IX & IY POP IX ; POP HL LD SP,HL ;FIX STACK ; RET ; MSTK: POP DE ;SAVE RET. ADDR. ; LD HL,0 ;GET CURRENT STACK ADD HL,SP ;IN HL. ; LD SP,STACK ;MOVE STACK PUSH HL ;SAVE OLD STACK ; PUSH DE ;RESTORE RET. ADDR. RET ; SELDSK: LD A,4 ;CHECK DRIVE BOUND CP C JR C,BDRV ;JMP IF BAD ; LD A,C ;SET DRIVE LD (SEKDSK+RAMDATY),A ; BIT 0,E ;SEE IF FIRST TIME JR NZ,SKPSET ;JP IF NOT FIRST ; LD HL,RAMDATY ;POINTER TO RAMDATY LD A,C CALL GDSK1 ;GET MTAB POINTER ; BIT 7,(HL) ;SEE IF FOREIGN DRIVE JR NZ,SKPSET ;JP IF FOREIGN ; INC HL PUSH HL ;SAVE DSKDEF POINTER PUSH BC CALL GETAB ;READ CONFIG TABLE FROM DISKETTE POP BC OR A ;SEE IF ERROR JP NZ,0 ;WARM BOOT IF ERROR ; DSKTB EQU DSKBUF+80H+25 ;CHECK FOR VALID TABLE LD HL,DSKTB ;POINTER TO END OF TABLE+1 LD B,25 ;COUNT MUST BE ODD! LD E,0 ;INIT 0-CHECK BYTE ; ; ACC IS 0 ALREADY CHKLP: DEC HL ;DEC POINTER XOR (HL NC HL LD D,(HL) POP HL PUSH DE ; JR NZ,NOTAB ; LD BC,15 LDIR ;UPDATE DPB ; NOTAB: POP HL LD A,(HL) ;GET SECTORS PER TRACK LD (SECTRK+RAMDATY),A ;SAVE IN RAMDATY ; INC HL ;INC POINTER INC HL ; LD A,8 ;GET RECORDS PER ALLOC. BLOCK BIT 2,(HL) JR Z,K1 ;JMP IF 1K BLOCKS ; LD A,16 ;2K VALUE ; K1: LD (UNAMAX+RAMDATY),A ;SAVE IN RAMDATY ; POP HL ;RESTORE DPB POINTER RET ; SKPSET: OR 0FFH ;CLEAR Z FLAG JR SKPST1 ; BDRV: LD HL,4 ;RETURN ERROR CODE AND LD (HL),H ;SET TO DRIVE A. LD L,H RET ; ; SETTRK: LD A,C ;SET TRACK IN RAMDATY LD (SEKTRK+RAMDATY),A RET ; ; SETSEC: LD A,C ;SET SECTOR IN RAMDATY LD (SEKSEC+RAMDATY),A RET ; ; SETDMA: LD (DMAADR+RAMDATY),BC ;SET DMA ADDRESS IN RAMDATY RET ; ; READ: CALL MSTK ;FIX THE STACK ; PUSH IX ;SAVE IX & IY PUSH IY ; LD IX,RAMDATX ;INIT IX & IY LD IY,RAMDATY ; OUT (ROMCTL),A ; TURN ON ROM CALL RDLSEC ; READ A LOGICAL SECTOR JR RWMOVE ; MOVE DATA ; WRITE: CALL MSTK ;FIX THE STAC SECTOR LD (IX+HSTTRK),0 LD (IX+HSTSEC),1 OUT (ROMCTL),A ;TURN ON ROM CALL HMRM ;HOME DRIVE ; CALL RDHST ;READ BOOT SECTOR JR DIRET ; SECTRAN:LD L,C ;HL=BC LD H,B ; INC HL ;START SECTORS AT 1 ; LD A,D ;SEE IF XLAT TABLE OR E RET Z ;RETURN IF NO XLAT ; EX DE,HL ;HL=XLT ; ADD HL,BC ;ADD TO TABLE LD L,(HL) ;GET XLATED SECTOR LD H,0 ; RET ; ; WRTHST: OUT (ROMCTL),A ;TURN THE ROM ON ; CALL WRHSRM ;CALL THE ROM ; HSTRET: IN A,(ROMCTL) ;TURN OFF THE ROM ; LD A,(IX+ERFLAG) ;GET STATUS ; RET ; RDHST: OUT (ROMCTL),A ;TURN ON ROM ; CALL RDHSRM ;CALL ROM ; JR HSTRET ;RETURN ; ; RDBLK: LD (IX+ERFLAG),0 ;CLEAR ERROR FLAG ; LD IY,RAMDATY ;INIT IY ; CALL MSTK ;FIX THE STACK ; CALL RDHST ;CALL ROM ; DRET: POP HL ;RESTORE THE STACK LD SP,HL ; RET ; WRBLK: LD (IX+ERFLAG),0 ;CLEAR ERROR FLAG ; LD IY,RAMDATY ;INIT IY ; CALL MSTK ;FIX STACK ; CALL WRTHST ;CALL ROM ; JR DRET ; DISCIO: LD (IX+ERFLAG),0 ;CLEAR ERROR FLAG ; LD IV1 DW ALV1 ; DPE2: DW XLT1K DW 0 DW 0 DW 0 DW DIRBUF DW DPB2 DW CSV2 DW ALV2 ; DPE3: DW XLT1K DW 0 DW 0 DW 0 DW DIRBUF DW DPB3 DW CSV3 DW ALV3 ; DPE4: DW XLT1K DW 0 DW 0 DW 0 DW DIRBUF DW DPB4 DW CSV4 DW ALV4 ; SDPB: DW 40 DB 4 DB 15 DB 1 DW 94 DW 127 DB 0C0H DB 0 DW 32 DW 2 ; DPB0: DW 40 DB 4 DB 15 DB 1 DW 94 DW 127 DB 0C0H DB 0 DW 32 DW 2 ; DPB1: DW 40 DB 4 DB 15 DB 1 DW 94 DW 127 DB 0C0H DB 0 DW 32 DW 2 ; DPB2: DW 40 DB 4 DB 15 DB 1 DW 94 DW 127 DB 0C0H DB 0 DW 32 DW 2 ; DPB3: DW 40 DB 4 DB 15 DB 1 DW 94 DW 127 DB 0C0H DB 0 DW 32 DW 2 ; DPB4: DW 40 DB 4 DB 15 DB 1 DW 94 DW 127 DB 0C0H DB 0 DW 32 DW 2 ; ; RAMDATX: HSTDSK EQU $-RAMDATX DB 0 HSTTRK EQU $-RAMDATX DB 0 HSTSEC EQU $-RAMDATX DB 0 SECCNT EQU $-RAMDATX DB 1 RETRY EQU $-RAMDATX DB 20 HSTBUF EQU $-RAMDATX DW DSKBUF ERFLAG EQU $-RAMDATX DB 0 PHYTRK EQU $-RAMDAK ; PUSH IX ;SAVE IX & IY PUSH IY ; LD IX,RAMDATX ;INIT IX & IY LD IY,RAMDATY ; OUT (ROMCTL),A ; TURN ON ROM CALL WRTLSEC ; WRITE A LOGICAL SECTOR ; ; RWMOVE: OR A ; SET FLAGS ON ACC IN A,(ROMCTL) ; TURN OFF ROM JR NZ,DIRET ; JUMP IF ERROR DURING READ OR WRITE LDIR ;MOVE SECTOR ; LD A,(IY+WRTYPE) ;CHECK IF DIR WRITE CP WRDIR LD A,0 ;A=NO ERROR STATUS IN CASE WE'RE DONE JR NZ,DIRET ;JMP IF NOT DIR WRITE ; RES HSTWRT,(IY+DFLAG) ;CLEAR WRITE FLAG ; CALL WRTHST ;WRITE BUFFER ; DIRET: POP IY ;RESTORE IX & IY POP IX ; POP HL ;RESTORE STACK LD SP,HL ; CP BDFM ;SEE IF UNREADABLE JP Z,BDRV ;JMP IF UNREADABLE ; CP NRDY ;SEE IF NOT READY JP Z,BDRV ;JMP IF NOT READY ; RET ; GETAB: CALL MSTK ;FIX STACK PUSH IX PUSH IY PUSH BC LD IX,RAMDATX LD IY,RAMDATY ; XOR A BIT HSTWRT,(IY+DFLAG) CALL NZ,WRTHST RES HSTWRT,(IY+DFLAG) RES HSTACT,(IY+DFLAG) POP BC OR A ;SEE IF ERROR JR NZ,DIRET ; LD (IX+HSTDSK),C ;SET RAMDATX TO READ BOOTY,RAMDATY ; CALL MSTK ;FIX THE STACK ; OUT (ROMCTL),A ;TURN ON THE ROM ; CALL DISRM ;CALL THE ROM ; IN A,(ROMCTL) ;TURN OFF ROM ; LD A,(IX+ERFLAG) ; JR DRET ;RETURN ; ; GDSK1: LD DE,MTOFF ;CALC. MTAB POINTER ADD HL,DE ; LD E,A ;MULTIPLY DRIVE BY 9 RLCA RLCA RLCA ADD A,E ; LD E,A ;ADD (9 * DRIVE) TO POINTER ADD HL,DE ; RET ; ; CVMSG IS A ROUTINE TO CHANGE THE VIRTUAL DRIVE MESSAGE. ; ON ENTRY: HL POINTS TO THE BEGINING OF THE NEW MESSAGE. ; DE POINTS TO THE LOCATION OF THE CHARACTER ; WHICH WILL BE SET TO THE LOGICAL DRIVE ; THAT THE VIRTUAL DRIVE IS TO BECOME. ; BC IS THE LENGTH OF THE NEW MESSAGE. ; ; AF,BC,DE,HL ARE CHANGED, ALL OTHER REGS. ARE UNCHANGED. ; CVMSG: PUSH HL EX DE,HL XOR A SBC HL,DE LD DE,VMSG ADD HL,DE LD (VDRVP+RAMDATY),HL ; POP HL LDIR RET ; DPBASE EQU $ DPE0: DW XLT1K DW 0 DW 0 DW 0 DW DIRBUF DW DPB0 DW CSV0 DW ALV0 ; DPE1: DW XLT1K DW 0 DW 0 DW 0 DW DIRBUF DW DPB1 DW CSTX DB 0 PHYHD EQU $-RAMDATX DB 0 IOADD EQU $-RAMDATX DW 0 SECSIZ EQU $-RAMDATX DW 0 STADD EQU $-RAMDATX DW 0 DW 0 DW 0 DB 0 CMDCNT EQU $-RAMDATX DB 9 CMDBUF EQU $-RAMDATX DW 0 DW 0 DW 0 DW 0 DB 0 ; DATXLN EQU $-RAMDATX ; SER1BAUD: DB DFLT1 ;index in Baud rate table for SER1 default baud rate SER2BAUD: DB DFLT2 ;index in Baud rate table for SER2 default baud rate DS 2,0ffh ;reserved for future expansion ; VNUMB: DB 3 ; # OF PHYSICAL DRIVES - 1 TLEV: DB 0 ; TERMINAL LEVEL ; ; RAMDATY: SEKDSK EQU $-RAMDATY DS 1 SEKTRK EQU $-RAMDATY DS 1 SEKSEC EQU $-RAMDATY DS 1 ; SEKHST EQU $-RAMDATY DS 1 ; UNACNT EQU $-RAMDATY DS 1 UNADSK EQU $-RAMDATY DS 1 UNATRK EQU $-RAMDATY DS 1 UNASEC EQU $-RAMDATY DS 1 UNAMAX EQU $-RAMDATY DS 1 SECTRK EQU $-RAMDATY DS 1 ; WRTYPE EQU $-RAMDATY DS 1 DFLAG EQU $-RAMDATY DB 10H TRSEC EQU $-RAMDATY DS 1 ; VMSGP EQU $-RAMDATY DW VMSG VDRVP EQU $-RAMDATY DW VDRV ; CDSK EQU $-RAMDATY DB 0FFH  increments of 4 ms. ; ; Byte 3 Head settle time (after seek) in increments ; of 4 ms. ; ; Byte 4-5 The two parameter bytes for the FDC specify ; command: Byte 4 = SRT/HUT ; Byte 5 = HLT/ND ; ND must be 1. ; ; Byte 6 EOT byte for FDC read or write commands. ; ; Byte 7 GPL byte for FDC read or write commands. ; ; Byte 8 Current track. ; MTAB: MTOFF EQU $-RAMDATY DB 1 DB 0D8H DB 88 DB 5 DB 6FH DB 3 DB 5 DB 28 DB 0FFH ; DB 2 DB 59H DB 88 DB 5 DB 6FH DB 3 DB 5 DB 28 DB 0FFH ; DB 4 DB 5AH DB 88 DB 5 DB 6FH DB 3 DB 5 DB 28 DB 0FFH ; DB 4 DB 5BH DB 88 DB 5 DB 6FH DB 3 DB 5 DB 28 DB 0FFH ; DB 1 DB 0D8H DB 88 DB 5 DB 6FH DB 3 DB 5 DB 28 DB 0FFH ; DIRBUF: DS 128 ; ALV0: DS 25 CSV0: DS 48 ALV1: DS 25 CSV1: DS 48 ALV2: DS 25 CSV2: DS 48 ALV3: DS 25 CSV3: DS 48 ALV4: DS 25 CSV4: DS 48 ; VMSG B cr,lf,'Your left drive is being re-assigned as drive ' VDRV: DB 'A.',cr,lf,'Exchange diXLT'S DS (BIOS+0A00H-$-55),0 ; DB 0FDH ;IMS BUFFER HEADER DW 0 ; DS 52,0 ;STACK SPACE ; DSKBUF EQU $ STACK EQU $ ; SIGNON: DB 0DH,0AH,'Micro-Decision -- 64K CP/M Vers. 2.2 -- Rev. ' DB ((REV AND 0F0H) SHR 4)+ASC0,'.',(REV AND 0FH)+ASC0 DB CR,LF DB "Copyright '76,'77,'78,'79,'80 Digital Research, Inc." DB CR,LF DB 'Copyright 1982,1983 Morrow Designs, Inc.' DB CR,LF,LF DB '************** Single Sided System **************' DB CR,LF,0 ; ; BOOT: LD SP,STACK LD IY,RAMDATY CALL INITCTC ;initialize baud rates LD DE,SIGNON OUT (ROMCTL),A ;TURN ON ROM CALL MSGRM IN A,(ROMCTL) ;TURN OFF ROM ; XOR A LD (3),A LD (4),A ; LD HL,CPM ; JP GOCPM ; END 8,19,20,21,22,23,24 ; DB 0FEH ; CONSOLE XLT TABLE DW CLEN esctbl: DB 0FFH ctrltbl:DB 0FFH escvect:DW 0 ctvect: DW 0 ; ; TRANSLATION STRINGS FOR THE TERMINAL GO HERE ; CLEN EQU $-ESCTBL ; DB 0FFH ;EOT DW BIOS+0A00H-$-57 ;SPACE FOR MORE PDSK EQU $-RAMDATY DB 0 VDSK EQU $-RAMDATY DB 0 ; DMAADR EQU $-RAMDATY DS 2 OUTP EQU $-RAMDATY DW CNOUT INP EQU $-RAMDATY DW CNIN ; ; MTAB contains one 9 byte entry for each logical drive. ; The bytes of each entry are defined as follows: ; ; Byte 0 DSKDEF0: ; Bit 0-2 Motor control bit ; Bit 3-4 Double sided mode: ; 00=Even tracks on side 0, ; Odd tracks on side 1. ; 01=1st 40 (or 80) tracks ; on side 0, remaining ; tracks on side 1. ; 10=Both sides are treated ; as a single track with ; twice as many sectors. ; Bit 5 Double sided drive if = 1. ; Bit 6 Unused. ; Bit 7 Foreign drive format if = 1. ; ; Byte 1 DSKDEF1: ; Bit 0-1 Physical drive address. ; Bit 2 Double sided media if = 1. ; Bit 3-4 Sector size: ; 00=128 ; 01=256 ; 10=512 ; 11=1024. ; Bit 5 Tracks: 0=40; 1=80. ; Bit 6 Density: 0=single; 1=double. ; Bit 7 Virtual drive: 1=virtual. ; ; Byte 2 Motor on wait time inskettes and press [RETURN]',0 ; LSTFLG: DB 0FFH ; PRINTER READY FLAG ; ; dcastrt b 1bh,3dh,0ffh dc prefi string ds 3,0ffh ; dcamid: ds 6,0ffh ; dca seperator ; dcaend: ds 6,0ffh ; dca terminator string ; esc_lvl b 0 ;indicate es sequenc level offset1: db 0 ;first character offset offset2: db 0 ;second character offset order: db 1 ;Bit 0 = 0 --> row, then column, ; = 1 --> column, then row ;Bit 1 = 0 --> binary cursor adresses ; 1 --> ascii cursor addresses first: db 0 ; temporary storage of first second: db 0 ; temporary storage of second ; XLTAB: DB 0 DW 40 XLT1K: DB 1,2,3,4,5,6,7,8 DB 25,26,27,28,29,30,31,32 DB 9,10,11,12,13,14,15,16 DB 33,34,35,36,37,38,39,40 DB 17,18,19,20,21,22,23,24 ; DB 0FEH ; CONSOLE XLT TABLE DW CLEN esctbl: DB 0FFH ctrltbl:DB 0FFH escvect:DW 0 ctvect: DW 0 ; ; TRANSLATION STRINGS FOR THE TERMINAL GO HERE ; CLEN EQU $-ESCTBL ; DB 0FFH ;EOT DW BIOS+0A00H-$-57 ;SPACE FOR MORE  !"#$%&'