IMD 1.15: 16/05/2007 8:37:30 DOUBLE SIDED RELEASE DISK 5 OF 7 10/23/84 DAB COPYSYS SOURCE & GENERATION DISK V1.2 SSDD @1:#2#:Qˏ2Q!BA>@@2QO !IA>!PA>@@:QO !WA!^A>@@K !:M2U#<  :QO(>!T=  !T . :NO  x :OO  :PO  e DJGZ!ANy(#  BIOS boot error reading disk. System reset required. DTTReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReserved1EN ͍E %E͍ED͍EDʢDC͏D͕D!CE~# 4D͕D C͍E:Eg:EsD:E_Dg:EsD!]C~$oD#~B̩D1EɷW|g ͏D͕D%zD͍ED͍ED ͍EvCPM3 SYS CPMLDR error: failed to open CPM3.SYS $ CPMLDR error: failed to read CPM3.SYS $ CP/M V3.0 Loader Copyright (C) 1982, Digital Research $021182"LyڥE2L2L:L2L{2L!" G"L9"@F1F!NLy2EK!EEdڛJ_^#V*LFFFFFFFFFFFFFLLLFFFF;LFFFFALGLFFFFFFFFFFFFFFFFFFFFFFF:FžF Ny!L4 5~yµF5 6y ’F ͒F:LF!L OͻFFMDF2 G>F BDOS ERR: $Select$Perm.$FFF GFFGFv{_zW{_zW )8G# ?G w#JGJN|^#V###"L##"L######"L!L IG*L!LIG*L|!L6ʕG67N*Lw#w*Lw#w#w!L^#V#FͪG'NOGG*L&I!Ls#r#p*LN#F*L^#V#F*L:LO}|yH*L%G+G*L.G}|yH#H*L%G*LDM"LN*Ls#r*Ls#r#pyoxgkHDM*L0NMD"L!N*LMD$N:LO&I!LN:L yHG>O:L ʐHÇH*L͒H :LʨHn` ~#forH2LO͚H"L}:LO*L7G"L2L"L:LO:LG2L!Lw*L *LH!H~2L~2LH:L2LH:Lw:Lw |g}o'I )4I:LO!3Iyoxg:LO&I}*L:Lo$H~w{ozg ^#VG:LʏI>LÛI͡I"LGͳG*LçI*LrI"L!L~#O&IE:LIHN/*L"Ly2LʹI͗GͻIͫIʛJ*LXI:LO~JJyʔJx ʍJ ʂJJJÍJNIJJ# hJ2 GG>GF:JH~XI*L IGIOw!JxJ>Fwx2L2L~:L:L6:LJw2LH~O I!K>w:JͨJH2LF4IO.K5FJͿJKH:L!LSKFJ: GFͮHFH:LL͛IGͳGI:L< G=!LwW*LMI_SG G-*LMD:I"L:L2Lɯ2LK>G=O*L~~w#~2L~wcIH~K~p2L!"L>2L*L~=2LK~2L͛KoK>*Lw!"L2L=2L!"LÛI͛KoK͢K͢J'LͫIH~<7Lw@ͩK7K:LF"LÛI:L~L:L2L:L~L*L6:LpLw#:LwH:Lw*@F* G}D>LI$*LL*LTM:L_2L{2L"LrI"L[MM?G,MdM>lM[MIG6:L<!=6M*LJM"L*LKN:LG/O*LL*LG=GdM##LIGQQ&Q+QQQQ+QÐPPÓPØPÆPPP$QéP$Q&Q$QîNQòNàPÞPPÁPYPÌPPP\PíNíNOPatchPatchPatchPatchPatchPatchPatchPatchPatch!0Q!NNORRRRORRRRORP  (? R-?&RR ? 8R$?AR?AR?AR?AR?AR?:P s12P*P| :PPBP"VP:P{![RûP!RûP ͌P*N9Qq#p#HQq#pɿ \P\P\PCRT SWOsborne Executive CP/M Plus BIOS V1.3 Copyright gG 1983 Osborne Computer Corporation Copyright gG 1984 Future Systems, 828 Nob Hill Avenue, Pinole, CA 94564 B            y2Pi&N) ~#fo"P+~2Q+~+ng{*P~#foR|:Q2P`(Q !2Q2P!O:Q#~ (<(#w#w s#r~#+2P! ~#fo+++~2P+~2QZR]:QGO(!P:P(82P!Qˎ:P+S:P2P*P"P!P4#5ES:PES#:PGS6!PJ2Q:P2M*P"K:PG&Pѷ(` :P !Q:Q Q !P6=ALOADER y; !91""|0!~ʞz=_: _* ""*og*%|}D S#N#F:ʒ#4ʝ^#V{‚:¿*.~w*DM!&_*.& >k s#rr+6.""1*D`.45. F.~. ^#Vx>`. s#rz 6#N#fi%$g1:=<@v_}v=p{_3;{<g"T=X3*j ~P#~R#~L{gbk#N#Fk$&Zcx {~#o}o1!;!"Ï:= w*wWx ~#&*.~s*"ѷ\ Cannot load Program 221282 COPYR '82 DRI <bHA$@DH   A@!" $$@1-! j 1".~2.~2 :Xck*kͮ  b < .~=>$.w.6#w.6#w.61.~  .~~w@.p T~º>+~.~~! yͮ Ë.~~w2g !PROFILE.S !+2 !  +~d {   O! w+w+: =w! 5 c ʋ  :p  m>> ͧ  N Ĩ –.~+w.~2  9 : ! ~##~ !7 : !Կ : x*l " !ZXچ! 6  zz: 6 : %2p  ͆ : =̀ 2r  DIR TYPE ERASE RENAME DIRSYS USER u"Q}:\=p:r Aæ R ÂN ͙ʸ} !M 545 x ]  ̵ 6 : oG! ~怹>2M  xf>:ͦ ͤ ͍ ͤ f ¹2 lf   ͫR  L͞L I *  *  A }_Yl !ͮ ͒6 \&đ %* "l ͍  ûȷ45: w ? A I N   SUBMIT COM ! ͮ ! 6 #"l  !cͿ  O!:r :ͦ ͍ !~B I !pͰ ^#VCOM SUB PRL y!cͰ  î !" * %.2P#ͮ !g 4*l +"l ͷ 2 "Qx2Sl "Tx2V!q ~ :p ͆ .ڶ2* og$2| .w#w#w#w.~ .w#w~?w; ; ! ~#49 w#~$ A  < > _I  ! 6 ! ~#Ͱ 6 m   _  ! 6=  { *.pѯ:r x , \<=!Ͱ =ɯ2 \s 2 ! D ;! : .44 #4"l ~[* 2 a7 {7 w!Y #! *l "l " ~ U #D ]T!̷ 6*%.w#w!} 6 r 6 #w.6#6 #t#6.wo*.s#r.rͧ ̧ m . ^#V45+ w#w.f.5\A "l " l |F# !( | !( : x. +"l ! ͮ   ͮ ~!G8 * ~;#1 կA *l ~:g X #I ѯ*l  *l ~0څ :҅ q X x<Ü AX QX X ~@#~:k #^ *jT~# ® wy#ù ! 4 : !Ͱ ~@*h~ yw y/w*hw*h~I E> ͦ > æ % 0  < : ~ȹͦ #* A !g ~6*  * >? A *l " ~0: :: q "l x~0 xG#Gs : &͘ ͤ &ͦ %˜ >  Ʌo$>?· !  > # ͮ x> # ~ Enter User #: $No File$ required$ERASE $ (Y/N)? $ Press RETURN to Continue $ (User 0)$NON-SYSTEM FILE(S) EXIST$: $$$ SUBBCRT CEN MODEM PRNTR IEEE   edReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedA????<<<?<<<<<<<<<<<<<<<<<~~~~<<<<<<<PO(_?:|L+     { }~ `  '[12345678QWERTYUIASDFGHJKZXCVBNM,0 .PO9-/;\L=     { }{ ` 0123456789   <20<ReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedReservedARAMS10 AS ACT COt COPYSYS BAK`abcdCOPYSYS BAKefghijklmnyzCOPYSYS HEXr !-./0123456@HEXCOM O >?COPYSYS COM)ABCDECOPYSYS BAK*SYSS1 ASFGHIJKLMNOPQRSTUSYSS1 ASBVWXYZ[\]^COPYSYS ASM"#$%&'()*+,789:;COPYSYS ASM<=_opqrstuvwx{|}COPYSYS ASM*~COPYSYS ASMCOPYSYS BAKCOPYSYS BAKGENCOPYSBAKGENCOPYSDOC ;RAMS10.ASM TITLE 'Monitor RAM Storage.' ; Used to assemble ROM resident and CBIOS ORG MRAM ; Disk operation temps and control DMABANK DS 1 ;Bank for read/write disk DMADR DS 2 ;Address for read/write disk ; Note order of xxxSEC,xxxTRK,xxxDSK must be maintained ; along with length (1,2,1). SAVSEC DS 1 ;last sector requested SAVTRK DS 2 ;last track requested SDISK DS 1 ;selected disk drive (0,1) SAVTYP DS 1 ;SELECTED TYPE (sector size) IE_ADR: DS 1 CURPOS: DS 2 ;Current cursor position ; VARIABLES FOR HIGH RAM ROUTINES TEMSAV DS 1 ;Used by jump bank routine SRCBANK DS 1 ;Source bank for block move DESTBANK DS 1 ;Destination bank for block move ;JMPSPOT and JMPADDR must stay next to each other JMPSPOT DS 1 ;To be filled in with a JMP instruction by the ROM JMPADDR DS 2 ;Address to jump to for BANKJMP and BANKCALL JMPBANK DS 1 ;Bank to jump to for BANKJMP and BANKCALL EMRAM = * ; INTERRUPT VARIABLES USR_BNK DS 1 ;User's bank on interrupt bank switch DS 2 I_POL_BANK: DS 1 I_POL_ADR: DS 2 USR_STK: DS 2 ;save current stk ptr ; Interrupt stack DS 30*2 ISTK: DS 0 ; ROM and BIOS stack DS 30*2 BIOSTK: ROMSTK: DS 0 HIBUFF: DS 100H f.2z1" 7oz2# 3Gz3$H4oz4# 4oz5$Q4oz6#03oz75 7oz83$4oz92&5oz:2,5os0 Ze.2.0.2jk)( s0s3l XON/XOFF ETX/ACK CENTRONICS IEEE s7= 0READ ERROR=!0Press ESC keys7= 0WRITE ERROR=!0Press ESC keys7= 0NOT AN EXECUTIVE SYSTEM DISKETTE=!0You can only setup diskettes with Executive system tracks.="0Press ESC keys7= 0INVALID VERSION NUMBER=!0Destination version is not up to date for this version of setup="0Press ESC keys1=*%ERROR: EXECUTIVE SETUP=+%This setup program is designed for the Osborne Executive=,%Your machine is not a valid Executive.=-%Please use the setup program designed for your machine=/%Press ESC keys7= 0INVALID VERSION NUMBER=!0Source is not up tACT I 808x Copyright SORCIM Corp. 1981 S/N- 007,Version 3.5EEV SorcALL ASMFilenameHEXFilenamePRNτ?1;͟4199!42 ͣ'6 #6 #6͎ 4!:f'*:;'*:;'F<*99>T29>2a$o*9|LH&*9*9*9(%b;'*9*9(%! ͩ"e:U&*:;'!HHF*|ʧ&!"F*e:|:9!B6 29!l$ Last error occurred on Page 123 Total LOST references were !?="9*9"929go"9*9&"9>s2K2:2:͎ 2929292929292929292Q:go"9!e:"^:"9*9":"9:92:5:9=29>2929>T29> 2K*9196:94H*:"9*9"9*9X!.X:9͓*9 "9:9:9*9}eG:9=__ͻ$#D> 24d"`:~G&vG!.#%fh"c:2e:*9"nx(:9¶ x= :9:9x(=:c:G 6)!K="9! B629>22>22J! :9ĭ!A$:9ĭFUnterminated IF nest. IUnterminated MACRO definition. !.~O#%~wy<#%J*9*9 ~w# œ~?ʜp ^#V#N#F r+s 9'n!ͭ~24#W$OToo many PROCs in program. *9?9' "9*9 "9yx  !e: f':d:_ :9¶!"f:":>(=*9"n!%4:c:#%^#V>SE>E24\*^:}!e:"^:2d::9 e::d: !9>wd:G::ʁ!4 W † :9 ͓!9~wÁn>-24>O>Y>S>E>A24*n|c~c=ͅ"::s2:ͨ :9ʽ:9>Y:9>F24292929͗!T.:9>P?*9~24 ͒ | >P24 R::9pͬ% ͬ/ƒͺ:9Ҿp %ҭ!f'!9~G?2:>N*nͻ,#!94:9ʤ>Ov ͼ ðv":"9:s2:2:> 2:Dv"9:s2:G::’*:9'> ʔ>#2:!4wðv:rG:e:N:9*:°>L24ð!e:~"^:*92~c!e:~"^:2*92ͬc!e:"^:v | } >W24>2[:\> ͒"\:, ::*^:w\>S24\*9e:':9 b *9?9'>O "9 *n~*!99ʽ f'ͬ-™ ͬ+ ͭ>UN!9{_~wͬ,ʋ N'*n#~T L@ C D F G M R͒:9@S ͒U͍f:9@͍^!9F6:96 I :9@I ͍!9~w*9~>S## C>E>S~29*9#N# f'! f'! W$Unknown CPU: '' ͓!46'#*9ͩ Of' ;' !) ͍'!4>!O$͓' 2929v}29| :9ͤ=D !94:e:- *9?>L͇ "9< ####>*9##"9'!:͡':92:*9:*9 f'"9x #"95%*9~w##s#r*9##h'%0+  3 Ƃ~ G >@w!:͆>w :9ē*9#"9 *c3 ~ ʪ(~w##^#V*9ʠ w#Ò ͤO:9= y*9#%N#Fx w# Ò *9"9|~ : # !"96!"9*9"9!9"9*9;'*9!9f'*9zV  6 s#r#Z ,;  >P ) s#r#"9x29O:9Gʃ ˆ =29} :9¶29>F:9ʴ ¶} :e:b !94:9¶vz°n:9ē:929*9"9*:":Y*9"9*9"9>L >S24!::9w:9 {: :9Ox~ :92*:*:":":͙ x (::2:>*9G:92:":!"9*9|? *n~}:} 1"9F::O@°yw*:#::w#s#rx ʴx@´>w:9x>D :9>:9:[:O::G!d:yO4Q Jx2::[:*\: lMW͛%O::_G͆%!:w{=@~6*^:w#"^:!d:4 ::W{2:[: !46^#þ':9M*9##(%"f:!46=##þ' ͩʝV=ʝ#^=ʝ>V24*^:s#r+y *^:>A+w¬ͩOGx!46V*n+6:d:2d:*^::9y#% Aw# "^:*n+~#:9(=*9"n*94;'::;>~;7ʧ*7ʧ 7ʧ:9¡ ڧ'.!_ʚ;Œ:9¯> #„òaژ{Ҙ #V#Ҟ#:9ʲ*9"9 ʵ>!;?~   7ȷy#:9ʲ*9ͤõ#N f'V>#"'#~'"# x)+pV9 B#0+> !"9"9"9!9!;~ p ~# f}| fO!~ʌ#7y,+-*/()><=^&[] : \(%*9*99'+~ y¹*99'"929*9.:9g"9"9:9 *9*99' "9>a*<<4:9W~#29  F  Rf> z > : "<<> `i"9!429z29 >=9'ҁͪ> !\#!7\\\ END Statement Missing !><\#6y  !W$ACT stopped by user. *99'"9"9\ f'ͻ#$!Ve%!VC f'>2a$!C͂$f$!>="<<6 Pass 1 - Reading D:FILENAME.EXT ;}; ͒:r >Uá*9"n|’7*nͩڤ?>E247go!"t."r!9"jz>Sͼ2l K*h};9'+~ffbMb*h};9' *f;9';A:@2s"tb*h9'+~H"h> 2l!z#%9'F#N   de~# ʼ+"n>2l!;"f!};"h6>2q>E*j24!"tt>2s7ͬ0 :Q:zzB~G#4V#^6Z6T]#%>2rxß*n+ͭ"n#~G:l x+~!9Oʃ!:Pʃ!9Lʃ>2r^#V#F>ßG> x,\]/*$+^^^&()=<> <= >= < > ~-ANDDEFEQGT GE HIGHLE LOWLT MODNE NOTORREVSHLSHRXOR+%>N>2r>#ß:px2p%x2pU+ͭڒ{ڒ#~"n*n+:s*n2s"n,> *n|ͻ#"n#~ ʺ*n+~ȷ+"n*f;9'>O+~2r+~+^+V"f:r2r2s=#%~+fo>>2s&:s*f<;9'>Sr#s#w#:rw#"fG*h;9'>Sp#"h>2q*h};9'+"h~!#%9nu d)0<D {ozg) {oz {oz#!)#!)##?##? 9'l3>2q}l:rG>2rx x> 24 ) ) 5%)5%) ͭ%) E=%) ͩ)z|5%ڻ PY ͩ)):*9 f':9="9$"9 !W$ A Memory OVERFLOW Stopped ACT!/q#p# *9(%:9"9:~%"n::::`:97͆`i?ځ'ځ!d3r+s+7!`3Fx!.H!d0R!2Ͱ2b:!?GN#xy_y_ѯ°#7# y÷y?>E2:2:1>w##^#VO:9#y2r>U724*9*98*9*9:9'b! =# cSh= :|:9 ^= :~ w “9'ʺ# µ¥þÐ7!6> oD# 9'7ȷ0 :?[$b#b.b~J%# ~#,4J%~#o$4f'HO$:9@Õ!9~w*9z^:4 |.> 24.5:9 :4!?怰G:9W:9O@:9ʺyzz>@GzGG&z>+24*94~# !4> #6 #6#2*9#"9!4O$H> 245!4:G~=> w# 56 #6:9@!4\!94:9l$*9:9Gʅw#xl͜lx29"9*9:9q<•!z8$Ҹ:9@29!W$G29!"9List file write error. *9}J%: !f'*&*9"2<29*9#"9&!\! \4>2$:9>B>20:0294:OJ%>$!4".%~*.>  ʄ>sw#UҚDښڛnpf'*99'ڼA6m#6a#6c#6 ###".6:9o:9=29bH:9!0*.6 #C*9!?~: ~ ~w 9'*9DM !?~Ex1}1Fd] d#KT]f 6 ^#VogʉNs#FrYP+y>!4".29|^#V#~/#oy&&".:9=29•5>Ë:9H#^*.&O:9:9:9:::?:92@/7N#F:@+w:9+w+p+qr+s*9#"9~#foþ' no ERRORs, 1234 Labels, h bytes not used. Program LWA = h. *Error page 999SYMBOL TABLE *Error page 999 SORCIM 808x Assembler ver 3.5E mm/dd/yy hh:mm Page 999 ~':9*:9'":Oi`) ))6 2:2:͎ *:"9p : f'::p : f'*:^ ͙ ~ *: ^ "::9:9w"*O::Q:#%9'!!*:"O:G_ :9:9<"#"" >!y2Q:&!!y2Q::Q: Q:G!!:"""#"z P!:N:'6 #6  :r!*O::Q:#%"O:2Q:2N:!):*@5w#}B!|6!!!B5u!"@5:9:9·"!!>12':*:"O: (!*@5B5!!B5V$!:929!!W$Hex file write error.  9'!p#9' "O:N:2N:yW :Q:O!):#%:9:9—"*O:x#%"O:!:~#f" #Oog5#o"_j#I"::O*O:9'Š":M:y2M:> "O:">\#!]#> *6"> *6"::O>*:":Y:"X:r!*@5B5!!"\#5#>>?:Z:y2Z:>\#yp ~ ###t#^#r# &#y?H#"N#_Pt#r#\r#@_t#\j#t#zK͛%O:Y:_G͆%!X:w{=#r!2X::Y:W{2Y:bzWu# Y w# ##7! wD$ѷ$ #7D$ѷ$ $D$7:k$`$l$f$>2k$>b$:k$O$2a$2k$O ͻ$~# ¡$Ù$ ͻ$x“$> _xUү$ͻ$Ä$|ͻ$ ͻ$ ~Oʹ#!$`$$ ?? OPEN error - l$!;6#e%!;l$:9%V:9͍zɅo$MDy_xW{z/W{/_xzW{_=%>  L%~ J%J%# S% As%@O:q#p#f'>.f'xy%%ɷ”%!%#%~?BK!xʾ% ô%BJ~0%:%A%[% #%+FyR&:p &x &Bʯ&N&Ql&Hʆ& :pBʯ&Ql&Hʆ&yG&A&;&5&'V&V&dV& V&V&7N&~0Q& Q&# =e&~0R&R&_ #M&)))l&~0R&:&AR&GR&_# M&))))Æ&~0R&R&)o# ²&M&&'&'&'&'}0>02'>0]T< &=kbG:''> x>2'0~0~0#y'z{x7# A'9'h' +~ x['x~# h'x~aڅ'{҅'# u'~#Í'7#Ö'zq#ã'O:'=@I±' ®'V|'}'Ɛ'@'ɯ2(#~:+:\'~@8(##(ͬ#<~>:7:(.$(~.#$(y^(!S:( ^(:(7x7~i(#.^(*V(>?a(~# :(G>  a(x!8(|8(;8(=8(:8(@ʖ(#ʖ(*ʖ(?›(2(a({ w!d:6͹-2e:>I24\..(>.c3]-Cͥ-M..c-3͓-c>d.cle3͓-cm( (me3͓-(-3͓-͒"f:cme3͓-g-à,..͒Xx.c>I*͹-..e3M-M.>!.c3-ڰ)ͥ-*-3>)O- M."-.c3-ڰ)͹-3-- M.>!.cs-e3l- *n+~)͹-M.cs-3@-C*n"9e3\-)ͥ-M..cs-͹-g-3-*ͥ-3-(s-e3\-)ͥ-M..J,3-j*:-ʉ**3 *--"-ڰ*ͥ-.cs-3 -*3-a* \s-s-3-ڃ*:-ƒ*3-a*Ã*s-s-3-ڃ*3-ڃ*:-ƒ*a*s-s-3@-ڃ*͹-..c>H2+3@-++3 *n-+͹-M.cs-~[.+"nÝ,s-s-3-M+3-M+͹-(s-3-^+,s-3)-ڀ+͹-M.>!.͒"g:cs-e3:+O-ڧ+M.e3-Cͥ-.c:+>s-͒"f:́.Ó+H͹->!.c3-+:- ͹-(s-+>d.,Ce3\-Cͥ-M.>!..c3=-*,ͥ-M.͒"f:G,s-e3I-Cͥ-M.͒"f:́..>c3=-l,ͥ-M..cs-e3]-Cͥ-M..c3-ښ,ͥ-.cs-͹-͒"f:c3@-,3-,͹-M.>!.cs-3-,͹-M.>!.3@-Ccs-3 -A-3-Cͥ-.cs-e3m-;-M.e3l-;-͹-M.cs-3->:->3%->͹-M.>.8,͒"f:́.c!b:55>*9"n*`:##"`:~2d:#~2e:-CM.ͥ-.-ʹ-!d:4-4:9 *nͭ"ny_b#V"-|-͒x.}2-]Cͬ,=-@!.!g:Fw#p*f:"g:*d:o"e::9>C >$24:9>C >#:.*-}o|-^.!e:w͒د†.z†.[.}|†.|<:4 >V24ASMHEX080808085Z80 =+CADD ADICADCJACIANA#ANDANIASEG.ASSERT6BIT@CALLCBITCCCLCCMA/CMC?#CMPCMCNZCNCCPECPOCPDRCPDCPIRCPI#CPICPU3CPCSEG.CZDAA'DAD DA&DBE%DB%DCE%DCRDCX DC%@#DEC DIDJNZDSEG.DS!DW&ECHO5EIEJECT:ELSE=ENDM<endm<ENDIF=END(ENTRY,EQU+ERR;EXT-EXXBEXHLTvIDENT0IF=IM0FIM1VIM2^#INCINDRINDINIRINIINRINXIN,C@IN#JMPJNZJMJCJNCJPEJPOJPJZJRC8JRNC0JRNZ JRZ(JRLDAX LDA:LDDRLDDLDIRLDI#LDKrLD :*KFLHLD*LINK2LIST8"LKLOC#LXIMACRO5MVISMOVWG@(MSG9NEGDNOPORG"ORAORI"OROTDROTIROT,CAOUTDOUTIOUTPAGE:PCHLPOPPROC$PUSHRALRARRCREPT5RETIMRETNERETRIM RLC#RLCRLDo"RLRMRNCRNZRPERPORPRRC#RRCRRDgRRRSTRZSBBCSBCBSBITSBISET+@SHLD"SIM0SLA SPACE7SPHLSRA(SRL8STAXSTA2STC7sSTO2"Cp63SUBSUITITLE1USE/VFD)XCHG#XORXRAXRIXTHL'*M%6[HL]6[IX[IYB C D E H $L -AA?IR AFA6PSWA6SP!6IX$IYdBC B DE D HL$H$AFA6SP!6IX$IYdBC DE HL$[SP]!6[IX]$[IY]d[BC] [DE] [HL]$(((() )%)-))0)3)+G)(((+++*B),U,(,`))*!*8*,6Kl#([ uX" F a T E w  2ͮ8>2k$!"R:ͬ#<@27a5:2$:29͈8*9!\ f'"9"9:94!Vͪ5:95!zͪ5!Af'!~6!l$2!T l$!.7:9f$6!=5$h'*ABS *CODE *DATA !"5!~ 8#O 65͹8!?="9l9 8}6:929l96ͭ8^#VPY##$!\ ?'\!5$ ?? Hex or Prn file name same as Input = 5@R6H=06H=6LO7L=06L=CON:6L=LP:6L=6L6O7PS(7SLA7S=_7S\7R=07R=S7R=F7R7!.7\'8\V!.7z! 77:929Ô5!.V7Ô5>29!RE".>L2.P!:͡'Ô5Í5:9ï6>`2i$:9ï6! 7z7:9ï6PRN;729Ô5;7"9Ô5:;7d!x8872Ô5P;72`i+~=7#%8{7':!d8$YPf'7Sf'!8l$!288!R88!d88Command input errorNO source file specified, ABORTMal-formed numberIll-formed filenamePS > 99SL < 60/!'> :!'!8f' Page *%"9"9OD9T9 .9}|:k99~ 9 9, 9; 9|.9 .9.9a 9{ 9 w#86#8:k9(9~ .9.9#96#86go~<9ѯx~ O9 S9#D9~'d9"d92k96#2k95~#ʇ9<+w#_^#Vѯ7TTTTTTTTTTTTTTTTT=99hhhh?=???99?=?9 :9999990099 ?\:e:`: prompt/command response JMP X30D2 ; end  ',* page ; Assembly Constants and definitions. LINK RAMS10.ASM ;RAM memory locations and constants 2.21 ; ; Conditional assembly equates: ; ; ; Generation toggles: ; BETA_TEST = true ; ; ROM terminal emulation supported: ; IF BETA_TEST TVI950 = false ENDIF IF NOT BETA_TEST TVI950 = true ENDIF TVI912 = not TVI950 ; ; ROM entry points: ; SEN_RTN = 160h ;SENDEN RD_RTN = 15Ah ;Read WRT_RTN = 15Dh ;Write DOUBTYP = 0CH ;DOUBLE DENSITY OSBORNE Sstorage for address of last command description displayed: ; O_SUB_MN: DW 0 PAGE F_CMD_DESC: ; Display general direction message and force re-display of command ; description for currently selected command. ; ; Command description IS re-displayed even if it has already been ; displayed. ; ; This routine is called after DO_COMMAND processes the current command. ; DO_COMMAND erases the command description and general directions and ; they must be restored even though the description has already been ; displayed. ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; ; PROC LK HL,DIR_MSG ;Display general (arrow key) directions CALL OUT_STRING LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A rAelative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return PAGE DO_COMMAND: ; Process the currently selected command on the currently selected ; menu. ; ; Clears current command description but re-displays it only if ; menu has NOT changed. ; ; ENTRY: ; Y_COORD = line # of current command. ; COM_TABLE = address of table of pointers to command routine for ; current menu. ; ; EXIT: ; None. ; PROC LK HL,:CLR_W_5 ;Clear command description for current CALL OUT_STRING ;command. LD A,Y_COORD ;Load line # of current command. SUB 32 ;Make relative - 0 ADD A ;Double to index into command ptr table MOV L,A LK H,0 LD DE,COM_TABLE ;Index into command table ADD HL,DE LD E,[HL] ;Load ptr to command routine INC HL LD D,[HL] EX DE,HL ;Put ptr in HL LK DE,:DO_RET ;Load address of return point PUSH DE ;and save as return address JMP [HL] ;Jump to command routine ; :DO_RET: ;Return point from command routine. LD DE,MAIN ;Has main menu changed? LD HL,OLD_MN STC CMC SBC HL,DE RNZ ;Yes, command descr must have changed, ;so return to driver without ;re-displaying it. CALL F_CMD_DESC ;Force re-display of command ;description and general directions CALL SET_CURSOR ;and reposition cursor at current ;choice RET ; ; String used to clear window 5: ; :CLR_W_5: DB ESC,'s5','Z'-40h,0 PAGE HI_CURR: ; Highlight (in reverse video) current command string on screen. ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; Assumes ATT_OFS-th char of command string is attribute byte of attribute ; definition escape sequence (ESC-G-X) ; ; EXIT: ; None. ; PROC IF TVI912 :ATT_OFS = 3 ;Offset in command string to attribute ;byte :INV_ON = 'j' ;Reverse video on attribute char :INV_OFF = 'k' ;Reverse video off attribute char ENDIF IF TVI950 :ATT_OFS = 4 ;Offset in command string to attribute ;byte :INV_ON = '4' ;Reverse video on attribute char :INV_OFF = '0' ;Reverse video off attribute char ENDIF PUSH AF ;Save line # ADI 5 ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save addr LK DE,:ATT_OFS ;Index into cmd line string to attribute ADD HL,DE ;byte STO :INV_ON,[HL] ;Set attribute byte to reverse video LK HL,W_STR ;Set window for current line CALL OUT_STRING ; POP HL ;Restore address of cmd string PUSH HL ;Save it CALL OUT_STRING ;Display cmd string in reverse video POP HL ;restore cmd string addr LK DE,:ATT_OFS ;Index back to attribute byte ADD HL,DE ; STO :INV_OFF,[HL] ;Set it to normal RET ;and return PAGE UN_HI_CR: ; Remove highlighting from command string on screen ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; ; EXIT: ; None. ; PUSH AF ;Save line # ADI 5 ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save it LK HL,W_STR ;Define window for current line CALL OUT_STRING ;Redisplay cmd string in normal mode POP HL ;Restore addr of cmd str CALL OUT_STRING ;Redisplay cmd string in normal mode RET ;and return PAGE ;------------------------------------------------------------------------------ ; Local storage for driver data structures follows. ; ; MENU_TABLE is a pointer to the table of pointers to command ; descriptions for each command in the current menu. ; MENU_TABLE: DW 0 ; ; COM_TABLE is a pointer to a table of pointers to command routines ; for each command in the current menu. ; COM_TABLE: DW 0 ; ; MAIN is a pointer to the current menu. ; MAIN: DW 0 PAGE EXIT: ; Program exit point. Program rAeturns to CP/M from here: ; Sends termination string to console: sets window 0, clears screen ; and enables fn. key xlate. ; ; ENTRY: ; None. ; ; EXIT: ; None. ; LK DE,GOOD_BYE ;Send termination string to ;console. LK C,PR_STR_FN CALL BDOS JMP WBOOTE ;and warm start. ; GOOD_BYE: DB ESC,'s','0','Z'-040h ; ; For TVI 912 emulation, include string to enable fn. key xlate: ; IF TVI912 DB ESC,'e' ENDIF DB '$' PAGE PROC GET_S_A: LK A,'A' CALL GETSYS RET GET_S_B LK A,'B' CALL GETSYS RET PUT_S_A: LK A,'A' CALL PUTSYS RET PUT_S_B: LK A,'B' CALL PUTSYS RET PAGE SETM1: ;Set menu 1 LK HL,MENU1 STO HL,MENU_TABLE LK HL,COM1 STO HL,COM_TABLE LK HL,MAIN1 STO HL,MAIN LK A,NO_OPT_1 STO A,NUM_OPTIONS LK A,32 ;Make Get from A default STO A,Y_COORD RET SETM2: ;Set menu 2 LK HL,MENU2 STO HL,MENU_TABLE LK HL,COM2 STO HL,COM_TABLE LK HL,MAIN2 STO HL,MAIN LK A,NO_OPT_2 STO A,NUM_OPTIONS LK A,33 ;Make Save on B default STO A,Y_COORD RET MENU1: DW GET_A_MSG DW GET_B_MSG DW EXIT_MSG COM1: DW GET_S_A DW GET_S_B DW EXIT MENU2: DW PUT_A_MSG DW PUT_B_MSG DW EXIT_MSG COM2: DW PUT_S_A DW PUT_S_B DW EXIT PAGE ; UTILITY SUBROUTINES CIN: ; LDK E,0FFH LDK C,6 CALL SYS ORA A JZ CIN RET OCHR: ;Output character to console ;Entry ;A = char ;EXIT ;NONE PROC MOV E,A LDK C,CONO JMP SYS @CRLF: ;SEND CARRIAGE RETURN, LINE FEED PROC LDK A,CR CALL OCHR LDK A,LF JR OCHR OLSTR: ;Output string to console with leading CR,LF ;Entry ;HL = Fwa of message proc PUSH HL CALL @CRLF ;new line POP HL OSTR: ;Output string LD A,[hl] OR A RZ ;if end PUSH HL CALL OCHR POP HL INC HL JR OSTR TITLE 'CALLS TO ROM RESIDENT ROUTINES' GOROM: LD A,2 MOV H,A LK L,5Ah JMP [HL] RET PAGE SENDEN: ;ENTRY ;NONE ;EXIT ;B = NUMBER OF SECTORS ON ONE TRACK ;A = 0 IF GOOD ;ZBIT = SET IF GOOD PROC LDK DE,SEN_RTN JMP GOROM READ: ;READ ONE SECTOR LDK DE,RD_RTN CALL GOROM RET WRITE: ;WRITE ONE SECTOR LDK DE,WRT_RTN CALL GOROM RET PAGE GETSYS: ;GET SYSTEM FROM DISK DRIVE PROC ;SELECT DISK GIVEN BY REGISTER A :1: STO A,BDISK ;Put drive letter in message SUI 'A' ;Make drive # relative 0 STO A,SDISK ;Save in Hi RAM disk select cell INC A ;Bump drive # to be relative 1 STO A,SRCFCB ;Store drive # in FCB CALL CLR_W_2 ;Clear status display window ;SET RW TO READ AND GET THE SYSTEM XRA A STO A,RW ;set flag for READ CALL GETPUT ;Get system into memory RNZ ;Try again if error ; ; Check for valid system disk: ; First byte on track 0 must be a 0, 4th byte must be the product code ; defined in the systext. ; :CONT: LD A,SYSBUFF ;Load first byte of system tracks OR A ;Is it zero? JRNZ :SYS_BAD ;No, system is bad ; ;First byte is zero... LD A,SYSBUFF+4 ;Load byte 4 CMP PROD_CODE ;Is it product code? JRZ :2 ;Yes, disk valid ; :SYS_BAD: ;Disk is invalid. LDK HL,BSYSD CALL OSTR ;indicate ill-formed disk CALL WAIT_CR ;Wait for carriage return CALL CLR_W_2 ;Clear message window RET ;try again :2: ;System tracks read in. ;Now read file CPM3.SYS LK C,0DH ;Reset disk system CALL SYS XOR A ;Clear extent byte of FCB STO A,SRCFCB+12 ; LK DE,SRCFCB ;Open CPM3.SYS LK C,0FH CALL SYS INC A ;Does it exist? (A <> 255) JNZ :EXISTS ;Yes... ; ;No. Check for error on file open. XOR A ;Zero A OR H ;Is H zero? JNZ :RD_ERR ;No, hard error occurred... ; LK HL,C3NFMSG ;Yes. File not found. Display message. CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET ;and return to driver ; :EXISTS: ;CPM3.SYS exists. Now read it in XOR A ;Zero count of 128 sector blocks STO A,BLKCNT ;and count of remaining sectors used STO A,REMCNT ;by write in PUTSYS later on LK E,128 ;Set Multi sector count to 128 LK C,2CH CALL SYS LK DE,FILEBUFF ;Set DMA address to beginning of file buffer :RDLP: PUSH DE ;Save DMA addr LK C,1AH CALL SYS LK DE,SRCFCB ;Read next 16K block of source file LK C,14H CALL SYS POP DE ;Restore DMA address OR A ;Check for errors (A <> 0) JNZ :MB_EOF ;Errors occurred. Check for EOF ; LK HL,BLKCNT ;No error, increment block counter INC [HL] ;Update DMA address LK HL,128*128 ;Advance it 16K ADD HL,DE EX HL,DE ;Put it in DE JMP :RDLP ;Read next 16 K block :MB_EOF: ;Error occurred in read. Is it EOF? DEC A ;is A=1? JNZ :RD_ERR ;No. Read error occurred... ; :ITS_EOF: ;Read error is EOF MOV A,H ;H = # sectors read STO A,REM_CNT ;Save as remainder count LK DE,SRCFCB ;Compute size of CPM3.SYS LK C,23H ; CALL SYS OR A ;Check for error. JNZ :RD_ERR ;Error occurred... ; ;CPM3.SYS is now read into the file ;buffer. LDK HL,RDONE CALL OSTR ;complete message to usA :10010000C37601C36B010D0A20436F707972696772 :100110006874201B67131B472031393833204F7315 :10012000626F726E6520436F6D70757465722043E7 :100130006F72706F726174696F6E2C0D0A203236A7 :100140003533382044616E746920436F7572742CA6 :1001500020486179776172642C204341203934351D :1001600034352E0D0A2056312E321A217201CDF36C :1001700002C91B73300031D6140E0CCD05007CB7BC :10018000C289017DFE30D29201210811CDF302C354 :1001900000001EFF0E2DCD0500CDFE01214D0ACD24 :1001A000F302218B11CDF302CD2504ED5BF9032A77 :1001B000FC01373FED52CAD601ED53FC0113130E7B :1001C00009CD05003A800ECD9703215A0BCDF302DD :1001D000CD1303CD020311AB01D5CDE702FE0BCA4F :1001E0003E02FE8ACA3E02FE0ACA6802FE8CCA6845 :1001F00002FE0DCA6203CDD702C3DA010000210B53 :1002000002CDF302213302CDF302C91B7A3125342A :100210002C701B7A32342037701B7A332D203370C8 :100220001B7A352A2030701B7A362D2030701B73D4 :10023000301A001B66001B7A3426342F7000218090 :100240000E3A7A0EFE00280321880E7EFE20281426 :10025000F53D77F1CDCD033A800ECD9703CD130355 :10026000CD0203C9CDD702C921800E3A7A0EFE0015 :10027000280F21880E3A8B0EC61F477EB8282018FB :100280000A3A790EC61F477EB82814F53C77F1CD9F :10029000CD033A800ECD9703CD1303CD0203C9CD14 :1002A000D702C93A8B0EFE0028153A7A0EFE0128B5 :1002B0000E3E01327A0E3E2032880ECD0203C9CDA9 :1002C000D702C93A7A0EFE0028093E00327A0ECDD6 :1002D0000203C9CDD702C91E070E02CD0500C91EF3 :1002E0001A0E02CD0500C91EFF0E06CD0500FE0048 :1002F00028F5C97E23FE00C80E025FE5CD0500E1AA :1003000018F121830E3A7A0EFE012803217B0ECDCF :10031000F302C93A800ED620876F2600ED5BF50305 :10032000195E23562A3E03373FED52CA3D03ED5373 :100330003E031A328B0E130E09CD0500C9C9000009 :10034000215A0BCDF3023A800ED620876F2600ED9E :100350005BF503195E23561A328B0E130E09CD0579 :1003600000C9219203CDF3023A800ED620876F2672 :1003700000ED5BF703195E2356EB117F03D5E9ED22 :100380005BF9032AFC01373FED52C0CD4003CD029B :1003900003C91B73351A00F5C605323902323B0218 :1003A000F1D6202AF9035E2356EB5F160019195E79 :1003B0002356EBE511030019366A213602CDF3020C :1003C000E1E5CDF302E111030019366BC9F5C6056D :1003D000323902323B02F1D6202AF9035E2356EB72 :1003E0005F160019195E2356EBE5213602CDF302A4 :1003F000E1CDF302C90000000000001106040E095F :10040000CD0500C300001B73301A1B65243E41CD8F :10041000BE04C93E42CDBE04C93E41CD7705C93EAA :1004200042CD7705C9215F0422F50321650422F737 :100430000321EE0A22F9033E0332790E3E20328078 :100440000EC9216B0422F50321710422F70321E870 :100450000C22F9033E0332790E3E2132800EC9FE92 :100460000B730C3C0E0D041304FB03520DC70D3C23 :100470000E19041F04FB031EFF0E06CD0500B7CAAC :100480007704C95F0E02C305003E0DCD83043E0A0A :1004900018F1E5CD8904E17EB7C8E5CD8304E123F9 :1004A00018F53A0200672E5AE9C9116001C3A20487 :1004B000115A01CDA204C9115D01CDA204C932A215 :1004C0000FD6413250FD3C32D614CD0F07AF32FE6D :1004D0000FCD2507C03A6C15B720073A7015FE02FC :1004E000280D217B0FCD9704CD0707CD0F07C90E2F :1004F0000DCD0500AF32E21411D6140E0FCD05005C :100500003CC21605AFB4C26A05212B12CD9704CDAB :100510000707CD0F07C9AF326915326A151E800E65 :100520002CCD0500116C51D50E1ACD050011D61435 :100530000E14CD0500D1B7C246052169153421003E :100540004019EBC327053DC26A057C326A1511D6F6 :10055000140E23CD0500B7C26A0521950ECD970470 :10056000CD0707CD0F07CD4204C921FF0FCD97045A :10057000CD0707CD0F07C9324B1332D613D6413200 :1005800050FD3C32FA14CD0F0721FE0F3601CD2568 :1005900007C00E0DCD0500AF32061511FA140E0F6F :1005A000CD05003CC2AF05AFB4C2BB06C3E905210F :1005B0009D13CD9704CDF206FE4EC2C105CD0F07A7 :1005C000C93A0315E67F3203153A0415E67F320473 :1005D0001511FA140E1ECD05003CCABB0611FA1403 :1005E0000E13CD05003CCABB061166150E1ACD05CB :1005F000003AFA143D5F0E2ECD05003CCABB06063C :100600000311F914216815CDE806DA1D06CA1D0686 :10061000211913CD9704CD0707CD0F07C9AF3206B7 :100620001511FA140E16CD05003CCABB06AF321ADE :10063000153A691547116C51AFB0CA5C06C5D50EA5 :100640001ACD05001E800E2CCD0500CD1B07D1C193 :10065000C2BB0621004019EB05C338063A6A15B73C :10066000CA7606D55F0E2CCD0500D10E1ACD050039 :10067000CD1B07C2BB0611FA140E10CD05003CCAF3 :10068000BB063A0315F6803203153A0415F680329C :10069000041511FA140E1ECD05003CCABB063A0320 :1006A00015E67F3203153A0415E67F320415210A58 :storage for address of last command description displayed: ; O_SUB_MN: DW 0 PAGE F_CMD_DESC: ; Display general direction message and force re-display of command ; description for currently selected command. ; ; Command description IS re-displayed even if it has already been ; displayed. ; ; This routine is called after DO_COMMAND processes the current command. ; DO_COMMAND erases the command description and general directions and ; they must be restored even though the description has already been ; displayed. ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; ; PROC LK HL,DIR_MSG ;Display general (arrow key) directions CALL OUT_STRING LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A r A elative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return PAGE DO_COMMAND: ; Process the currently selected command on the currently selected ; menu. ; ; Clears current command description but re-displays it only if ; menu has NOT changed. ; ; ENTRY: ; Y_COORD = line # of current command. ; COM_TABLE = address of table of pointers to command routine for ; current menu. ; ; EXIT: ; None. ; PROC LK HL,:CLR_W_5 ;Clear command description for current CALL OUT_STRING ;command. LD A,Y_COORD ;Load line # of current command. SUB 32 ;Make relative - 0 ADD A ;Double to index into command ptr table MOV L,A LK H,0 LD DE,COM_TABLE ;Index into command table ADD HL,DE LD E,[HL] ;Load ptr to command routine INC HL LD D,[HL] EX DE,HL ;Put ptr in HL LK DE,:DO_RET ;Load address of return point PUSH DE ;and save as return address JMP [HL] ;Jump to command routine ; :DO_RET: ;Return point from command routine. LD DE,MAIN ;Has main menu changed? LD HL,OLD_MN STC CMC SBC HL,DE RNZ ;Yes, command descr must have changed, ;so return to driver without ;re-displaying it. CALL F_CMD_DESC ;Force re-display of command ;description and general directions CALL SET_CURSOR ;and reposition cursor at current ;choice RET ; ; String used to clear window 5: ; :CLR_W_5: DB ESC,'s5','Z'-40h,0 PAGE HI_CURR: ; Highlight (in reverse video) current command string on screen. ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; Assumes ATT_OFS-th char of command string is attribute byte of attribute ; definition escape sequence (ESC-G-X) ; ; EXIT: ; None. ; PROC IF TVI912 :ATT_OFS = 3 ;Offset in command string to attribute ;byte :INV_ON = 'j' ;Reverse video on attribute char :INV_OFF = 'k' ;Reverse video off attribute char ENDIF IF TVI950 :ATT_OFS = 4 ;Offset in command string to attribute ;byte :INV_ON = '4' ;Reverse video on attribute char :INV_OFF = '0' ;Reverse video off attribute char ENDIF PUSH AF ;Save line # ADI 5 ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save addr LK DE,:ATT_OFS ;Index into cmd line string to attribute ADD HL,DE ;byte STO :INV_ON,[HL] ;Set attribute byte to reverse video LK HL,W_STR ;Set window for current line CALL OUT_STRING ; POP HL ;Restore address of cmd string PUSH HL ;Save it CALL OUT_STRING ;Display cmd string in reverse video POP HL ;restore cmd string addr LK DE,:ATT_OFS ;Index back to attribute byte ADD HL,DE ; STO :INV_OFF,[HL] ;Set it to normal RET ;and return PAGE UN_HI_CR: ; Remove highlighting from command string on screen ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; ; EXIT: ; None. ; PUSH AF ;Save line # ADI 5 ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save it LK HL,W_STR ;Define window for current line CALL OUT_STRING ;Redisplay cmd string in normal mode POP HL ;Restore addr of cmd str CALL OUT_STRING ;Redisplay cmd string in normal mode RET ;and return PAGE ;------------------------------------------------------------------------------ ; Local storage for driver data structures follows. ; ; MENU_TABLE is a pointer to the table of pointers to command ; descriptions for each command in the current menu. ; MENU_TABLE: DW 0 ; ; COM_TABLE is a pointer to a table of pointers to command routines ; for each command in the current menu. ; COM_TABLE: DW 0 ; ; MAIN is a pointer to the current menu. ; MAIN: DW 0 PAGE EXIT: ; Program exit point. Program r A eturns to CP/M from here: ; Sends termination string to console: sets window 0, clears screen ; and enables fn. key xlate. ; ; ENTRY: ; None. ; ; EXIT: ; None. ; LK DE,GOOD_BYE ;Send termination string to ;console. LK C,PR_STR_FN CALL BDOS JMP WBOOTE ;and warm start. ; GOOD_BYE: DB ESC,'s','0','Z'-040h ; ; For TVI 912 emulation, include string to enable fn. key xlate: ; IF TVI912 DB ESC,'e' ENDIF DB '$' PAGE PROC GET_S_A: LK A,'A' CALL GETSYS RET GET_S_B LK A,'B' CALL GETSYS RET PUT_S_A: LK A,'A' CALL PUTSYS RET PUT_S_B: LK A,'B' CALL PUTSYS RET PAGE SETM1: ;Set menu 1 LK HL,MENU1 STO HL,MENU_TABLE LK HL,COM1 STO HL,COM_TABLE LK HL,MAIN1 STO HL,MAIN LK A,NO_OPT_1 STO A,NUM_OPTIONS LK A,32 ;Make Get from A default STO A,Y_COORD RET SETM2: ;Set menu 2 LK HL,MENU2 STO HL,MENU_TABLE LK HL,COM2 STO HL,COM_TABLE LK HL,MAIN2 STO HL,MAIN LK A,NO_OPT_2 STO A,NUM_OPTIONS LK A,33 ;Make Save on B default STO A,Y_COORD RET MENU1: DW GET_A_MSG DW GET_B_MSG DW EXIT_MSG COM1: DW GET_S_A DW GET_S_B DW EXIT MENU2: DW PUT_A_MSG DW PUT_B_MSG DW EXIT_MSG COM2: DW PUT_S_A DW PUT_S_B DW EXIT PAGE ; UTILITY SUBROUTINES CIN: ; LDK E,0FFH LDK C,6 CALL SYS ORA A JZ CIN RET OCHR: ;Output character to console ;Entry ;A = char ;EXIT ;NONE PROC MOV E,A LDK C,CONO JMP SYS @CRLF: ;SEND CARRIAGE RETURN, LINE FEED PROC LDK A,CR CALL OCHR LDK A,LF JR OCHR OLSTR: ;Output string to console with leading CR,LF ;Entry ;HL = Fwa of message proc PUSH HL CALL @CRLF ;new line POP HL OSTR: ;Output string LD A,[hl] OR A RZ ;if end PUSH HL CALL OCHR POP HL INC HL JR OSTR TITLE 'CALLS TO ROM RESIDENT ROUTINES' GOROM: LD A,2 MOV H,A LK L,5Ah JMP [HL] RET PAGE SENDEN: ;ENTRY ;NONE ;EXIT ;B = NUMBER OF SECTORS ON ONE TRACK ;A = 0 IF GOOD ;ZBIT = SET IF GOOD PROC LDK DE,SEN_RTN JMP GOROM READ: ;READ ONE SECTOR LDK DE,RD_RTN CALL GOROM RET WRITE: ;WRITE ONE SECTOR LDK DE,WRT_RTN CALL GOROM RET PAGE GETSYS: ;GET SYSTEM FROM DISK DRIVE PROC ;SELECT DISK GIVEN BY REGISTER A :1: STO A,BDISK ;Put drive letter in message SUI 'A' ;Make drive # relative 0 STO A,SDISK ;Save in Hi RAM disk select cell INC A ;Bump drive # to be relative 1 STO A,SRCFCB ;Store drive # in FCB CALL CLR_W_2 ;Clear status display window ;SET RW TO READ AND GET THE SYSTEM XRA A STO A,RW ;set flag for READ CALL GETPUT ;Get system into memory RNZ ;Try again if error ; ; Check for valid system disk: ; First byte on track 0 must be a 0, 4th byte must be the product code ; defined in the systext. ; :CONT: LD A,SYSBUFF ;Load first byte of system tracks OR A ;Is it zero? JRNZ :SYS_BAD ;No, system is bad ; ;First byte is zero... LD A,SYSBUFF+4 ;Load byte 4 CMP PROD_CODE ;Is it product code? JRZ :2 ;Yes, disk valid ; :SYS_BAD: ;Disk is invalid. LDK HL,BSYSD CALL OSTR ;indicate ill-formed disk CALL WAIT_CR ;Wait for carriage return CALL CLR_W_2 ;Clear message window RET ;try again :2: ;System tracks read in. ;Now read file CPM3.SYS LK C,0DH ;Reset disk system CALL SYS XOR A ;Clear extent byte of FCB STO A,SRCFCB+12 ; LK DE,SRCFCB ;Open CPM3.SYS LK C,0FH CALL SYS INC A ;Does it exist? (A <> 255) JNZ :EXISTS ;Yes... ; ;No. Check for error on file open. XOR A ;Zero A OR H ;Is H zero? JNZ :RD_ERR ;No, hard error occurred... ; LK HL,C3NFMSG ;Yes. File not found. Display message. CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET ;and return to driver ; :EXISTS: ;CPM3.SYS exists. Now read it in XOR A ;Zero count of 128 sector blocks STO A,BLKCNT ;and count of remaining sectors used STO A,REMCNT ;by write in PUTSYS later on LK E,128 ;Set Multi sector count to 128 LK C,2CH CALL SYS LK DE,FILEBUFF ;Set DMA address to beginning of file buffer :RDLP: PUSH DE ;Save DMA addr LK C,1AH CALL SYS LK DE,SRCFCB ;Read next 16K block of source file LK C,14H CALL SYS POP DE ;Restore DMA address OR A ;Check for errors (A <> 0) JNZ :MB_EOF ;Errors occurred. Check for EOF ; LK HL,BLKCNT ;No error, increment block counter INC [HL] ;Update DMA address LK HL,128*128 ;Advance it 16K ADD HL,DE EX HL,DE ;Put it in DE JMP :RDLP ;Read next 16 K block :MB_EOF: ;Error occurred in read. Is it EOF? DEC A ;is A=1? JNZ :RD_ERR ;No. Read error occurred... ; :ITS_EOF: ;Read error is EOF MOV A,H ;H = # sectors read STO A,REM_CNT ;Save as remainder count LK DE,SRCFCB ;Compute size of CPM3.SYS LK C,23H ; CALL SYS OR A ;Check for error. JNZ :RD_ERR ;Error occurred... ; ;CPM3.SYS is now read into the file ;buffer. LDK HL,RDONE CALL OSTR ;complete message to us A 1006B0000FCD9704CD0707CD0F07C93A0315E67F85 :1006C0003203153A0415E67F32041511FA140E1E92 :1006D000CD050011FA140E13CD0500218310CD971E :1006E00004CD0707CD0F07C91ABEC005C81B2BC311 :1006F000E806CD7704E65FFE59CA0107FE4EC2F256 :1007000006F5CD8304F1C9CD7704FE0D20F9C9218A :100710001607CD9704C91B73321A0011FA140E156F :10072000CD0500B7C9216C15224BFDDB00324AFD17 :100730003E01324DFDCDAA04205CC5CDAE07C120DF :10074000647AFE0E2004CDD707C9C53A51FDCB3FD0 :10075000CB3FE6032813473E01CB2710FC477A1610 :100760000090F514F1280230F8C14AAF324EFD79FD :10077000B7C890300241AF4FC53AFE0FB72808CD39 :10078000B704C120111806CDB004C12009224BFDC9 :100790003A4EFD3C18D63AFE0FB7218310200321B4 :1007A000FF0FCD9704CD0707CD0F07F6FFC92151E5 :1007B000FD7EFE0CC2C00778FE05C2CE071678C9C2 :1007C000FE0EC2CE0778FE05C2CE07160EC9211551 :1007D00014CD9704F6FFC9AF324EFD3C324DFD21DA :1007E0006C15224BFDDB00324AFD3A51FDCB8F32B6 :1007F00051FD0605CD1D0AC2D609216C39224BFDDB :100800003E01324DFD3A51FDCBCF3251FD0601CDB7 :100810001D0AC2D609216C3D224BFD3E02324DFD20 :100820000602CD1D0AC2D609216C4D224BFD3E04A5 :10083000324DFD0601CD1D0AC2D6090E0DCD0500B3 :100840003A50FD3C321E15324215AF322A15322D78 :1008500015323E15324E153251153262153AFE0FE1 :10086000B7C2C008111E150E0FCD05003CCA0E0AF6 :10087000016C29111E15212000CD2B0AC2E409119B :100880001E150E10CD0500B7C2E4091142150E0F5A :10089000CD05003CC2A408216C3D116C4501000847 :1008A000EDB0AFC9016C45114215211000CD2B0AE6 :1008B000C2F2091142150E10CD0500B7C2F209C9E6 :1008C000111E150E0FCD05003CF53A2715E67F32B7 :1008D00027153A2815E67F322815F12818111E151C :1008E0000E1ECD05003CCA000A111E150E13CD05C3 :1008F000003CCA000A1142150E0FCD05003CF53A26 :100900004B15E67F324B153A4C15E67F324C15F10C :1009100028181142150E1ECD05003CCA000A1142CE :10092000150E13CD05003CCA000A111E150E16CD7A :1009300005003CCA000A016C29111E15212000CDBA :100940002B0AC2000A111E150E10CD0500B7C200F9 :100950000A3A2715F6803227153A2815F6803228EC :1009600015111E150E1ECD0500F53A2715E67F322E :1009700027153A2815E67F322815F13CCA000A11DE :1009800042150E16CD05003CCA000A016C45114205 :1009900015211000CD2B0AC2000A1142150E10CDF0 :1009A0000500B7C2000A3A4B15F680324B153A4C97 :1009B00015F680324C151142150E1ECD0500F53A84 :1009C0004B15E67F324B153A4C15E67F324C15F14C :1009D0003CCA000AAFC93AFE0FB72183102032216A :1009E000FF0F182D3AFE0FB7218310202421FF0F8F :1009F000181F3AFE0FB7218310201621FF0F181180 :100A00003AFE0FB7218310200821FF0F180321A2FF :100A100012CD9704CD0707CD0F07F6FFC93AFE0F99 :100A2000B72804CDB704C9CDB004C9D550590E1AA2 :100A3000E5CD0500E1EB0E2CCD0500D13AFE0FB758 :100A40000E1520020E14CD0500B7C83DC91B73302A :100A50001A2020202020202020202020202020209C :100A6000202020202020202020204F7065726174DB :100A7000696E672053797374656D20436F707920B8 :100A800050726F6772616D0D0A2020202020202097 :100A90002020202020202020202020202020202056 :100AA0004F73626F726E65204558454355544956E1 :100AB0004520436F6D70757465722053797374654A :100AC0006D0D0A2020202020202020202020202002 :100AD0002020202020202020202020202020202016 :100AE00020202020202020202056312E3200540BA0 :100AF0001B73311A20201B6B2047657420537973B8 :100B000074656D2066726F6D204472697665204150 :100B1000201B6B000D0A20201B6B2047657420539F :100B2000797374656D2066726F6D204472697665A5 :100B30002042201B6B000D0A20201B6B2052657485 :100B400075726E20746F2043502F4D201B6B000D6B :100B50000A0D0A24F40A160B380B1B73351A2020D1 :100B60002020202020202020202020202020202085 :100B70002020202020557365207468652041525242 :100B80004F57204B45595320746F20706F73697411 :100B9000696F6E207468650D0A20202020202020B7 :100BA0002020202020202020202020202020202045 :100BB000637572736F72206E65787420746F207421 :100BC000686520646573697265642063686F696332 :100BD000652E0D0A202020202020202020202020EB :100BE0002020202020202020202020202020202005 :100BF00020202020202020202020206F7200001B99 :100C000073361A2020202020202020202020202081 :100C1000202020202020202020202020496E7365C5 :100C20007274206469736B6574746520696E204406 :100C300072697665204120616E640D0A20202020B3 :100C400020202020202020202020202020202020A4 :100C5000202020202020205072657373205245549C :100C600055524E20746F20524541442053595354DD :100C7000454D24001B73361A2020202020202020E0 :100C80002020202020202020202020202020202064 :100C900020496E73657274206469736B6574746542 :100CA00020696E204472697665204220616E640D71 :100CB0000A2020202020202020202020202020204A :100CC000202020202020202020202020507265730A :100CD000732052455455524E20746F205245414462 :100CE0002053595354454D244C0D1B73311A202069 :100CF0001B6B20536176652053797374656D206F8B :100D00006E2044726976652041201B6B000D0A201D :100D1000201B6B20536176652053797374656D20B9 :100D20006F6E2044726976652042201B6B000D0AAD :100D300020201B6B2052657475726E20746F2043E7 :100D4000502F4D201B6B000D0A0D0A24EE0C0F0DC9 :100D5000300D001B73361A20202020202020202058 :100D60002020202020202020202020202020202083 :100D7000496E73657274206469736B657474652061 :100D8000696E204472697665204120616E640D0AA7 :100D90002020202020202020202020202020202053 :100DA00020202020202020202020205072657373D6 :100DB0002052455455524E20746F205341564520C1 :100DC00053595354454D24001B73361A202 A 02020BC :100DD0002020202020202020202020202020202013 :100DE0002020202020496E73657274206469736B23 :100DF0006574746520696E204472697665204220AE :100E0000616E640D0A202020202020202020202038 :100E100020202020202020202020202020202020D2 :100E200050726573732052455455524E20746F2092 :100E3000534156452053595354454D24001B733696 :100E40001A202020202020202020202020202020A8 :100E50002020202020202020202050726573732025 :100E600052455455524E20746F2072657475726EDF :100E700020746F2043502F4D2400001B73311B3D05 :0B0E80002020001B73321B3D202000CF :100E8C00001B73321A1B7331241B73321A2020205F :100E9C002020202020202020202020202020202046 :100EAC00202020202020202053797374656D20721F :100EBC00656164207375636365737366756C6C79B7 :100ECC002E200D0A20202020202020202020202031 :100EDC002020202020202020202050726573732099 :100EEC0052455455524E20746F2073656C65637473 :100EFC002073617665206F7074696F6E2E001B73A2 :100F0C00321A2020202020202020202020202020C9 :100F1C002020202020202020202020205379737492 :100F2C00656D20636F7069656420737563636573A9 :100F3C007366756C6C792E200D0A202020202020E1 :100F4C002020202020202020202020202020202095 :100F5C002020202050726573732052455455524EF8 :100F6C0020746F20636F6E74696E75652E20001B84 :100F7C0073321A2020202020202020202020202006 :100F8C00202020204469736B6574746520696E2081 :100F9C0064726976652058206973206E6F742061C5 :100FAC002073797374656D206469736B65747465F3 :100FBC002E0D0A2020202020202020202020202040 :100FCC002020202053797374656D2067657420612F :100FDC00626F727465642E20507265737320524573 :100FEC005455524E20746F20636F6E74696E756524 :020FFC002E00C5 :100FFF001B73321A20202020202020202020202088 :10100F002020202041206469736B206572726F72FB :10101F00206F63637572726564207768696C6520F1 :10102F0072656164696E6720746865207379737483 :10103F00656D2E0D0A20202020202020202020202A :10104F0020202020202053797374656D20676574EC :10105F002061626F727465642E2050726573732005 :10106F0052455455524E20746F20636F6E74696EE3 :10107F0075652E001B73321A20202020202020207F :10108F00202020202020202041206469736B2065C0 :10109F0072726F72206F6363757272656420776806 :1010AF00696C652077726974696E67207468652052 :1010BF0073797374656D2E0D0A2020202020202057 :1010CF002020202020202020202053797374656D4C :1010DF0020736176652061626F727465642E205093 :1010EF00726573732052455455524E20746F2063AE :1010FF006F6E74696E75652E00434F505953595377 :10110F002072657175697265732043502F4D2033BE :10111F002E58206F7220677265617465722E0D0AEA :10112F00436F70797269676874201B67131B4720C0 :10113F0031393833204F73626F726E6520436F6D94 :10114F00707574657220436F72706F726174696F1E :10115F006E2C0D0A32363533382044616E74692097 :10116F00436F7572742C20486179776172642C20FB :10117F0043412039343534352E0D0A001B73321A92 :10118F002020201B67131B472031393833204F7322 :10119F00626F726E6520436F6D7075746572204358 :1011AF006F72706F726174696F6E2C2032363533C7 :1011BF00382044616E746920436F7572742C204817 :1011CF006179776172642C2043412039343534358D :1011DF000D0A2020202020202020201B67131B47D2 :1011EF002031393834204675747572652053797300 :1011FF0074656D732C20383238204E6F6220486929 :10120F006C6C204176656E75652C2050696E6F6C25 :10121F00652C204341203934353634001B73321A84 :10122F0020202020202020202020202020202020AF :10123F002020202043504D332E535953206E6F746E :10124F0020666F756E642E2053797374656D2067F9 :10125F0065742061626F727465642E0D0A20202000 :10126F00202020202020202020202020202020206F :10127F0020202020202020202050726573732052C0 :10128F00455455524E20746F20636F6E74696E759E :10129F00652E001B73321A202020202020202020B2 :1012AF002020202020202020202020204343502EAB :1012BF00434F4D206E6F7420666F756E642E2053F2 :1012CF00797374656D206765742061626F727465E0 :1012DF00642E0D0A202020202020202020202020D6 :1012EF0020202020202020202020202020202020EF :1012FF0050726573732052455455524E20746F20AF :10130F00636F6E74696E75652E001B73321A202021 :10131F0020202020202020202020202020202020BE :10132F00496E73756666696369656E742073706163 :10133F006365206F6E206472697665200120666F89 :10134F00722043504D332E5359532E200D0A202017 :10135F00202020202020202020202020202020534B :10136F00797374656D20736176652061626F727435 :10137F0065642E2050726573732052455455524E3A :10138F0020746F20636F6E74696E75652E001B730A :10139F00321A202020202020202020202020202032 :1013AF002020202020202020202043504D332E535A :1013BF00595320697320616C7265616479206F6E77 :1013CF0020647269766520012E0D0A2020202020CE :1013DF0020202020202020202020202020202020FE :1013EF002020446F20796F752077616E7420746FA1 :1013FF00206F766572777269746520697420287919 :10140F002F6E293F20001B73321A2020202020200E :10141F002020202020202020202020537973746545 :10142F006D206469736B206D757374206265204F36 :10143F00434320646F75626C652064656E736974D5 :10144F007920666F726D61742E0D0A202020202086 :10145F00202020202020202020202020537973744A :10146F00656D20736176652061626F727465642E9D :10147F002050726573732052455455524E20746F2D :0B148F0020636F6E74696E75652E009F :1014D6000043504D33202020205359530000000074 :1014E60000000000000000000000000000000000F6 :1014F600000000000043504D332020202053595354 :1015060000000000000000000000000000000000D5 :1015160000000000000000000043 Aer CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window CALL SET_M2 ;Set menu 2 RET PAGE :RD_ERR: ;Hard read error occurred. LK HL,F_RD_ERR ;Display message CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET PAGE PUTSYS: ;Now put the system on user requested disk PROC :1: STO A,PDISK2 ;SET DRIVE letter STO A,PDISK3 ;in messages SUI 'A' STO A,SDISK ;and in data structures INC A ;Bump to be relative 1 STO A,DSTFCB ; CALL CLR_W_2 ;Clear message window ;Write system track image to destination diskette: :WR_SYS: LDK HL,RW ;Set read/write flag to write. STO 1,[HL] CALL GETPUT ;TO PUT SYSTEM BACK ON DISKETTE RNZ ;TRY AGAIN IF ERROR ;Write CPM3.SYS file to destination drive LK C,0DH ;Reset disk system CALL SYS XOR A STO A,DSTFCB+12 ;Clear extent byte of dest FCB LK DE,DSTFCB ;See if file exists already LK C,0FH CALL SYS INC A ;(A <> 255) JNZ :EXISTS ;File exists already...  ; XOR A ;Check for hard error. Clear A OR H ;Is H zero? JNZ :WR_ERR ;No... hard err ; JMP :NO_DEST ;A = 255 and H = 0. No file on dest disk. ; :EXISTS: LK HL,DELMSG ;Destination file exists, ask CALL OSTR ;user if it should be overwritten :G_ANS: CALL Y_N ;Get user response: Y or N CMP 'N' JNZ :CONT ;Yes... ; ;No. ;User doesn't want to delete old file. CALL CLR_W_2 ;Clear message window RET ;and return to driver ; :CONT: ;Delete old CPM3.SYS LD A,DSTFCB+9 ;Set dest file R/W and DIR AND 7FH STO A,DSTFCB+9 LD A,DSTFCB+10 AND 7FH STO A,DSTFCB+10 LK DE,DSTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; L DE,DSTFC ;Delet destinatio file L C,13H CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; :NO_DEST: ;No conflicting file on destination drive LK DE,DRVSPC ;Set DMA address to scratch area LK C,1AH ;for drive space calculation CALL SYS LD A,DSTFCB ;Check for sufficient space on destination ;drive DEC A ;Decr drive # to be relative 0 MOV E,A ;Get drive spec from FCB LK C,2EH CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; LK B,3 ;See if space left is => file size (left in LK DE,SRCFCB+35 ;source file FCB) LK HL,DRVSPC+2 ; CALL CMP_N_STR ; JC :SUFF_SPC ;Sufficient space available ; JZ :SUFF_SPC ;Ditto... ; LK HL,NSF_SPC ;Insufficient space. Display message CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET ; :SUFF_SPC: ;Sufficient space. Write output file XOR A STO A,DSTFCB+12 ;Clear extent byte of dest FCB LK DE,DSTFCB ;Create output file LK C,16H CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; XOR A ;Clear current record byte of FCB STO A,DSTFCB+32 LD A,BLKCNT ;Get number of blocks to transfer MOV B,A ;Put it in A LK DE,FILEBUFF ;Set DMA to beginning of buffer :WR_LP: XOR A OR B ;Any 16 K blocks left? JZ :WR_REM ;No, write remainder ; PUSH BC ;Save block count PUSH DE ;Save DMA address LK C,1AH ;Set DMA address CALL SYS LK E,128 ;Set multi sector count to 128 LK C,2CH CALL SYS CALL WR_BUFF ;Write current 16 K block POP DE ;Restore DMA addr POP BC ;and block count JNZ :WR_ERR ;Write error? LK HL,128*128 ;Bump DMA addr another 16 K ADD HL,DE EX HL,DE ;Put it in DE DEC B ;Decrement block counter JMP :WR_LP ;Loop again ; :WR_REM: ;All full 16K blocks written, write ;remainder LD A,REMCNT ;Get number of remaining 128 byte sectors OR A ;Is it zero? JZ :CLS_CPM3 ;Yes, no remaining records to write: close file ; ;No, write remainder PUSH DE ;Save DMA address MOV E,A ;Yes, set multi sector count LK C,2CH CALL SYS POP DE ;Restore DMA address LK C,1AH ;Set BDOS DMA address CALL SYS CALL WR_BUFF JNZ :WR_ERR ;Write error? ; ; No errors, close file and write system tracks ; :CLS_CPM3: ;Output file written, now close it LK DE,DSTFCB LK C,10H CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; LD A,DSTFCB+9 ;Set dest file R/O and SYS OR 80H STO A,DSTFCB+9 LD A,DSTFCB+10 OR 80H STO A,DSTFCB+10 LK DE,DSTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; LD A,DSTFCB+9 ;Reset dest file attributes to R/W and DIR. AND 7FH ;If attributes are not reset, any attempt STO A,DSTFCB+9 ;to create a new destination file (on another ;diskette, perhaps) results in a CP/M Error: LD A,DSTFCB+10 ;File Read/Only message. This is due to the AND 7FH ;file being created with the R/O attribute set. STO A,DSTFCB+10 LK HL,DONE CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET ;FOR ANOTHER PUT OPERATION PAGE :WR_ERR: ;Write error occurred in writing CPM3.SYS LD A,DSTFCB+9 ;Set deAst file R/W and DIR AND 7FH STO A,DSTFCB+9 LD A,DSTFCB+10 AND 7FH STO A,DSTFCB+10 LK DE,DSTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS ;No check for error, since we're going to ;display an error message anyway L DE,DSTFC ;Delet destinatio file L C,13H CALL SYS ;No check for error, since we're going to ;display an error message anyway LK HL,W_ERR_MS ;Write error: display message CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET PAGE CMP_N_STR: ; Utility subroutine to compare 2 numerical byte strings ; of equal length. Strings are stored with their least significant ; byte in low memory. ; ; ENTRY: ; B = Length of strings ; DE ==> Most Significant Byte of string 1 ; HL ==> MSB of string 2 ; ; EXIT: ; Z bit set if String 1 = String 2 ; C Bit set if String 1 < String 2 ; (i.e., flags are set just as if a single byte compare were done.) ; PROC :COMP_LP: LD A,[DE] ;Load byte of str 1 CMP [HL] ;Compare with byte of str 2 RNZ ;Return if bytes different: C set ;accordingly ; DEC B ;Is this the last byte? RZ ;Yes, return with Z set ; DEC DE ;No, check next byte DEC HL JMP :COMP_LP PAGE Y_N: ; Get Y or N response from keyboard PROC :YNLP: CALL CIN AND 5FH CMP 'Y' JZ :ECHO ; CMP 'N' JNZ :YNLP ; :ECHO: PUSH AF ;Echo char in A CALL OCHR POP AF RET PAGE WAIT_CR: ; Wait for user to enter carriage return PROC :CR_LP: CALL CIN ;Get a char CMP CR ;Is it carriage return? JRNZ :CR_LP ;No, get another ; RET ;Yes, return. PAGE CLR_W_2: ; Clear window 2 LK HL,:CLS CALL OSTR RET ; :CLS: DB ESC,'s2','Z'-40h,0 WR_BUFF: ; Routine to perform sequential to destination file LK DE,DSTFCB ; LK C,15H CALL SYS OR A ;Set Z bit if no error RET PAGE GETPUT: ;Get or PUT cpm onto disk requested ;ENTRY ;RW = 0 if read, 1 if WRITE ;EXIT ;ZBIT = RESET IF ERROR proc :1: LDK HL,SYS_BUFF STO HL,DMADR ;SET DMA AÀCP/M Version 3.0COPYRIGHT 1982, DIGITAL RESEARCH251082654321!9"k1G \!m!w# š!v6H#6E#6X!e6C#6O#6M<<&:g.".g"?S:2n!`w #4o"c*e{ozg"hj:]@*c"\y!5C*^N{zb+"^*^*`*h"!j4&"h"y:b<5*kG!gwxS0  *cN,*cN{zҽ{,*c*e{ozg ~*c#"c> :[ >  X N*c>:> !:q#G*eDM*h ERROR: $DISK READ$LOAD ADDRESS LESS THAN 100$DISK WRITE$LOAD ADDRESS $ERROR ADDRESS $INVALID HEX DIGIT$CHECKSUM ERROR $FIRST ADDRESS $LAST ADDRESS $BYTES READ $RECORDS WRITTEN $CANNOT OPEN SOURCE FILE$DIRECTORY FULL$CANNOT CLOSE FILE$HEXCOM VERS: 3.00 $UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU4350202020206F :1015260020434F4D000000000000000000000000B6 :1015360000000000000000000000000000414C54C4 :10154600464F4E542053595300000000000000003F :101556000000000000000000000000000000000085 :031569000000007F :00010010 C,xxxTRK,xxxDSK must be maintained ; along with length (1,2,1). SAVSEC DS 1 ;last sector requested SAVTRK DS 2 ;last track requested SDISK DS 1 ;selected disk drive (0,1) SAVTYP DS 1 ;SELECTED TYPE (sector size) IE_ADR: DS 1 CURPOS: DS 2 ;Current cursor position ; VARIABLES FOR HIGH RAM ROUTINES TEMSAV DS 1 ;Used by jump bank routine SRCBANK DS 1 ;Source bank for block move DESTBANK DS 1 ;Destination bank for block move ;JMPSPOT and JMPADDR must stay next to each other JMPSPOT DS 1 ;To be filled in with a JMP instruction by the ROM JMPADDR DS 2 ;Address to jump to for BANKJMP and BANKCALL JMPBANK DS 1 ;Bank to jump to for BANKJMP and BANKCALL EMRAM = * ; INTERRUPT VARIABLES USR_BNK DS 1 ;UAvk Copyright gG 1983 Osborne Computer Corporation, 26538 Danti Court, Hayward, CA 94545. V1.2!rs01 |‰}0Ғ!-!M !%[*7?RS :͗!Z  >> hh b! !3z1%4,pz24 7pz3- 3pz5* 0pz6- 0ps0fz4&4/p!:z(!~ (=w:͗!:z(!:G~(  :yG~(2z> 2:z( >2z(~#_!:z(!{: o&[^#V*>7?R=S>2 !Z : o&[^#V2 !: o&[^#V[*7?R@s5292; *^#V_^#V6j!66k292; *^#V_^#V!6 s0e$>A;>B;>Aw>Bw!_"!e"! ">2y> 2!k"!q"! ">2y>!2 s < R <w_> ̓> ͉~̓#:g.Z`âZ͢]͢2A2P<22%:l :p( !{͗ 2<j!+͗ɯ2i2j,lQѷF!i4!@'=j|2j#j!͗B!͗2K2A2P<2!6% 2<¯»!͗N:2:2<ʻ<ʻf:=_.<ʻ!h!͗ɯ2<ʻ2:iGlQ\,»!@8:jv_,»<ʻ:2:2<ʻ:2:2! ͗:2:2!͗+w_YN̓w !͗s2!l"K2J>2Mͪ \ͮ dz :Q??(G>'Gz(0J2NyȐ0AO:(ͷ Ͱ "K:N<:! !͗!Q~ xxx!͗ɯ2N<2M!l"K2J:Qˏ2Q !l9"K>2M:Q2Q !l="K>2M !lM"K>2M  :P<22B2*2-2>2N2Q2b:< l)! +  B<¤!l=lElEB!+ B <:'2':(2((< < B<:K2K:L2L(B< B< < l)! +  :'2':(2(:'2':(2(< B< lEB!+ B :K2K:L2LB:K2K:L2L< :! 2!-:! $!:! !:! !!͗:(ͷͰPY,: =s0 Operating System Copy Program Osborne EXECUTIVE Computer System V1.2T s1 k Get System from Drive A k k Get System from Drive B k k Return to CP/M k $  8 s5 Use the ARROW KEYS to position the cursor next to the desired choice. ors6 Insert diskette in Drive A and Press RETURN to READ SYSTEM$s6 Insert diskette in Drive B and Press RETURN to READ SYSTEM$L s1 k Save System on Drive A k k Save System on Drive B k k Return to CP/M k $  0 s6 Insert diskette in Drive A and Press RETURN to SAVE SYSTEM$s6 Insert diskette in Drive B and Press RETURN to SAVE SYSTEM$s6 Press RETURN to return to CP/M$s1= s2= s2s1$s2 System read successfully. Press RETURN to select save option.s2 System copied successfully. Press RETURN to continue. s2 Diskette in drive X is not a system diskette. System get aborted. Press RETURN to continue.s2 A disk error occurred while reading the system. System get aborted. Press RETURN to continue.s2 A disk error occurred while writing the system. System save aborted. Press RETURN to continue.COPYSYS requires CP/M 3.X or greater. Copyright gG 1983 Osborne Computer Corporation, 26538 Danti Court, Hayward, CA 94545. s2 gG 1983 Osborne Computer Corporation, 26538 Danti Court, Hayward, CA 94545 gG 1984 Future Systems, 828 Nob Hill Avenue, Pinole, CA 94564s2 CPM3.SYS not found. System get aborted. Press RETURN to continue.s2 CCP.COM not found. System get aborted. Press RETURN to continue.s2 Insufficient space on drive  for CPM3.SYS. System save aborted. Press RETURN to continue.s2 CPM3.SYS is already on drive . Do you want to overwrite it (y/n)? s2 System disk must be OCC double density format. System save aborted. Press RETURN to continue.CPM3 SYSCPM3 A ; +-------------------------------+ ; | | ; | SHELLY SYSTEXT | ; | | ; +-------------------------------+ ; I/O PORTS SYS_DTA = 00H ;System PIA data A SYS_CNA = 01H ;System PIA control A SYS_DTB = 02H ;System PIA data B SYS_CNB = 03H ;System PIA control B TIM_CT0 = 04H ;8253 Timer counter 1 TIM_CT1 = 05H ;8253 Timer counter 2 TIM_CT2 = 06H ;8253 Timer counter 3 TIM_CNL = 07H ;8253 Timer control register DSK_CMD = 08H ;Floppy disk DISK COMMAND REG (WRITE) DSK_STS = DSK_CMD ;STATUS REG (READ) DSK_TRK = DSK_CMD+1 ;TRACK REG DSK_SEC = DSK_CMD+2 ;SECTOR REG DSK_DAT = DSK_CMD+3 ;DATA REG (R/W) SIO_DTA = 0CH ;SIO data reg A SIO_CNA = 0DH ;SIO control reg A SIO_DTB = 0EH ;SIO data reg B SIO_CNB = 0FH ;SIO control reg B PAR_DTA = 10H ;Parallel port PIA data A PAR_CNA = 11H ;Control register A PAR_DTB = 12H ;Parallel port PIA data B PAR_CNB = 13H ;Control register B KEYBD = 14H ;Keyboard PAGE  ;SYSTEM PIA COMMANDS ;DATA A: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; ROM enable <-+ | | | | | | | ; VIDEO enable <---+ | | | | | | ; Bank 6 enable <------+ | | | | | ; Bank 5 enable <----------+ | | | | ; Bank 4 enable <--------------+ | | | ; Bank 3 enable <------------------+ | | ; Bank 2 enable <----------------------+ | ; Bank 1 enable <--------------------------+ ;DATA B: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; RI(act low) <+ | | | | | | | ; DSR(act low) <---+ | | | | | | ; TX clock select <----+ | | | | | ; RX clock select <--------+ | | | | ; Speaker <--------------------+ | | | ; Drive B (act low) <--------------+ | | ; Drive A (act low) <------------------+ | ; Double density (act low) <---------------+ ;Data DATA_INIT = 1000_0000B ;Enable ROM DATB_INIT = 0000_0111B ;Deselect drives A & B, single density ;spkr off ;Direction DIRA_INIT = 1111_1111B ;Select all lines as outputs DIRB_INIT = 0011_1111B ;Select RI & DSR as inputs, rest as outputs ;Masks ROM_BANK = 1000_0000B ;ROM bank VID_BANK = 0100_0000B ;VIDEO bank SPEAKER = 0000_1000B ;Speaker bit PAGE ;SYSTEM PIA CONTROL REGISTERS ; +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; INTERRUPT FLAGS: | | | | | | | | ; A: DMA Interrupt | | | | | | | | ; B: Real time clock interrupt <---+ | | | | | | | ; | | | | | | | ; Not used <-------+ | | | | | | ; | | | | |  | ; CONTROL 2: | | | | | | ; A: 110 = 64 columns, 111 = 80 columns | | | | | | ; B: 110 = 60 Hz, 111 = 50 Hz <---+---+---+ | | | ; | | | ; DDRA: | | | ; A & B: 1 = Data register, 0 = Direction register <--+ | | ; | | ; CONTROL 1: | | ; A: DMA interrupt request (hw) | | ; B: Real time clock interrupt | | ; | | ; 1 = active high <--------------------------------+ | ; 1 = enable <------------------------------------+ ;Control CA_DAT = 00_110_1_00B ;64 columns ;enable DATA reg ;Disable interrupts CA_DIR = 00_110_0_00B ;64 columns ;enable DIRECTION reg ;disable interrupts CA_64C = 00_110_1_01B ;64 columns ;enable data reg ;enable interrupts CB_DAT = 00_110_1_10B ;60Hz ;enable DATA reg ;Disable interrupts CB_DIR = 00_110_0_10B ;60Hz ;enable DIRECTION reg ;disable interrupts CB_60H = 00_110_1_11B ;60Hz ;enable data reg ;Enable interrupts ;Control masks COL_MSK = 00_001_0_00B ;64/80 Column mask INT_MSK = 00_000_0_01B ;Interrupt enable mask PAGE ;SERIAL PORT -- SIO COMMANDS ;SIO WRITE REGISTERS ;WRITE REG 0: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;CRC RESET CODES: | | | | | | | | ; Null 0 0 | | | | | | ; Reset Rx CRC checker 0 1 | | | | | | ; Reset Tx CRC generator 1 0 | | | | | | ; Reset Tx Underrun/EOM latch 1 1 | | | | | | ;COMMAND BITS: | | | | | | ; Null 0 0 0 | | | ; Send Abort 0 0 1 | | | ; Reset EXT/Status interrupt 0 1 0 | | | ; Channel reset 0 1 1 | | | ; Enable int on next Rx character 1 0A 0 | | | ; Reset Tx int pending 1 0 1 | | | ; Error reset 1 1 0 | | | ; Return from int (Chan A only) 1 1 1 | | | ;POINTER BITS: | | | ; Register 0 0 0 0 ; Register 1 0 0 1 ; Register 2 0 1 0 ; Register 3 0 1 1 ; Register 4 1 0 0 ; Register 5 1 0 1 ; Register 6 1 1 0 ; Register 7 1 1 1 ;WRITE REG 1: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;WAIT/READY: | | | | | | | | ; Wait/Ready Enable <-+ | | | | | | | ; ~Wait/Ready Function <--+ | | | | | | ; Wait/Ready on Rx/Tx <------+ | | | | | ;Rx INTERRUPT MODE: | | | | | ; Rx interrupts disabled 0 0 | | | ; Rx int on first char 0 1 | | | ; Int on all Rx chars 1 0 | | | ; Int on all Rx chars 1 1 | | | ;Status Affects Vector (Chan B only) <--------------+ | | ;Tx Int Enable <---------------------------------------+ | ;Ext Int Enable <-------------------------------------------+ PAGE ;WRITE REG 2: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Interrupt Vector <--------------+---+---+---+---+---+---+---+ ;WRITE REG 3: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;RECEIVER BITS/CHARACTER: | | | | | | | | ; 5 bits 0 0 | | | | | | ; 6 bits 0 1 | | | | | | ; 7 bits 1 0 | | | | | | ; 8 bits 1 1 | | | | | | ;Auto Enables <--------------------------+ | | | | | ;Enter Hunt Phase (not used) <---------------+ | | | | ;Rx CRC Enable <---------------------------------+ | | | ;Address Search Mode (not used) <--------------------+ | | ;SYNC Char Load Inhibit (not used) <---------------------+ | ;Rx Enable <---------------------------------------------+ ;WRITE REG 4: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;CLOCK MODE: | | | | | | | | ; X1 Clock Mode 0 0 | | | | | | ; X16 Clock Mode 0 1 | | | | | | ; X32 Clock Mode 1 0 | | | | | | ; X64 Clock Mode 1 1 | | | | | | ;SYNC MODE: (not used) | | | | | | ; 8 Bit Sync char 0 0 | | | | ; 16 Bit Sync char 0 1 | | | | ; SDLC Mode 1 0 | | | | ; Ext Sync mode 1 1 | | | | ;STOP BITS: | | | | ; SYNC Mode Enable 0 0 | | ; 1 Stop Bit/Char 0 1 | | ; 1.5 Stop Bits/Char 1 0 | | ; 2 Stop Bits/Char 1 1 | | ;PARITY: | | ; Parity Even/Odd <--------------------------------+ | ; Parity Enable <------------------------------------+ PAGE ;WRITE REG 5: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;DTR <---------------------------+ | | | | | | | ;Tx BITS/CHARACTER: | | | | | | | ; 5 Bits 0 0 | | | | | ; 6 Bits 0 1 | | | | | ; 7 Bits 1 0 | | | | | ; 8 Bits 1 1 | | | | | ;Send Break <--------------------------------+ | | | | ;Tx Enable <------------------------------------+ | | | ;CRC Type (not used) <-------------------------------+ | | ;RTS <---------------------------------------------------+ | ;Tx CRC Enable <---------------------------------------------+ ;WRITE REG 6: +---+---+---+---+---+---+---+---+ ; (not used) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Transmit Sync char A<------------+---+---+---+---+---+---+---+ ;WRITE REG 7: +---+---+---+---+---+---+---+---+ ; (not used) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Receive Sync char <------------+---+---+---+---+---+---+---+ PAGE ;SIO READ REGISTERS ;READ REG 0: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;Break/Abort <----------------+ | | | | | | | ;Tx Underrun/EOM <--------------------+ | | | | | | ;CTS <------------------------+ | | | | | ;Sync/Hunt <----------------------------+ | | | | ;DCD <--------------------------------+ | | | ;Tx Buffer Empty <------------------------------------+ | | ;Int Pending (Chan A only) <-----------------------------+ | ;Rx Character Available <------------------------------------+ ;READ REG 1: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;End of Frame <-----------------+ | | | | | | | ;CRC/Framing Error <-----------------+ | | | | | | ;Rx Overrun Error <---------------------+ | | | | | ;Parity Error <-----------------------------+ | | | | ;Residue codes (not used) <----------------------+---+---+  | ;All Sent <---------------------------------------------+ ;READ REG 2: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;Interrupt vector <--------------+---+---+---+---+---+---+---+ PAGE ;SIO Control constants REG0 = 0000_0000B ;Select register 0 REG1 = 0000_0001B ;Select register 1 REG2 = 0000_0010B ;Select register 2 REG3 = 0000_0011B ;Select register 3 REG4 = 0000_0100B ;Select register 4 REG5 = 0000_0101B ;Select register 5 REG6 = 0000_0110B ;Select register 6 REG7 = 0000_0111B ;Select register 7 INT_CNL = 0000_0000B ;Interrupt control (Reg 1) ; no interrupts RCV_CNL = 1110_0001B ;Logic control (Reg 3) ; 8 Bits/char, Auto enables on, Rx enable, ; Sync char hunt inhibit disabled BAS_CNL = 0100_0100B ;Basic control values (Reg 4) ; X16 Clock, 1 Stop bit, No parity TX_CNL_A = 1110_1000B ;Transmit control for (Reg 5) ; Channel A: DTR on, 8 Bits/char, RTS off TX_CNL_B = 1110_1010B ;Transmit control for (Reg 5) ; Channel B: DTR on, 8 Bits/char, RTS on SIO_I_IN = 000_10_111B ;Command to write to SIO WR1 to set: ; Interrupt on all Rx chars (parity ; affects vector) ; Status affects vector ; Tx Int. Enable ; External Int. Enable ;Masks SI.RRDY = 0000_0001B ;Receive char ready (Read Reg 0) SI.TRDY = 0000_0100B ;Transmit buffer empty (Read Reg 0) PAGE ;8253 TIMER ;CONTROL REG: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;Select Counter <----------------+---+ | | | | | | ;READ/LOAD: | | | | | | ;  Counter Latching 0 0 | | | | ; R/L Most Significant Byte only 0 1 | | | | ; R/L Least Significant Byte only 1 0 | | | | ; R/L Both Bytes 1 1 | | | | ;MODE <------------------------------------------+---+---+ | ;BCD <------------------------------------------------------+ ;Control COUNTA = 0011_0110B ;Select counter 0, 2 bytes, Mode 3 COUNTB = 0111_0110B ;Select counter 1, 2 bytes, Mode 3 ;SETBAUD Codes ; (Code is a table offset. Table entries are 8253 count values neccessary to produce the desired baud rate) BD1200 = 8 ;Code for 1200 baud PAGE ;PARALLEL PORT CONSTANTS ;port ctl register constants. PA.CDR = 00101010b ;to address port a direction PA.CDT = 00101110b ;to address port a data and set ;port a in input program handshake mode. PB.CDR = 00000000b ;to address port b direction PB.CDT = 00000100b ;toA address port b data ;direction register constants PA.DRO = 0FFh ;port a output mode PA.DRI = 00h ;port a input mode PB.DR = 0BFh ;port b direction PB.DTO = 00000010b ;port b data for output PB.DTI = 00001011b ;port b data for input PP.ORDY = 01000000b ;output rdy bit in pib PP.IRDY = 10000000b ;input rdy bit in pia ctl reg STRB = 00100000b ;strobe bit in port b ;port modes PP.OUT = 1 PP.IN = 2 ;IEEE control codes IE_TALK = 40h ;make talker IE_UTLK = 5Fh ;make untalk IE_LSTN = 20h ;make listener IE_ULST = 3Fh ;make unlisten PAGE ;VIDEO CONSTANTS FWAVM = 0C000h ;LVMEM = 128*23 + 80 ;Length of video memory ;VIDEND = FWAVM+LVMEM-1 ;End of video memory VMROWS = 24 ;24 Rows VMCOLS = 80 ;80 Columns RESERVED = 0 ;Window 0 is reserved (always set to full screen) ;NVDL = 24 ;LVDIS = 128*NVDL ;Length of Display memory ;VFLO = -22 ;First line video offset VLL = 128 ;Length of one video line ;VLDL = 64 ;Length of displayed char/line ;FWASM = FWAVM+VLDL ;Status info ;NLINE = 24 ;Number of lines MODEMSK = 0F0H ;Mask video mode bits MODEOFF = 1000H ;Offset from video character address to mode address ;MASKS REVMODE = 1000_0000B ;Reverse bit = high bit of character HAFMODE = 1000_0000B ;Half intensity bit = high bit of mode address UNDMODE = 0100_0000B ;Underline bit BLMODE = 0010_0000B ;Blink bit ALTMODE = 0001_0000B ;Alternate character set bit REV_CUR = 1000_0000B ;Reverse video (block) cursor UND_CUR = 0100_0000B ;Underline cursor INV_CUR = 0000_0000B ;Invisible cursor BLK_CUR = 0010_0000B ;Blinking cursor PAGE RTC_OFL = 18H ;RTC overflow counter port SIXTY_HZ = 60 ;Decimal 60 Hz (ticks/sec) FIFTY_HZ = 50 ;50 Hz (ticks/sec) SEC_MIN = 60H ;BCD seconds/minute MIN_HR = 60H ;minutes/hr HR_DAY = 24H ;Hours/day PAGE ;KEYBOARD CONSTANTS KL_LEN = 3 ;KEY LIST LENTH KLE_LEN = 2 ;KEY LIST ENTRY LENTH KL_USED = 7 ;KEYLIST ENTRY USED KY_SRVD = 6 ;KEY SERVICED ONCE KROW_M = 38H ;ROW NUMBER MASK KCOL_M = 7H ;COL NUMBER MASK RPTCTR = 1 ;REPEAT COUNT ROW0_M = 81H ;MASK FOR ADDRESSING ROW 0 DB_CT = 1 ;DEBOUNCE COUNT IRPTCT = 24 ;INITIAL REPEAT COUNT (400MS) SRPTCT = 3 ;SECOND REPEAT COUNT (100MS) DAB9/17 ;Reduced to half original value to ;speed repeat. TOT_ROW = 8 ;TOTAL ROWS TOT_COL = 8 CTL_KY = 2 ;COLUMN NUMBER OF CTL,ALPHA AND SHIFT KEYS ALPH_KY = 3 SHFT_KY = 4 PAGE ;BUFFER HANDLING EQUATES MX_CH_BF = 10H ;Max number of chars in a buffer BF_OV_HD = 4 ;No. bytes overhead in buffer D_RT_LEN = 6 ;No of bytes in Device List Root data structure NO_DEVS = 5 ;Number of devices NO_BUFS = 40 ;Number of buffers THR_HOLD = 4 ;Number of buffers to reserve for high priority ;devices HI_PRIOR = 80H ;High priority bit to indicate ;high priority buffers can be used PAGE ;CONTROL CHARACTERS CR = 0Dh ;^M, CR = Carriage Return LF = 0Ah ;^J, LF = Line Feed CRLF = '_'-40H ;^_, CR and LF BKS = 08h ;^H, Backspace CBELL: = 'G'-40h ;Ring the Bell MCUP: = 'K'-40h ;Move cursor up MCRIGH: = 'L'-40h ;Move cursor right VDWN: = 'V'-40H ;Move cursor down VLIN: = '_'-40H ;New line (CR,LF) VCLRS: = 'Z'-40h ;Clear and home cursor VHOME: = '^'-40h ;Home Cursor ETX = 'C' - 40h ;ASCII ETX char ACK = 'F' - 40h ;ASCII ACK char XON = 'Q' - 40h ;ASCII XON (DC1) char XOFF = 'S' - 40h ;ASCII XOFF (DC3) char ;ESCAPE SEQUENCE CHARACTERS ESC = 1Bh ;^[, ESC = Escape VLOCK: = '#' ;Lock Keyboard VUNLK: = '"' ;Unlock Keyboard VCAD: = '=' ;Cursor Addressing VSAD: = 'S' ;Screen Addressing VINC: = 'Q' ;Insert Char VDELC: = 'W' ;Delete char VINL: = 'E' ;Insert line VDELL: = 'R' ;Delete line VCEOL: = 'T' ;Clear to end of line VCEOS: = 'Y' ;Clear to end of screen (window) VSAL: = 'a' ;Start alternate character set VEAL: = 'A' ;End VSHI: = ')' ;Start half intensity VEHI: = '(' ;End VSGH: = 'g' ;Start graphics VEGH: = 'G' ;End VRON: = 'b' ;Set reverse video background (black on white) VROFF: = 'd' ;Clear reverse video background (set to white on black) VCTYP: = '.' ;Cursor type define VSRV: = 'j' ;Start reverse video VERV: = 'k' ;End reverse video VSUL: = 'l' ;Start underline VEUL: = 'm' ;End underline VSBL: = '^' ;Start Blink VEBL: = 'q' ;End blink EKC: = '>' ;Enable key click DKC: = '<' ;Disable key click EFKT: = 'e' ;Enable function key translate DFKT: = 'f' ;Disable Function key translate VWDEF: = 'z' ;Window define VWSET: = 's' ;Window set VOFF: = 'o' ;Define X-Y offset VBACK: = 'x' ;Define background attributes UNDBIT: = 0000_1000B ;Underline bit ALTBIT: = 0001_0000B ; REVBIT: = 0000_0100B ;Reverse video bit BLKBIT: = 0000_0010B ;Blink bit HAFBIT: = 0000_0001B ;Half intensity bit PAGE ;BOOT CONSTANTS BOOTADDR: = 4000H ;Boot load address for P-System BIOSBANK = 0000_0000B ;BIOS bank BOOTBANK = 0000_0000B ;Boot strap loader bank TEMPBUF = 0CC00H ;Temporary buffer in video bank A ; used for DMA address when booting system PROD_CODE = 2 ;Shelly product code written on boot sector PAGE ;INTERRUPT CONSTANTS SIO_I_TBL = 0FFE0H ;Location in RAM of SIO interrupt vector ;Must be in high RAM and end in 0 INTVEC = 0FFFEH ;Other interrupt's vector ;Interrupt Device Numbers KBD_DEV = 0 ;Keyboard device number S_CH_A_I = 1 ;Device number for Serial channel A input S_CH_B_I = 2 ;Device number for Serial channel B input S_CH_A_O = 3 ;Device number for Serial channel A output S_CH_B_O = 4 ;Device number for Serial channel B output PAGE ;ROM's RAM VALUES ;Flags for console and function key table flags SYS_TBL: = 0 ;Use system table APP_TBL: = 1 ;Use application table NO_TBL: = 2 ;Don't use translation table (function key only) PAGE ;TABLE DEFINITION LOCATIONS ;SYSTEM TRACK LOCATIONS KCTRK = 2 ;Track for keyboard and character font definitions KEYSEC = 17 ;Sector for keyboard definition CHARSEC = 20 ;Sector for character font definition ALTSEC = 30 ;Sector for alternate character font definition ;RAM LOCATIONS RAMTBL = 2000H ;Keyboard and console table pointers CHRFONT = 0000H ;Character font RAM location ALTFONT = 800H ;Alternate character font RAM location PAGE ; CP/M DEFINITIONS SVER = 14 ERSIZE = 64 ; default = 64k version CVER = 22 ;CPM version number CBIOSV = SVER ;cbios version NDSKS = 2 K = 1024 ABTC = 'C'-40h ;Abort character ;DRIVE DEFINITIONS LSECB = 256 ;Length of a sector MTRK = 40 ;Maximum tracks MSEC = 10 ;Maximum Sectors FMTCHR = 0E5h ;Data format char ; Set CP/M symbols. IOBYTE = 3 CDISK = 4 ;Current logged-in CPM disk SYS = 5 ;CPM Monitor call address SYSL = SYS+1 ;(lwa of CP/m) TIMPTR = 40h ;points to where time kept DBUF = 80h ;Default disk buffer OM#LRAM = SYSL SYSR = 0 ;return to system SYSDSK = CDISK ;Contains current system disk # SYSDAT = 10h ;Date in ddmmyy SYSTIM = SYSDAT+3 ;Time in hhmmss ORGP = 100h ;Transient program origin ;EOL ;does not exist in CP/M EOM = '$' ;End of Message (for system function) EOF = 'Z'-40h ;End of File L$PRU = 128 ;Bytes per floppy sector FCB = 5Ch ;SYSTEM DEFAULT FILE CONTROL BLOCK FCB_NR = FCB+32 ;Next Record = LRN F_EX = 12 ;Extend field F_S2 = 14 ;CPM system usage **used with 2.0 SIZ funct** F_RC = 15 ;Record count (0 to 128) F_NR = 32 ;Next record ordinal in FCB F_RRF = 33 ;r0,r1,r2 (random field) in FCB L_FILEN = 8 ;length of File name L_FILEX = 3 ;length of filename suffix L_FCB = 36 ;length of entire FCB (comp with 2.0) DMA = 80h ;WHERE SECTORS ARE READ TBUFF = DMA ;where CCP puts command line PAGE ; FIRMWARE RAM DEFINITIONS ;TEMPBUF: = HSTBUF ;* TEMPBUF WILL BE THE SAME AREA AS THE SPACE ; RESERVED FOR KEYBOARD AND CONSOLE TABLES -- ; IT CAN ONLY BE USED BEFORE THESE AREAS ARE INITIALIZED PAGE ; True/False definitions FALSE = 0 TRUE = not FALSE ; Defined function codes ROMVEC = 100h ;Start of rom vector MONRAM = 2000H COMJMP = 0FD40H ;Common memory jump vectors (BANKJMP,BANKMOVE,BANKCALL,DMA READ and WRITE) MRAM = 0FD4Ah ;High memory area for variables used by ROM and BIOS HI_ROUT = 0FEF0H ;High memory routines moved from ROM TAB = 09h ;TAB ERC = 7FH ;Illegal key @FREQ = 4000 ;freq of processor SCLFRE = @FREQ/22 ;for DELAY routine Bad = 0FFH ;Entry in keybd table if key is invalid BADKEY = Bad ; TOG_ALT_SET = 0FEh ;Entry in keybd table if key is used to ;toggle alternate char set KEYTBL: = 2800H-140H ;Key code location ROMVER: = 0FEH ;ROM version number location ;Cold Boot Masks SP_KEY = 0000_0100b ;Load keyboard translation code from disk SP_CHAR = 0000_0010B ;Load character font from disk SP_ALT = 0000_0001B ;Load alternate character font from disk PAGE ;MACROS ; ALIGN Set origin to even boundary. ALIGN MACRO SIZ,O DS (*%2+(%1)-1)/(%1)*(%1)-*%2  ENDM PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; Endx SYSTEXT PAGEH~O I!K>w:JͨJH2LF4IO.K5FJͿJKH:L!LSKFJ: GFͮHFH:LL͛IGͳGI:L< G=!LwW*LMI_SG G-*LMD:I"L:L2Lɯ2LK>G=O*L~~w#~2L~wcIH~K~p2L!"L>2L*L~=2LK~2L͛KoK>*Lw!"L2L=2L!"LÛI͛KoK͢K͢J'LͫIH~<7Lw@ͩK7K:LF"LÛI:L~L:L2L:L~L*L6:LpLw#:LwH:Lw*@F* G}DVSNNNPP(? ```P>LI$DD*LL*LTM:L_2L{2L"LrI"L[MM?G,MdM>lM[MIG6:L<!=6M*LJM"L*LKN:LG/O*LL*LG=GdM##LIGADDR IN SYS_DTA ;Get TPA bank STO A,DMA_BANK ;and save it as DMA bank ;Main loop for reading or writing next Track LDK A,1 STO A,SAVSEC ;set sector *SET "SAVTYP" AND GET NUMBER OF SECTORS PER TRACK CALL SENDEN ;SENCE DENSITY AND SET SAVTYP JRNZ :ERR1 ;IF ERROR PUSH BC ;SAVE NUMBER OF SECTORS IN ONE TRACK ;CHECK FOR VALID FORMAT AND SET D = NUMBER OF 128 BYTE SECTORS TO READ CALL CHKTYP POP BC JRNZ :ERR3 ;IF INVALID FORMAT (ERROR MESSAGE ALREADY PRINTED) MOV A,D ;Check for dsdd 841001 CPI DSTYP ;Is it dsdd? 841001 JRNZ :NODSDD ;No... 841001 ; CALL DSGTPT ;Yes... call dsdd routine 841001 RET ;and return 841001 *SET NUMBER OF SECTORS TO READ :NODSDD: PUSH BC LD A,SAVTYP SRL A SRL A ANI 0000_0011B ;A=NUMBER OF BYTES IN ONE SECTOR(0-3) JRZ :2 ;IF 128 BYTES SECTORS ;GET NUMBER TO DIVIDE BY MOV B,A ;B=NUMBER OF BYTES IN ONE SECTOR(1-3) LDK A,1 :1LOOP: SLA A ;TIMES TWO DJNZ :1LOOP MOV B,A ;NUMBER TO er CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window CALL SET_M2 ;Set menu 2 RET PAGE :RD_ERR: ;Hard read error occurred. LK HL,F_RD_ERR ;Display message CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET PAGE PUTSYS: ;Now put the system on user requested disk PROC :1: STO A,PDISK2 ;SET DRIVE letter STO A,PDISK3 ;in messages SUI 'A' STO A,SDISK ;and in data structures INC A ;Bump to be relative 1 STO A,DSTFCB ; CALL CLR_W_2 ;Clear message window ;Write system track image to destination diskette: :WR_SYS: LDK HL,RW ;Set read/write flag to write. STO 1,[HL] CALL GETPUT ;TO PUT SYSTEM BACK ON DISKETTE RNZ ;TRY AGAIN IF ERROR ;Write CPM3.SYS file to destination drive LK C,0DH ;Reset disk system CALL SYS XOR A STO A,DSTFCB+12 ;Clear extent byte of dest FCB LK DE,DSTFCB ;See if file exists already LK C,0FH CALL SYS INC A ;(A <> 255) JNZ :EXISTS ;File exists already...  ; XOR A ;Check for hard error. Clear A OR H ;Is H zero? JNZ :WR_ERR ;No... hard err ; JMP :NO_DEST ;A = 255 and H = 0. No file on dest disk. ; :EXISTS: LK HL,DELMSG ;Destination file exists, ask CALL OSTR ;user if it should be overwritten :G_ANS: CALL Y_N ;Get user response: Y or N CMP 'N' JNZ :CONT ;Yes... ; ;No. ;User doesn't want to delete old file. CALL CLR_W_2 ;Clear message window RET ;and return to driver ; :CONT: ;Delete old CPM3.SYS LD A,DSTFCB+9 ;Set dest file R/W and DIR AND 7FH STO A,DSTFCB+9 LD A,DSTFCB+10 AND 7FH STO A,DSTFCB+10 LK DE,DSTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; L DE,DSTFC ;Delet destinatio file L C,13H CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; :NO_DEST: ;No conflicting file on destination drive LK DE,DRVSPC ;Set DMA address to scratch area LK C,1AH ;for drive space calculation CALL SYS LD A,DSTFCB ;Check for sufficient space on destination ;drive DEC A ;Decr drive # to be relative 0 MOV E,A ;Get drive spec from FCB LK C,2EH CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; LK B,3 ;See if space left is => file size (left in LK DE,SRCFCB+35 ;source file FCB) LK HL,DRVSPC+2 ; CALL CMP_N_STR ; JC :SUFF_SPC ;Sufficient space available ; JZ :SUFF_SPC ;Ditto... ; LK HL,NSF_SPC ;Insufficient space. Display message CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET ; :SUFF_SPC: ;Sufficient space. Write output file XOR A STO A,DSTFCB+12 ;Clear extent byte of dest FCB LK DE,DSTFCB ;Create output file LK C,16H CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; XOR A ;Clear current record byte of FCB STO A,DSTFCB+32 LD A,BLKCNT ;Get number of blocks to transfer MOV B,A ;Put it in A LK DE,FILEBUFF ;Set DMA to beginning of buffer :WR_LP: XOR A OR B ;Any 16 K blocks left? JZ :WR_REM ;No, write remainder ; PUSH BC ;Save block count PUSH DE ;Save DMA address LK C,1AH ;Set DMA address CALL SYS LK E,128 ;Set multi sector count to 128 LK C,2CH CALL SYS CALL WR_BUFF ;Write current 16 K block POP DE ;Restore DMA addr POP BC ;and block count JNZ :WR_ERR ;Write error? LK HL,128*128 ;Bump DMA addr another 16 K ADD HL,DE EX HL,DE ;Put it in DE DEC B ;Decrement block counter JMP :WR_LP ;Loop again ; :WR_REM: ;All full 16K blocks written, write ;remainder LD A,REMCNT ;Get number of remaining 128 byte sectors OR A ;Is it zero? JZ :CLS_CPM3 ;Yes, no remaining records to write: close file ; ;No, write remainder PUSH DE ;Save DMA address MOV E,A ;Yes, set multi sector count LK C,2CH CALL SYS POP DE ;Restore DMA address LK C,1AH ;Set BDOS DMA address CALL SYS CALL WR_BUFF JNZ :WR_ERR ;Write error? ; ; No errors, close filAe and write system tracks ; :CLS_CPM3: ;Output file written, now close it LK DE,DSTFCB LK C,10H CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; LD A,DSTFCB+9 ;Set dest file R/O and SYS OR 80H STO A,DSTFCB+9 LD A,DSTFCB+10 OR 80H STO A,DSTFCB+10 LK DE,DSTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS INC A ;Check for error (A = 255) JZ :WR_ERR ;Hard error... ; LD A,DSTFCB+9 ;Reset dest file attributes to R/W and DIR. AND 7FH ;If attributes are not reset, any attempt STO A,DSTFCB+9 ;to create a new destination file (on another ;diskette, perhaps) results in a CP/M Error: LD A,DSTFCB+10 ;File Read/Only message. This is due to the AND 7FH ;file being created with the R/O attribute set. STO A,DSTFCB+10 LK HL,DONE CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET ;FOR ANOTHER PUT OPERATION PAGE :WR_ERR: ;Write error occurred in writing CPM3.SYS LD A,DSTFCB+9 ;Set dest file R/W and DIR AND 7FH STO A,DSTFCB+9 LD A,DSTFCB+10 AND 7FH STO A,DSTFCB+10 LK DE,DSTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS ;No check for error, since we're going to ;display an error message anyway L DE,DSTFC ;Delet destinatio file L C,13H CALL SYS ;No check for error, since we're going to ;display an error message anyway LK HL,W_ERR_MS ;Write error: display message CALL OSTR CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window RET PAGE CMP_N_STR: ; Utility subroutine to compare 2 numerical byte strings ; of equal length. Strings are stored with their least significant ; byte in low memory. ; ; ENTRY: ; B = Length of strings ; DE ==> Most Significant Byte of string 1 ; HL ==> MSB of string 2 ; ; EXIT: ; Z bit set if String 1 = String 2 ; C Bit set if String 1 < String 2 ; (i.e., flags are set just as if a single byte compare were done.) ; PROC :COMP_LP: LD A,[DE] ;Load byte of str 1 CMP [HL] ;Compare with byte of str 2 RNZ ;Return if bytes different: C set ;accordingly ; DEC B ;Is this the last byte? RZ ;Yes, return with Z set ; DEC DE ;No, check next byte DEC HL JMP :COMP_LP PAGE Y_N: ; Get Y or N response from keyboard PROC :YNLP: CALL CIN AND 5FH CMP 'Y' JZ :ECHO ; CMP 'N' JNZ :YNLP ; :ECHO: PUSH AF ;Echo char in A CALL OCHR POP AF RET PAGE WAIT_CR: ; Wait for user to enter carriage return PROC :CR_LP: CALL CIN ;Get a char CMP CR ;Is it carriage return? JRNZ :CR_LP ;No, get another ; RET ;Yes, return. PAGE CLR_W_2: ; Clear window 2 LK HL,:CLS CALL OSTR RET ; :CLS: DB ESC,'s2','Z'-40h,0 WR_BUFF: ; Routine to perform sequential to destination file LK DE,DSTFCB ; LK C,15H CALL SYS OR A ;Set Z bit if no error RET PAGE GETPUT: ;Get or PUT cpm onto disk requested ;ENTRY ;RW = 0 if read, 1 if WRITE ;EXIT ;ZBIT = RESET IF ERROR proc :1: LDK HL,SYS_BUFF STO HL,DMADR ;SET DMA ADDR IN SYS_DTA ;Get TPA bank STO A,DMA_BANK ;and save it as DMA bank ;Main loop for reading or writing next Track LDK A,1 STO A,SAVSEC ;set sector *SET "SAVTYP" AND GET NUMBER OF SECTORS PER TRACK CALL SENDEN ;SENCE DENSITY AND SET SAVTYP JRNZ :ERR1 ;IF ERROR PUSH BC ;SAVE NUMBER OF SECTORS IN ONE TRACK ;CHECK FOR VALID FORMAT AND SET D = NUMBER OF 128 BYTE SECTORS TO READ CALL CHKTYP POP BC JRNZ :ERR3 ;IF INVALID FORMAT (ERROR MESSAGE ALREADY PRINTED) MOV A,D ;Check for dsdd 841001 CPI DSTYP ;Is it dsdd? 841001 JRNZ :NODSDD ;No... 841001 ; CALL DSGTPT ;Yes... call dsdd routine 841001 RET ;and return 841001 *SET NUMBER OF SECTORS TO READ :NODSDD: PUSH BC LD A,SAVTYP SRL A SRL A ANI 0000_0011B ;A=NUMBER OF BYTES IN ONE SECTOR(0-3) JRZ :2 ;IF 128 BYTES SECTORS ;GET NUMBER TO DIVIDE BY MOV B,A ;B=NUMBER OF BYTES IN ONE SECTOR(1-3) LDK A,1 :1LOOP: SLA A ;TIMES TWO DJNZ :1LOOP MOV B,A ;NUMBER TO DIVIDE BY MOV A,D ;A=NUMBER OF 128 BYTE BLOCKS LDK D,0 :2LOOP: SUB B ;SUBTRACK WITH DIVISOR PUSH AF ;Save flags INC D ;COUNT POP AF ;Restore flags JRZ :2 ;IF REZULT IS ZERO (NO PARTIAL SECTORS) JRNC :2LOOP ;LOOP :2: POP BC ;B=NUMBER OF SECTORS IN ONE TRACK MOV C,D ;C=NUMBER OF SECTORS TO READ *READ SYSTEM XRA A ;A=0 :TLOOP: STO A,SAVTRK ;SET TRACK ;CHECK FOR ALL SECTORS READ MOV A,C ;SECTORS TO READ ORA A RZ ;IF C IS ZERO YOUR DONE ;UPDATE NUMBER OF SECTORS LEFT TO READ SUB B ;SUBTRACK SECTORS IN ONE TRACK JRNC :3 ;A>B MORE THAN ONE TRACK LEFT TO READ ;IF THIS IS LAST TRACK ZERO NUMBER OF SECTORS LEFT TO READ MOV B,C ;READ ALL THE REMAINING SECTORS XRA A ;STOP AFTER THIS READ ;R/W ONE TRACK :3: MOV C,A ;SAVE REMAINING SECTORS TO READ PUSH BC ;Save BC around call to READ and WRITE LD A,RW ORA A JRZ :4 ;IF READ CALL WRITE ;WRITE POP BC ;Restore BC JRNZ :ERR1 ;IF ERROR JR :5 ;SKIP READ IF WRITE A :4: CALL READ ;READ POP BC ;Restore BC JRNZ :ERR1 ;IF ERROR ;UPDATE DMA :5: STO HL,DMADR ;SET DMA ;UPDATE TRACK LD A,SAVTRK INC A JR :TLOOP ;TRACK LOOP :ERR1: LD A,RW ORA A LDK HL,WRERR JRNZ :ERR2 LDK HL,READERR :ERR2: CALL OSTR :ERR3: CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window ORI 0FFH RET ;RETURN ERROR PAGE CHKTYP: ;CHECK FOR VALID FORMAT FOR SYSGEN ; For Shelly, only OCC Double Density disks can be used as system 2.21 ; disks 2.21 ; ; Allows Vixen compatible dsdd. Returns DSTYP if disk is dsdd 841001 ; ;ENTRY ;SAVTYP SET ;B = NUMBER OF SECTORS ;EXIT ;Z RESET IF NOT VALID ;D = NUMBER OF 128 BYTE BLOCKS IN SYSTEM or DSTYP if DSDD 841001 PROC LDK HL,SAVTYP LD A,[HL] ;GET TYPE ;CHECK FOR OSBORNE DOUBLE DENSITY CMP DOUBTYP ;Is disk double density and 1024 byte sectors? 2.21 JNZ :CKDS ;No...Check dsdd 841001 ; ;Yes MOV A,B ;Is Sectors/Track = 5 (OCC DD)? 2.21 CMP DOUBSEC ;  2.21 JNZ :DERR ;No...Indicate error 2.21 ; LK D,N128BS ;Yes. Return B = # 128 byte blocks in system 2.21 RET ;and return with Z set 2.21 ; :CKDS: CMP DSTYP ;Check for dsdd 841001 JNZ :DERR ;No, error 841001 ; MOV A,B ;Is sectors/trk 5? 841001 CMP DSSEC ; 841001 JNZ :DERR ;No, error 841001 ; LK D,DSTYP ;Return DSTYP 841001 RET ; 841001 :DERR: LK HL,DENSERR ;Display error message 2.21 CALL OSTR ; 2.21 OR 0FFH ;and return with Z clear 2.21 RET ; 2.21 PAGE DSGTPT: ; 841001 ; OS get/put routine for dsdd disk. ; ; On get, Reads boot data on track 0 (side 0 and 1) and puts it in841001 ; buffer in same place as ssdd disk. Reads CCP.COM and ALTFONT.SYS841001 ; files and places them, too. 841001 ; ; On write, writes boot data from appropriate places in buffers, 841001 ; writes CCP.COM and ALTFONT.SYS. Error results if insufficient 841001 ; space on destination disk. 841001 ; ; This is done so that a ssdd disk can be written straight away, 841001 ; right out of the buffer. 841001 ; ; Entry: ; SDISK contains drive (0 for A, 1 for B). ; RW = 1 for write, 0 for read. ; ; Exit: ; Buffer contains sys trk data in ssdd format. ; Z flag is reset if error occurred. ; PROC XOR A ;Set trk to 0 841001 STO A,SAVTRK ; 841001 INC A ;Set sec to 1 841001 STO A,SAVSEC ; 841001 LK HL,SYS_BUFF ;Set DMA addr 841001 STO HL,DMADR ; 841001 IN SYS_DTA ;Set DMA bank 841001 STO A,DMA_BANK ; 841001 LD A,SAVTYP ;Set side 0 841001 CBIT 1,A ; 841001 STO A,SAVTYP ; 841001 LK B,5 ;Read/write all sectors on trk 0, side 0841001 CALL :RW ;Do read or write 841001 JNZ :RWERR ;Check for err 841001 LK HL,OURSEC ;Point at buffer for SETUP override 841001 STO HL,DMADR ;Set DMA 841001 LK A,1 ;Set sec to 1 841001 STO A,SAVSEC ; 841001 LD A,SAVTYP ;Set side 1 841001 SBIT 1,A ; 841001 STO A,SAVTYP ;  841001 LK B,1 ;One sector 841001 CALL :RW ;I/O 841001 JNZ :RWERR ;Check for err 841001 LK HL,FONTM ;Set DMA for main font 841001 STO HL,DMADR ; 841001 LK A,2 ;Sec = 2 841001 STO A,SAVSEC ; 841001 LK B,2 ;2 sectors 841001 CALL :RW ;I/O 841001 JNZ :RWERR ;Check for err 841001 LK HL,ROMRAM ;Point at buffer for ROM's RAM override 841001 STO HL,DMADR ;Set DMA 841001 LK A,4 ;Set sec to 4 841001 STO A,SAVSEC ; 841001 LK B,1 ;One sector 841001 CALL :RW ;I/O 841001 JNZ :RWERR ;Check for err 841001 ; ; Now read in / write out CCP.COM and ALTFONT.SYS ; If ALTFONT.SYS doesn't exist on read, copy the main font. ; ; Do this for read or write: ; LK C,0DH ;Reset disk system CALL SYS LD A,SDISK ;Get source disk drive # INC A ;Increment to make relative 1 for CP/M STO A,CCPDR ;Stuff into CCP.COM fcb STO A,ALTDR ;and alternate font fcb XOR A ;Clear extent byte, rec cnt, cur rec  STO A,CCPFCB+12 ;in both fcbs STO A,CCPFCB+15 ; STO A,CCPFCB+32 ; STO A,ALTFCB+12 ; STO A,ALTFCB+15 ; STO A,ALTFCB+32 ; LD A,RW ;Load read/wr flag OR A ; JNZ :WRF ;Write... LK DE,CCPFCB ;Point at fcb LK C,15 ; CALL SYS ;Call BDOS open INC A ;Returns A=255 if not home JZ :NOCCP ;Oops, no ccp ; LK BC,CCPBUFF ;Point at ccp buffer, LK DE,CCPFCB ;ccp fcb LK HL,32 ;Specify 32 128-byte sectors (4K) CALL :FILERW ;I/O it JNZ :CCPERR ;Oops, error LK DE,CCPFCB ;Close it LK C,16 CALL BDOS OR A ;Check for err JNZ :CCPERR ; LK DE,ALTFCB ;Point at fcb LK C,15 ; CALL SYS ;Call BDOS open INC A ;Returns A=255 if not home JNZ :RDALT ;Read alt font... ; LK HL,FONTM ;Point at main font LK DE,FONTA ;and alternate LK BC,2*1024 ;2K LDIR ;Move it XOR A ; RET ;Return z set-no error ; :RDALT: LK BC,FONTA ;Point at alt font buffer, LK DE,ALTFCB ;alt font fcb LK HL,16 ;Specify 16 128-byte sectors (2K) CALL :FILERW ;I/O it JNAZ :ALTERR ;Oops, error ; LK DE,ALTFCB ;Close it LK C,16 CALL BDOS OR A ;Check for err JNZ :ALTERR RET ;Everything ok, return with z set :WRF: ; Write the files. ; See if it's there already: LK DE,CCPFCB ;Point at fcb LK C,15 ; CALL SYS ;Call BDOS open INC A ;Returns A=255 if not home PUSH AF ;Save return value while we set FCB 841022 ;R/W and DIR 841022 LD A,CCPFCB+9 ;Set dest file R/W and DIR AND 7FH STO A,CCPFCB+9 LD A,CCPFCB+10 AND 7FH STO A,CCPFCB+10 POP AF ;Restore returned value from FCB 841022 JRZ :NOC ;no ccp 841022 ; LK DE,CCPFCB ;Call BDOS to set attributes LK C,1EH CALL SYS INC A ;Check for error (A = 255) JZ :FWERR ;Hard error... ; LK DE,CCPFCB ;Point at it LK C,19 ; CALL SYS ;Delete it INC A ;Check for err JZ :FWERR ;Yes... ; :NOC: LK DE,ALTFCB ;Point at fcb LK C,15 ; CALL SYS ;Call BDOS open INC A ;Returns A=255 if not home PUSH AF ;Save return value while we set FCB 841022DIVIDE BY MOV A,D ;A=NUMBER OF 128 BYTE BLOCKS LDK D,0 :2LOOP: SUB B ;SUBTRACK WITH DIVISOR PUSH AF ;Save flags INC D ;COUNT POP AF ;Restore flags JRZ :2 ;IF REZULT IS ZERO (NO PARTIAL SECTORS) JRNC :2LOOP ;LOOP :2: POP BC ;B=NUMBER OF SECTORS IN ONE TRACK MOV C,D ;C=NUMBER OF SECTORS TO READ *READ SYSTEM XRA A ;A=0 :TLOOP: STO A,SAVTRK ;SET TRACK ;CHECK FOR ALL SECTORS READ MOV A,C ;SECTORS TO READ ORA A RZ ;IF C IS ZERO YOUR DONE ;UPDATE NUMBER OF SECTORS LEFT TO READ SUB B ;SUBTRACK SECTORS IN ONE TRACK JRNC :3 ;A>B MORE THAN ONE TRACK LEFT TO READ ;IF THIS IS LAST TRACK ZERO NUMBER OF SECTORS LEFT TO READ MOV B,C ;READ ALL THE REMAINING SECTORS XRA A ;STOP AFTER THIS READ ;R/W ONE TRACK :3: MOV C,A ;SAVE REMAINING SECTORS TO READ PUSH BC ;Save BC around call to READ and WRITE LD A,RW ORA A JRZ :4 ;IF READ CALL WRITE ;WRITE POP BC ;Restore BC JRNZ :ERR1 ;IF ERROR JR :5 ;SKIP READ IF WRITE  :4: CALL READ ;READ POP BC ;Restore BC JRNZ :ERR1 ;IF ERROR ;UPDATE DMA :5: STO HL,DMADR ;SET DMA ;UPDATE TRACK LD A,SAVTRK INC A JR :TLOOP ;TRACK LOOP :ERR1: LD A,RW ORA A LDK HL,WRERR JRNZ :ERR2 LDK HL,READERR :ERR2: CALL OSTR :ERR3: CALL WAIT_CR ;Wait for RETURN CALL CLR_W_2 ;Clear message window ORI 0FFH RET ;RETURN ERROR PAGE CHKTYP: ;CHECK FOR VALID FORMAT FOR SYSGEN ; For Shelly, only OCC Double Density disks can be used as system 2.21 ; disks 2.21 ; ; Allows Vixen compatible dsdd. Returns DSTYP if disk is dsdd 841001 ; ;ENTRY ;SAVTYP SET ;B = NUMBER OF SECTORS ;EXIT ;Z RESET IF NOT VALID ;D = NUMBER OF 128 BYTE BLOCKS IN SYSTEM or DSTYP if DSDD 841001 PROC LDK HL,SAVTYP LD A,[HL] ;GET TYPE ;CHECK FOR OSBORNE DOUBLE DENSITY CMP DOUBTYP ;Is disk double density and 1024 byte sectors? 2.21 JNZ :CKDS ;No...Check dsdd 841001 ; ;Yes MOV A,B ;Is Sectors/Track = 5 (OCC DD)? 2.21 CMP DOUBSEC ;  2.21 JNZ :DERR ;No...Indicate error 2.21 ; LK D,N128BS ;Yes. Return B = # 128 byte blocks in system 2.21 RET ;and return with Z set 2.21 ; :CKDS: CMP DSTYP ;Check for dsdd 841001 JNZ :DERR ;No, error 841001 ; MOV A,B ;Is sectors/trk 5? 841001 CMP DSSEC ; 841001 JNZ :DERR ;No, error 841001 ; LK D,DSTYP ;Return DSTYP 841001 RET ; 841001 :DERR: LK HL,DENSERR ;Display error message 2.21 CALL OSTR ; 2.21 OR 0FFH ;and return with Z clear 2.21 RET ; 2.21 PAGE DSGTPT: ; 841001 ; OS get/put routine for dsdd disk. ; ; On get, Reads boot data on track 0 (side 0 and 1) and puts it in841001 ; buffer in same place as ssdd disk. Reads CCP.COM and ALTFONT.SYS841001 ; files and places them, too. 841001 ; ; On write, writes boot data from appropriate places in buffers, 841001 ; writes CCP.COM and ALTFONT.SYS. Error results if insufficient 841001 ; space on destination disk. 841001 ; ; This is done so that a ssdd disk can be written straight away, 841001 ; right out of the buffer. 841001 ; ; Entry: ; SDISK contains drive (0 for A, 1 for B). ; RW = 1 for write, 0 for read. ; ; Exit: ; Buffer contains sys trk data in ssdd format. ; Z flag is reset if error occurred. ; PROC XOR A ;Set trk to 0 841001 STO A,SAVTRK ; 841001 INC A ;Set sec to 1 841001 STO A,SAVSEC ; 841001 LK HL,SYS_BUFF ;Set DMA addr 841001 STO HL,DMADR ; 841001 IN SYS_DTA ;Set DMA bank 841001 STO A,DMA_BANK ; 841001 LD A,SAVTYP ;Set side 0 841001 CBIT 1,A ; 841001 STO A,SAVTYP ; 841001 LK B,5 ;Read/write all sectors on trk 0, side 0841001 CALL :RW ;Do read or write 841001 JNZ :RWERR ;Check for err 841001 LK HL,OURSEC ;Point at buffer for SETUP override 841001 STO HL,DMADR ;Set DMA 841001 LK A,1 ;Set sec to 1 841001 STO A,SAVSEC ; 841001 LD A,SAVTYP ;Set side 1 841001 SBIT 1,A ; 841001 STO A,SAVTYP ; A 841001 LK B,1 ;One sector 841001 CALL :RW ;I/O 841001 JNZ :RWERR ;Check for err 841001 LK HL,FONTM ;Set DMA for main font 841001 STO HL,DMADR ; 841001 LK A,2 ;Sec = 2 841001 STO A,SAVSEC ; 841001 LK B,2 ;2 sectors 841001 CALL :RW ;I/O 841001 JNZ :RWERR ;Check for err 841001 LK HL,ROMRAM ;Point at buffer for ROM's RAM override 841001 STO HL,DMADR ;Set DMA 841001 LK A,4 ;Set sec to 4 841001 STO A,SAVSEC ; 841001 LK B,1 ;One sector 841001 CALL :RW ;I/O 841001 JNZ :RWERR ;Check for err 841001 ; ; Now read in / write out CCP.COM and ALTFONT.SYS ; If ALTFONT.SYS doesn't exist on read, copy the main font. ; ; Do this for read or write: ; LK C,0DH ;Reset disk system CALL SYS LD A,SDISK ;Get source disk drive # INC A ;Increment to make relative 1 for CP/M STO A,CCPDR ;Stuff into CCP.COM fcb STO A,ALTDR ;and alternate font fcb XOR A ;Clear extent byte, rec cnt, cur rec  STO A,CCPFCB+12 ;in both fcbs STO A,CCPFCB+15 ; STO A,CCPFCB+32 ; STO A,ALTFCB+12 ; STO A,ALTFCB+15 ; STO A,ALTFCB+32 ; LD A,RW ;Load read/wr flag OR A ; JNZ :WRF ;Write... LK DE,CCPFCB ;Point at fcb LK C,15 ; CALL SYS ;Call BDOS open INC A ;Returns A=255 if not home JZ :NOCCP ;Oops, no ccp ; LK BC,CCPBUFF ;Point at ccp buffer, LK DE,CCPFCB ;ccp fcb LK HL,32 ;Specify 32 128-byte sectors (4K) CALL :FILERW ;I/O it JNZ :CCPERR ;Oops, error LK DE,CCPFCB ;Close it LK C,16 CALL BDOS OR A ;Check for err JNZ :CCPERR ; LK DE,ALTFCB ;Point at fcb LK C,15 ; CALL SYS ;Call BDOS open INC A ;Returns A=255 if not home JNZ :RDALT ;Read alt font... ; LK HL,FONTM ;Point at main font LK DE,FONTA ;and alternate LK BC,2*1024 ;2K LDIR ;Move it XOR A ; RET ;Return z set-no error ; :RDALT: LK BC,FONTA ;Point at alt font buffer, LK DE,ALTFCB ;alt font fcb LK HL,16 ;Specify 16 128-byte sectors (2K) CALL :FILERW ;I/O it JNZ :ALTERR ;Oops, error ; LK DE,ALTFCB ;Close it LK C,16 CALL BDOS OR A ;Check for err JNZ :ALTERR RET ;Everything ok, return with z set :WRF: ; Write the files. ; See if it's there already: LK DE,CCPFCB ;Point at fcb LK C,15 ; CALL SYS ;Call BDOS open INC A ;Returns A=255 if not home PUSH AF ;Save return value while we set FCB 841022 ;R/W and DIR 841022 LD A,CCPFCB+9 ;Set dest file R/W and DIR AND 7FH STO A,CCPFCB+9 LD A,CCPFCB+10 AND 7FH STO A,CCPFCB+10 POP AF ;Restore returned value from FCB 841022 JRZ :NOC ;no ccp 841022 ; LK DE,CCPFCB ;Call BDOS to set attributes LK C,1EH CALL SYS INC A ;Check for error (A = 255) JZ :FWERR ;Hard error... ; LK DE,CCPFCB ;Point at it LK C,19 ; CALL SYS ;Delete it INC A ;Check for err JZ :FWERR ;Yes... ; :NOC: LK DE,ALTFCB ;Point at fcb LK C,15 ; CALL SYS ;Call BDOS open INC A ;Returns A=255 if not home PUSH AF ;Save return value while we set FCB 841022 ;R/W and DIR 841022 LD A,ALTFCB+9 ;Set dest file R/W and DIR AND 7FH STO A,ALTFCB+9 LD A,ALTFCB+10 AND 7FH STO A,ALTFCB+10 POP AF ;Restore returned value from FCB 841022 JRZ :NOA ;no alt font 841022 ; LK DE,ALTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS INC A ;Check for error (A = 255) JZ :FWERR ;Hard error... ; LK DE,ALTFCB ;Point at it LK C,19 ; CALL SYS ;Delete it INC A ;Check for err JZ :FWERR ;Yes... :NOA: ; Create files and write 'em LK DE,CCPFCB ;Point at fcb LK C,22 CALL SYS ;Make it INC A ;Check for err JZ :FWERR ;Yes... ; LK BC,CCPBUFF ;Point at ccp buffer, LK DE,CCPFCB ;ccp fcb LK HL,32 ;Specify 32 128-byte sectors (4K) CALL :FILERW JNZ :FWERR ;Error ; LK DE,CCPFCB ;Close it LK C,16 CALL BDOS OR A ;Check for err JNZ :FWERR ; LD A,CCPFCB+9 ;Set dest file R/O and SYS OR 80H STO A,CCPFCB+9 LD A,CCPFCB+10 OR 80H STO A,CCPFCB+10 LK DE,CCPFCB ;Call BDOS to set attributes LK C,1EH CALL SYS PUSH AF ; LD A,CCPFCB+9 ;Reset dest file attributes to R/W and DIR. AND 7FH ;If attributes are not reset, any attempt STO A,CCPFCB+9 ;to create a new destination file (on another ;diskette, perhaps) results in a CP/M Error: LD A,CCPFCB+10 ;File Read/Only message. This is due to the AND 7FH ;file being created with the R/O attribute set. STO A,CCPFCB+10 POP AF INC A ;Check for error (A = 255) JZ :FWERR ;Hard error... ; ; LK DE,ALTFCB ;Point at fcb LK C,22 CALL SYS ;Make it INC A ;Check for err JZ :FWERR ;Yes... LK BC,FONTA ;Point at ccp buffer, LK DE,ALTFCB ;ccp fcb LK HL,16 ;Specify 16 128-byte sectors (2K) CALL :FILERW JNZ :FWERR ;Error ; LK DE,ALTFCB ;Close it LK C,16 CALL BDOS OR A ;Check for err JNZ :FWERR ; LD A,ALTFCB+9 ;Set dest file R/O and SYS OR 80H STO A,ALTFCB+9 LD A,ALTFCB+10 OR 80H STO A,ALTFCB+10 LK DE,ALTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS PUSH AF ;SaveA BDOS return LD A,ALTFCB+9 ;Reset dest file attributes to R/W and DIR. AND 7FH ;If attributes are not reset, any attempt STO A,ALTFCB+9 ;to create a new destination file (on another ;diskette, perhaps) results in a CP/M Error: LD A,ALTFCB+10 ;File Read/Only message. This is due to the AND 7FH ;file being created with the R/O attribute set. STO A,ALTFCB+10 POP AF INC A ;Check for error (A = 255) JZ :FWERR ;Hard error... ; XOR A ; RET ;Return with Z set :RWERR: LD A,RW ;Was it read or write? 841001 OR A ; 841001 LK HL,WRERR ;Assume write 841001 JRNZ :ERR ;Yup... 841001 ; LK HL,READERR ;No 841001 JR :ERR :CCPERR: LD A,RW ;Was it read or write? 841001 OR A ; 841001 LK HL,CCPWRERR ;Assume write 841001 JRNZ :ERR ;Yup... 841001 ; LK HL,CCPRDERR ;No 841001 JR :ERR :ALTERR: LD A,RW ;Was it read or write? 841001 OR A ; 841001 LK HL,ALTWRERR ;Assume write 841001 JRNZ :ERR ;Yup... 841001 ;R/W and DIR 841022 LD A,ALTFCB+9 ;Set dest file R/W and DIR AND 7FH STO A,ALTFCB+9 LD A,ALTFCB+10 AND 7FH STO A,ALTFCB+10 POP AF ;Restore returned value from FCB 841022 JRZ :NOA ;no alt font 841022 ; LK DE,ALTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS INC A ;Check for error (A = 255) JZ :FWERR ;Hard error... ; LK DE,ALTFCB ;Point at it LK C,19 ; CALL SYS ;Delete it INC A ;Check for err JZ :FWERR ;Yes... :NOA: ; Create files and write 'em LK DE,CCPFCB ;Point at fcb LK C,22 CALL SYS ;Make it INC A ;Check for err JZ :FWERR ;Yes... ; LK BC,CCPBUFF ;Point at ccp buffer, LK DE,CCPFCB ;ccp fcb LK HL,32 ;Specify 32 128-byte sectors (4K) CALL :FILERW JNZ :FWERR ;Error ; LK DE,CCPFCB ;Close it LK C,16 CALL BDOS OR A ;Check for err JNZ :FWERR ; LD A,CCPFCB+9 ;Set dest file R/O and SYS OR 80H STO A,CCPFCB+9 LD A,CCPFCB+10 OR 80H STO A,CCPFCB+10 LK DE,CCPFCB ;Call BDOS to set attributes LK C,1EH CALL SYS PUSH AF ; LD A,CCPFCB+9 ;Reset dest file attributes to R/W and DIR. AND 7FH ;If attributes are not reset, any attempt STO A,CCPFCB+9 ;to create a new destination file (on another ;diskette, perhaps) results in a CP/M Error: LD A,CCPFCB+10 ;File Read/Only message. This is due to the AND 7FH ;file being created with the R/O attribute set. STO A,CCPFCB+10 POP AF INC A ;Check for error (A = 255) JZ :FWERR ;Hard error... ; ; LK DE,ALTFCB ;Point at fcb LK C,22 CALL SYS ;Make it INC A ;Check for err JZ :FWERR ;Yes... LK BC,FONTA ;Point at ccp buffer, LK DE,ALTFCB ;ccp fcb LK HL,16 ;Specify 16 128-byte sectors (2K) CALL :FILERW JNZ :FWERR ;Error ; LK DE,ALTFCB ;Close it LK C,16 CALL BDOS OR A ;Check for err JNZ :FWERR ; LD A,ALTFCB+9 ;Set dest file R/O and SYS OR 80H STO A,ALTFCB+9 LD A,ALTFCB+10 OR 80H STO A,ALTFCB+10 LK DE,ALTFCB ;Call BDOS to set attributes LK C,1EH CALL SYS PUSH AF ;Save ; LK HL,ALTRDERR ;No 841001 JR :ERR :FWERR: LD A,RW ;Was it read or write? 841001 OR A ; 841001 LK HL,W_ERR_MS ;Assume write 841001 JRNZ :ERR ;Yup... 841001 ; LK HL,F_RD_ERR ;No 841001 JR :ERR :NOCCP: LK HL,NCCPMSG ;Point at no ccp message 841001 :ERR: CALL OSTR ;Print message 841001 CALL WAIT_CR ;Wait for user to read & respond 841001 CALL CLR_W_2 ;Erase message 841001 ORI 0FFh ;Return with Z clear 841001 RET ; 841001 :RW: LD A,RW ;Check for read or write 841001 OR A ; 841001 JRZ :RD ;It's read... 841001 ; CALL WRITE ;Nope, write it 841001 RET ;Return 841001 ; :RD: CALL READ ;Read it 841001 RET :FILERW: PUSH DE ;Save fcb addr MOV D,B ;Put DMA addr in DE MOV E,C ; LK C,26 ;Spec set DMA PUSH HL ;Save # logical secs to I/O CALL SYS ;Call BDOS POP HL XCHG ;Put # secs in DE LK C,44 ;Call set multi r/w CALL SYS ;in BDOS POP DE ;Restore fcb addr LD A,RW  ;Read or write? OR A ; LK C,21 ;Assume write JRNZ :IO ;Yup ; LK C,20 ;Nope :IO: CALL SYS ;Call BDOS OR A ;If A=0, return with Z set RZ ; DEC A ;If A=1, it's ok too-return Z set RET ;Return to caller PAGE ; Data and all message constants ;***** SYSTEM MESSAGES NO_OPT_1: = 3 SCR_TOP: DB ESC,'s','0',CLR_SCR DB ' Operating System Copy Program' DB cr,lf DB ' Osborne EXECUTIVE Computer System' DB CR,LF DB ' V1.2' DB 0 IF TVI950 MAIN1: DW MAIN_1_L DB ESC,'s1',CLR_SCR MN_1_A: DB ' ',ESC,'G0 Get System from Drive A ',ESC,'G0',0,CR,LF MN_1_B: DB ' ',ESC,'G0 Get System from Drive B ',ESC,'G0',0,CR,LF MN_1_C: DB ' ',ESC,'G0 Return to CP/M ',ESC,'G0',0,CR,LF DB CR,LF DB '$' ENDIF IF TVI912 MAIN1: DW MAIN_1_L DB ESC,'s1',CLR_SCR MN_1_A: DB ' ',ESC,'k Get System from Drive A ',ESC,'k',0,CR,LF MN_1_B: DB ' ',ESC,'k Get System from ADrive B ',ESC,'k',0,CR,LF MN_1_C: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' ENDIF MAIN_1_L: DW MN_1_A DW MN_1_B DW MN_1_C DIR_MSG: DB ESC,'s5',CLR_SCR DB ' Use the ARROW KEYS to position the',cr,lf DB ' cursor next to the desired choice.',cr,lf DB ' or',0 GET_A_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Insert diskette in Drive A and',cr,lf DB ' Press RETURN to READ SYSTEM$' GET_B_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Insert diskette in Drive B and',cr,lf DB ' Press RETURN to READ SYSTEM$' NO_OPT_2: = 3 IF TVI950 MAIN2: DW MAIN_2_L DB ESC,'s','1',CLR_SCR MN_2_A: DB ' ',ESC,'G0 Save System on Drive A ',ESC,'G0',0,CR,LF MN_2_B: DB ' ',ESC,'G0 Save System on Drive B ',ESC,'G0',0,CR,LF MN_2_C: DB ' ',ESC,'G0 Return to CP/M ',ESC,'G0',0,CR,LF DB CR,LF DB '$' ENDIF IF TVI912 MAIN2: DW MAIN_2_L DB ESC,'s','1',CLR_SCR MN_2_A: DB ' ',ESC,'k Save System on Drive A ',ESC,'k',0,CR,LF MN_2_B: DB ' ',ESC,'k Save System on Drive B ',ESC,'k',0,CR,LF MN_2_C: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' ENDIF MAIN_2_L: DW MN_2_A DW MN_2_B DW MN_2_C PUT_A_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Insert diskette in Drive A and',cr,lf DB ' Press RETURN to SAVE SYSTEM$' PUT_B_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Insert diskette in Drive B and',cr,lf DB ' Press RETURN to SAVE SYSTEM$' EXIT_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Press RETURN to return to CP/M$' NUM_OPTIONS DB 0 ;# OF OPTIONS in current ;main menu SIDE: DB 0 ;0-LEFT MENU, 1- RIGHT PUT_CURSOR: DB ESC,'s','1',ESC,'=' ;MAIN MENU CURSOR POSITION Y_COORD: DB 32 X_COORD: DB 32 DB 0 PUT_SUB_CURSOR: DB ESC,'s','2',ESC,'=' ;MAIN MENU CURSOR POSITION Y_SUB_COORD: DB 32 X_SUB_COORD: DB 32 DB 0 NUM_SUB_CMDS: DS 1 ;# OF COMMANDS IN SUB MENU NUL_MSG: M_EXIT: DB 0 DB ESC,'s','2','Z'-040h DB ESC,'s','1' DB '$' PAGE RDONE: DB ESC,'s','2','Z'-040h DB ' System read successfully. ',cr,lf DB ' Press RETURN to select save option.' DB 0 DONE: DB ESC,'s','2','Z'-040h DB ' System copied successfully. ',cr,lf DB ' Press RETURN to continue. ' DB 0 BSYSD: DB ESC,'s','2','Z'-040h DB ' Diskette in drive ' BDISK: DB 'X ' ;Drive letter filled in by GETSYS DB 'is not a system diskette.',cr,lf DB ' System get aborted. Press RETURN to continue.' DB 0 RW: DS 1 ;READ IF 0, WRITE IF 1 F_RD_ERR: READERR: CCPRDERR: ALTRDERR: DB ESC,'s','2','Z'-040h DB ' A disk error occurred while reading the system.',cr,lf DB ' System get aborted. Press RETURN to continue.' DB 0 CCPWRERR: ALTWRERR: W_ERR_MS: WRERR: DB ESC,'s','2','Z'-040h DB ' A disk error occurred while writing the system.',cr,lf DB ' System save aborted. Press RETURN to continue.' DB 0 OS_BAD_MSG: db 'COPYSYS requires CP/M 3.X or greater.',cr,lf DB 'Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation,',cr,lf DB '26538 Danti Court, Hayward, CA 94545.',cr,lf,0 COPYR_MSG: DB ESC,'s2',CLR_SCR DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation, ' DB '26538 Danti Court, Hayward, CA 94545',cr,lf DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole, CA 94564' DB 0 C3NFMSG: DB ESC,'s','2','Z'-040h DB ' CPM3.SYS not found. System get aborted.',cr,lf DB ' Press RETURN to continue.' DB 0 NCCPMSG: DB ESC,'s','2','Z'-040h DB ' CCP.COM not found. System get aborted.',cr,lf DB ' Press RETURN to continue.' DB 0 NSF_SPC: DB ESC,'s','2','Z'-040h DB ' Insufficient space on drive ' PDISK2: DB 1 ;Filled in by PUTSYS DB ' for CPM3.SYS. ',cr,lf DB ' System save aborted. Press RETURN to continue.' DB 0 DELMSG: DB ESC,'s','2','Z'-040h DB ' CPM3.SYS is already on drive ' PDISK3: DB 1 ;Filled in by PUTSYS DB '.',cr,lf DB ' Do you want to overwrite it (y/n)? ' DB 0 DENSERR: DB ESC,'s','2','Z'-040h DB ' System disk must be OCC double density format.',cr,lf DB ' System save abortAed. Press RETURN to continue.' DB 0 DS 30*2 STACK: DS 0 SRCFCB: ;FCB for CPM3.SYS source file DB 0 ;Drive # filled by GETSYS DB 'CPM3 SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 DSTFCB: ;FCB for CPM3.SYS source file DB 0 ;Drive # filled by PUTSYS DB 'CPM3 SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 CCPFCB: ;FCB for CCP.COM source file CCPDR: DB 0 ;Drive # filled by DSGTPT DB 'CCP COM' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 CCPNR: DB 0,0,0,0 ALTFCB: ;FCB for ALTFONT.SYS source file ALTDR: DB 0 ;Drive # filled by DSGTPT DB 'ALTFONT SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 ALTNR: DB 0,0,0,0 DRVSPC: DS 3 ;Three byte area for BDOS to put drive free space in BLKCNT: DB 0 ;16K block count in CPM3.SYS set by GETSYS REMCNT: DB 0 ;Count of remaining 128 byte sectors CURUSR: DB 0 ;Current user when COPYSYS was run SYS_BUFF: DS 5*1024 ;First 5 secs CCPBUFF: D BDOS return LD A,ALTFCB+9 ;Reset dest file attributes to R/W and DIR. AND 7FH ;If attributes are not reset, any attempt STO A,ALTFCB+9 ;to create a new destination file (on another ;diskette, perhaps) results in a CP/M Error: LD A,ALTFCB+10 ;File Read/Only message. This is due to the AND 7FH ;file being created with the R/O attribute set. STO A,ALTFCB+10 POP AF INC A ;Check for error (A = 255) JZ :FWERR ;Hard error... ; XOR A ; RET ;Return with Z set :RWERR: LD A,RW ;Was it read or write? 841001 OR A ; 841001 LK HL,WRERR ;Assume write 841001 JRNZ :ERR ;Yup... 841001 ; LK HL,READERR ;No 841001 JR :ERR :CCPERR: LD A,RW ;Was it read or write? 841001 OR A ; 841001 LK HL,CCPWRERR ;Assume write 841001 JRNZ :ERR ;Yup... 841001 ; LK HL,CCPRDERR ;No 841001 JR :ERR :ALTERR: LD A,RW ;Was it read or write? 841001 OR A ; 841001 LK HL,ALTWRERR ;Assume write 841001 JRNZ :ERR ;Yup... 841001 ; LK HL,ALTRDERR ;No 841001 JR :ERR :FWERR: LD A,RW ;Was it read or write? 841001 OR A ; 841001 LK HL,W_ERR_MS ;Assume write 841001 JRNZ :ERR ;Yup... 841001 ; LK HL,F_RD_ERR ;No 841001 JR :ERR :NOCCP: LK HL,NCCPMSG ;Point at no ccp message 841001 :ERR: CALL OSTR ;Print message 841001 CALL WAIT_CR ;Wait for user to read & respond 841001 CALL CLR_W_2 ;Erase message 841001 ORI 0FFh ;Return with Z clear 841001 RET ; 841001 :RW: LD A,RW ;Check for read or write 841001 OR A ; 841001 JRZ :RD ;It's read... 841001 ; CALL WRITE ;Nope, write it 841001 RET ;Return 841001 ; :RD: CALL READ ;Read it 841001 RET :FILERW: PUSH DE ;Save fcb addr MOV D,B ;Put DMA addr in DE MOV E,C ; LK C,26 ;Spec set DMA PUSH HL ;Save # logical secs to I/O CALL SYS ;Call BDOS POP HL XCHG ;Put # secs in DE LK C,44 ;Call set multi r/w CALL SYS ;in BDOS POP DE ;Restore fcb addr LD A,RW  ;Read or write? OR A ; LK C,21 ;Assume write JRNZ :IO ;Yup ; LK C,20 ;Nope :IO: CALL SYS ;Call BDOS OR A ;If A=0, return with Z set RZ ; DEC A ;If A=1, it's ok too-return Z set RET ;Return to caller PAGE ; Data and all message constants ;***** SYSTEM MESSAGES NO_OPT_1: = 3 SCR_TOP: DB ESC,'s','0',CLR_SCR DB ' Operating System Copy Program' DB cr,lf DB ' Osborne EXECUTIVE Computer System' DB CR,LF DB ' V1.1' DB 0 IF TVI950 MAIN1: DW MAIN_1_L DB ESC,'s1',CLR_SCR MN_1_A: DB ' ',ESC,'G0 Get System from Drive A ',ESC,'G0',0,CR,LF MN_1_B: DB ' ',ESC,'G0 Get System from Drive B ',ESC,'G0',0,CR,LF MN_1_C: DB ' ',ESC,'G0 Return to CP/M ',ESC,'G0',0,CR,LF DB CR,LF DB '$' ENDIF IF TVI912 MAIN1: DW MAIN_1_L DB ESC,'s1',CLR_SCR MN_1_A: DB ' ',ESC,'k Get System from Drive A ',ESC,'k',0,CR,LF MN_1_B: DB ' ',ESC,'k Get System from Drive B ',ESC,'k',0,CR,LF MN_1_C: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' ENDIF MAIN_1_L: DW MN_1_A DW MN_1_B DW MN_1_C DIR_MSG: DB ESC,'s5',CLR_SCR DB ' Use the ARROW KEYS to position the',cr,lf DB ' cursor next to the desired choice.',cr,lf DB ' or',0 GET_A_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Insert diskette in Drive A and',cr,lf DB ' Press RETURN to READ SYSTEM$' GET_B_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Insert diskette in Drive B and',cr,lf DB ' Press RETURN to READ SYSTEM$' NO_OPT_2: = 3 IF TVI950 MAIN2: DW MAIN_2_L DB ESC,'s','1',CLR_SCR MN_2_A: DB ' ',ESC,'G0 Save System on Drive A ',ESC,'G0',0,CR,LF MN_2_B: DB ' ',ESC,'G0 Save System on Drive B ',ESC,'G0',0,CR,LF MN_2_C: DB ' ',ESC,'G0 Return to CP/M ',ESC,'G0',0,CAR,LF DB CR,LF DB '$' ENDIF IF TVI912 MAIN2: DW MAIN_2_L DB ESC,'s','1',CLR_SCR MN_2_A: DB ' ',ESC,'k Save System on Drive A ',ESC,'k',0,CR,LF MN_2_B: DB ' ',ESC,'k Save System on Drive B ',ESC,'k',0,CR,LF MN_2_C: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' ENDIF MAIN_2_L: DW MN_2_A DW MN_2_B DW MN_2_C PUT_A_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Insert diskette in Drive A and',cr,lf DB ' Press RETURN to SAVE SYSTEM$' PUT_B_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Insert diskette in Drive B and',cr,lf DB ' Press RETURN to SAVE SYSTEM$' EXIT_MSG: DB 0 DB ESC,'s6',CLR_SCR DB ' Press RETURN to return to CP/M$' NUM_OPTIONS DB 0 ;# OF OPTIONS in current ;main menu SIDE: DB 0 ;0-LEFT MENU, 1- RIGHT PUT_CURSOR: DB ESC,'s','1',ESC,'=' ;MAIN MENU CURSOR POSITION Y_COORD: DB 32 X_COORD: DB 32 DB 0 PUT_SUB_CURSOR: DB ESC,'s','2',ESC,'=' ;MAIN MENU CURSOR POSITION Y_SUB_COORD: DB 32 X_SUB_COORD: DB 32 DB 0 NUM_SUB_CMDS: DS 1 ;# OF COMMANDS IN SUB MENU NUL_MSG: M_EXIT: DB 0 DB ESC,'s','2','Z'-040h DB ESC,'s','1' DB '$' PAGE RDONE: DB ESC,'s','2','Z'-040h DB ' System read successfully. ',cr,lf DB ' Press RETURN to select save option.' DB 0 DONE: DB ESC,'s','2','Z'-040h DB ' System copied successfully. ',cr,lf DB ' Press RETURN to continue. ' DB 0 BSYSD: DB ESC,'s','2','Z'-040h DB ' Diskette in drive ' BDISK: DB 'X ' ;Drive letter filled in by GETSYS DB 'is not a system diskette.',cr,lf DB ' System get aborted. Press RETURN to continue.' DB 0 RW: DS 1 ;READ IF 0, WRITE IF 1 F_RD_ERR: READERR: CCPRDERR: ALTRDERR: DB ESC,'s','2','Z'-040h DB ' A disk error occurred while reading the system.',cr,lf DB ' System get aborted. Press RETURN to continue.' DB 0 CCPWRERR: ALTWRERR: W_ERR_MS: WRERR: DB ESC,'s','2','Z'-040h DB ' A disk error occurred while writing the system.',cr,lf DB ' System save aborted. Press RETURN to continue.' DB 0 OS_BAD_MSG: db 'COPYSYS requires CP/M 3.X or greater.',cr,lf DB 'Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation,',cr,lf DB '26538 Danti Court, Hayward, CA 94545.',cr,lf,0 COPYR_MSG: DB ESC,'s2',CLR_SCR DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation, ' DB '26538 Danti Court, Hayward, CA 94545',cr,lf DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole, CA 94564' DB 0 C3NFMSG: DB ESC,'s','2','Z'-040h DB ' CPM3.SYS not found. System get aborted.',cr,lf DB ' Press RETURN to continue.' DB 0 NCCPMSG: DB ESC,'s','2','Z'-040h DB ' CCP.COM not found. System get aborted.',cr,lf DB ' Press RETURN to continue.' DB 0 NSF_SPC: DB ESC,'s','2','Z'-040h DB ' Insufficient space on drive ' PDISK2: DB 1 ;Filled in by PUTSYS DB ' for CPM3.SYS. ',cr,lf DB ' System save aborted. Press RETURN to continue.' DB 0 DELMSG: DB ESC,'s','2','Z'-040h DB ' CPM3.SYS is already on drive ' PDISK3: DB 1 ;Filled in by PUTSYS DB '.',cr,lf DB ' Do you want to overwrite it (y/n)? ' DB 0 DENSERR: DB ESC,'s','2','Z'-040h DB ' System disk must be OCC double density format.',cr,lf DB ' System save aborted. Press RETURN to continue.' DB 0 DS 30*2 STACK: DS 0 SRCFCB: ;FCB for CPM3.SYS source file DB 0 ;Drive # filled by GETSYS DB 'CPM3 SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 DSTFCB: ;FCB for CPM3.SYS source file DB 0 ;Drive # filled by PUTSYS DB 'CPM3 SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 CCPFCB: ;FCB for CCP.COM source file CCPDR: DB 0 ;Drive # filled by DSGTPT DB 'CCP COM' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 CCPNR: DB 0,0,0,0 ALTFCB: ;FCB for ALTFONT.SYS source file ALTDR: DB 0 ;Drive # filled by DSGTPT DB 'ALTFONT SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 ALTNR: DB 0,0,0,0 DRVSPC: DS 3 ;Three byte area for BDOS to put drive free space in BLKCNT: DB 0 ;16K block count in CPM3.SYS set by GETSYS REMCNT: DB 0 ;Count of remaining 128 byte sectors CURUSR: DB 0 ;Current user when COPYSYS was run SYS_BUFF: DS 5*1024 ;First 5 secs CCPBUFF: DAS 4*1024 ;CCP OURSEC: DS 1024 ;setup override FONTM: DS 2*1024 ;main font FONTA: DS 2*1024 ;alternate font ROMRAM: DS 1024 ;rom's ram override FILEBUFF = * ;Buffer area for CPM3.SYS  source file DB 0 ;Drive # filled by PUTSYS DB 'CPM3 SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 CCPFCB: ;FCB for CCP.COM source file CCPDR: DB 0 ;Drive # filled by DSGTPT DB 'CCP COM' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 CCPNR: DB 0,0,0,0 ALTFCB: ;FCB for ALTFONT.SYS source file ALTDR: DB 0 ;Drive # filled by DSGTPT DB 'ALTFONT SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 ALTNR: DB 0,0,0,0 DRVSPC: DS 3 ;Three byte area for BDOS to put drive free space in BLKCNT: DB 0 ;16K block count in CPM3.SYS set by GETSYS REMCNT: DB 0 ;Count of remaining 128 byte sectors CURUSR: DB 0 ;Current user when COPYSYS was run SYS_BUFF: DS 5*1024 ;First 5 secs CCPBUFF: D SYSCCP COMALTFONT SYSA 94545. s2 gG 1983 Osborne Computer Corporation, 26538 Danti Court, Hayward, CA 94545 gG 1984 Future Systems, 828 Nob Hill Avenue, Pinole, CA 94564s2 CPM3.SYS not found. System get aborted. Press RETURN to continue.s2 CCP.COM not found. System get aborted. Press RETURN to continue.s2 Insufficient space on drive  for CPM3.SYS. System save aborted. Press RETURN to continue.s2 CPM3.SYS is already on drive . Do you want to overwrite it (y/n)? s2 System disk must be OCC double density format. System save aborted. Press RETURN to continue.CPM3 SYSCPM3  SYSCCP COMALTFONT SYSA 94545. s2 gG 1983 Osborne Computer Corporation, 26538 Danti Court, Hayward, CA 94545 gG 1984 Future Systems, 828 Nob Hill Avenue, Pinole, CA 94564s2 CPM3.SYS not found. System get aborted. Press RETURN to continue.s2 CCP.COM not found. System get aborted. Press RETURN to continue.s2 Insufficient space on drive  for CPM3.SYS. System save aborted. Press RETURN to continue.s2 CPM3.SYS is already on drive . Do you want to overwrite it (y/n)? s2 System disk must be OCC double density format. System save aborted. Press RETURN to continue.CPM3 SYSCPM3 S 4*1024 ;CCP OURSEC: DS 1024 ;setup override FONTM: DS 2*1024 ;main font FONTA: DS 2*1024 ;alternate font ROMRAM: DS 1024 ;rom's ram override FILEBUFF = * ;Buffer area for CPM3.SYS  source file DB 0 ;Drive # filled by PUTSYS DB 'CPM3 SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 CCPFCB: ;FCB for CCP.COM source file CCPDR: DB 0 ;Drive # filled by DSGTPT DB 'CCP COM' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 CCPNR: DB 0,0,0,0 ALTFCB: ;FCB for ALTFONT.SYS source file ALTDR: DB 0 ;Drive # filled by DSGTPT DB 'ALTFONT SYS' DB 0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 ALTNR: DB 0,0,0,0 DRVSPC: DS 3 ;Three byte area for BDOS to put drive free space in BLKCNT: DB 0 ;16K block count in CPM3.SYS set by GETSYS REMCNT: DB 0 ;Count of remaining 128 byte sectors CURUSR: DB 0 ;Current user when COPYSYS was run SYS_BUFF: DS 5*1024 ;First 5 secs CCPBUFF: D Generation procedure for Executive COPYSYS V1.1 (3.080) T generat objec cod fo COPYSYS th followin file ar needed: COPYSYS.ASM, SYSS1.AST, RAMS10.ASM, ACT.COM and HEXCOM.COM. Al o thes file ar o dis o th COPYSY releas diskette. COPYSYS is generated with the command lines: ACT COPYSYS S=SYSS1 HEXCOM COPYSYS If a listing is desired, enter the following command: ACT COPYSYS S=SYSS1 R=F L UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUA _RTN = 15Dh ;Write DOUBTYP = 0CH ;DOUBLE DENSITY OSBORNE SAVTYP DOUBSEC = 5 ;# OF SECTORS/TRACK FOR OSBORNE DOUBLE DENSITY N128B 12 ;NUMBE O 12 BYT BLOC I TH SYSTE 2.21b DSTYP = 0Eh ;Vixen dsdd type 841001 DSSEC = 5 ;Vixen dsdd sectors/trk 841001 NDISKS = 2 ;Maximum supported disk drives SECSIZ = 128 ;SIZE OF CP/M LOGICAL SECTOR CONI = 1 ;CONSOLE INPUT FUNCTION CONO = 2 ;CONSOLE OUTPUT FUNCTION PAGE ; ; BDOS function numbers: ; PR_STR_FN = 9 ;BDOS print string function OS_VER_FN = 12 ;BDOS version number function SRC_FIRST = 17 ;BDOS search for first matching file ; ; Macro definitions: ; PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; ; Character definitions: ; CTRL_G = 'G' - 40h CTRL_H = 'H' - 40h CTRL_J = 'J' - 40h CTRL_K = 'K' - 40h CTRL_L = 'L' - 40h CTRL_S = 'S' - 40h CTRL_Z = 'Z' - 40h ;Control-Z ; ; Executive definitions: ; CP_RG_CH = CTRL_S ;Copyright character ;VEGH ;Clear Graphics mode esc seqn defined in ;systext ;VSGH ;Set Graphics mode esc seqn defined in ;systext ;VWDEF ;Define window escape seqn defined in systext ; ; CP/M definitios: ; WBOOTE = 0000H ;Warm boot emtry point TPA_Base = 0100h ;Base of TPA EOF_Mark = CTRL_Z ;CP/M logical end-of-file marker CPM_PLUS = 30h ;Value returned by function 12 is greater than ;or equal to this if running CP/M Plus. ; ; Console definitions: ; BELL_Char = CTRL_G ;Char to ring bell. CLR_SCR = CTRL_Z ;Char to clear screen (or current window) ; ; Keyboard definitions: ; RAW_UP = 8ah ;Untranslated cursor up char RAW_DOWN = 8ch ;Untranslated cursor down char PAGE ORG TPA_Base ;Start code at base of TPA JMP START ;Jump around copyright and version stamp ;to start of code. JMP SETW0 ;Utility to set window 0 for debugging 841004 ; ; Copyright and version stamp: ; DB cr,lf DB ' Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation,',cr,lf DB ' 26538 Danti Court, Hayward, CA 94545.',cr,lf DB ' V1.1',EOF_Mark SETW0: LK HL,W0SET ; 841004 CALL OUT_STRING ; 841004 RET ; 841004 W0SET: DB ESC,'s0',0 ; 841004 PAGE START: ;Start of COPY main program. LDK SP,STACK ;Set up local stack PROC ; ; Make sure CP/M Plus is running. ; LK C,OS_VER_FN ;Get OS version # CALL BDOS MOV A,H ;Check for H = 0 OR A JNZ :OS_BAD ;H ne 0, not running CP/M ; MOV A,L ;Check for L => 30 CMP CPM_PLUS ; JNC :OS_OK ;L => 30... ; :OS_BAD: ;Not running CP/M 3.X or greater LK HL,OS_BAD_MSG ;Print message and quit CALL OUT_STRING JMP 0 ;Warm Boot... ; :OS_OK: ;OS ok, continue... LK E,0FFh ;Set BDOS error mode to RETURN ERROR LK C,2Dh CALL SYS ; ; Fall through to screen driver... ; PAGE ; Menu screen driver begins here: ; BDOS EQU 0005h ;BDOS entry point UP EQU CTRL_K ;TVI character for cursor up DOWN EQU CTRL_J ;TVI char for cursor down RIGHT EQU CTRL_L ;TVI char for cursor right LEFT EQU CTRL_H ;TVI char for cursor left ENTER EQU cr ;Char entered by user to execute command PAGE PROC START1: ; ; Driver initialization code: ; CALL SET_STUFF ;Initialize windows used by driver LK HL,SCR_TOP ;Display program name and vers num CALL OUT_STRING LK HL,COPYR_MSG ;Display copyright message CALL OUT_STRING CALL SET_M1 ;Make current menu menu #1: main menu: ;Select copy or format :COPYSYS: ; ; Return point for driver function execution ; ; ; See if current menu has already been displayed: ; LD DE,MAIN ;Load address of current menu LD HL,OLD_MN ;and compare with address of last ;menu displayed. STC CMC SBC HL,DE JZ :NO_DSP ;Menu already displayed, don't re- ;display. ; STO DE,OLD_MN ;Menu must be displayed. Save address ;of menu as last displayed. INC DE  ;Bump ptr past address of command INC DE ;string table to start of menu display ;data. LK C,PR_STR_FN ;Tell BDOS to print it. CALL BDOS LD A,Y_COORD ;Hilight default selection CALL HI_CURR LK HL,DIR_MSG ;Display arrow key directions CALL OUT_STRING CALL CMD_DESC ;Display command description for ;this menu's default selection CALL SET_CURSOR ;Set cursor next to default selection. ; ; Branch point if current menu already displayed: ; :NO_DSP: LK DE,:COPYSYS ;Load address of top of driver loop PUSH DE ;and push on stack as return address ;for the next user command. ; ; Wait for user to enter char and process accordingly: ; :GET_CH: ;Return here if invalid char entered. CALL GET_CHAR ;Wait for char to A CMP UP ;Is it TVI cursor up char? JZ MOVE_UP ;Yes, move up. ; ;No. CMP RAW_UP ;Is it raw (untranslated) up char? JZ MOVE_UP ;Yes, move up. ; CMP DOWN ;Is it TVI move down? JZ MOVE_DOWN ;Yes... ; ;No.  A! CMP RAW_DOWN ;Is it raw down char? JZ MOVE_DOWN ;Yes... ; ; CMP RIGHT ;Horizontal motion not supported. ; JZ MOVE_RIGHT ; CMP 08Bh ; JZ MOVE_RIGHT ; CMP LEFT ; JZ MOVE_LEFT ; CMP 08Dh ; JZ MOVE_LEFT ; CMP ENTER ;Is it enter command? JZ DO_COMMAND ;Yes, process current command. ; CALL BEEP ;Char invalid. Ring bell. JMP :GET_CH ;and wait for another char... ; ; Local storage to save address of last menu displayed. ; OLD_MN: DW 0 PAGE SET_STUFF: ; Initialize driver: set up necessary windows. Disable function key ; translation. ; ; ENTRY: ; None. ; EXIT: ; Windows initialized. ; LK HL,INIT_STRING ;Point at window init string. CALL OUT_STRING ;Send it to console LK HL,XL_OFF ;Point at fn key xlate off string CALL OUT_STRING ;send it RET ;and return. ; INIT_STRING: ;Windows for screen driver. Window 4 is defined on ;the fly to display command string in reverse video. ; ; Window 1 is used for current menu: ; DB ESC,VWDEF,'1 Generation procedure for Executive COPYSYS V1.1 10/14/84 DAB T generat objec cod fo COPYSYS th followin file ar needed: COPYSYS.ASM, SYSS1.AST, RAMS10.ASM, ACT.COM and HEXCOM.COM. Al o thes file ar o dis o th COPYSY releas diskette. COPYSYS is generated with the command lines: ACT COPYSYS S=SYSS1 HEXCOM COPYSYS If a listing is desired, enter the following command: ACT COPYSYS S=SYSS1 R=F L UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU| | ` 0 0 TUUUUU;.Date: 10/22/84 ;.Last modified: David Andrew Berg ;.Title: COPYSYS ;.Comments: Rev 1.2 ; ; +---------------+ ; | | ; | COPYSYS | ; | | ; +---------------+ ; ; (c) 1983 Osborne Computer Corporation, ; 26538 Danti Court, ; Hayward, CA 94545 ; ; This revision copies all three system tracks (120 128 byte logical ; sectors) of an OCC double density disk and copies the file CPM3.SYS ; from the source to the destination drive. ; ; Since the file copy routine uses BDOS functions supported only ; under CP/M Plus, the program will abort if CP/M Plus is not ; running. ; ; Revision history: ; 3/15/83: ; a. Implemented redesign to handle all error conditions within program. ; This program should never exit to CP/M unexpectedly. Per SPRs #127, 162 ; ; b. Read and write error messages were made consistent, per SPR #137 ; ; 3/16/83: ; a. Changed all ESC-w references to ESC-VWDEF. VWDEF is defined in the ; systext file for the correct Window Define char. Per SPR #225 ; ; b. Installed code to verify system tracks for correctness as does ; the ROM boot loader. Per SPR # ; ; c. Removed (c) from sign-on message, per SPR #103 ; ; d. Changed character wait routines to only accept character specified ; in message on screen (e.g., only RETURN is accepted if it is ; specified). Per SPR # ; ; e. Installed final release version numbers. ; ;3/21/83: ; a. Installed new, clearer error messages indicating operation has ; been aborted. ; ; b. Final release of V1.0 (3.080) ; ;10/1/84: ; a. Installed support for Vixen compatible dsdd disks. ; ;10/22/84: ; a. Accomodated flaw in BDOS. When CCP.COM and ALTFONT.SYS are ; opened to read the system, the corresponding FCB is set according ; to the file status of the existing file. Thus, if ; the source file is R/O and SYS (as it normally is), when it is ; opened for writing on the destination drive, it is opened R/O ; and SYS. When the file is written to, the write fails since the ; file is R/O. This is fixed by always resetting the FCB to ; R/W and DIR. ; page ; Assembly Constants and definitions. LINK RAMS10.ASM ;RAM memory locations and constants 2.21 ; ; Conditional assembly equates: ; ; ; Generation toggles: ; BETA_TEST = true ; ; ROM terminal emulation supported: ; IF BETA_TEST TVI950 = false ENDIF IF NOT BETA_TEST TVI950 = true ENDIF TVI912 = not TVI950 ; ; ROM entry points: ; SEN_RTN = 160h ;SENDEN RD_RTN = 15Ah ;Read WRT_RTN = 15Dh ;Write DOUBTYP = 0CH ;DOUBLE DENSITY OSBORNE SAVTYP DOUBSEC = 5 ;# OF SECTORS/TRACK FOR OSBORNE DOUBLE DENSITY N128B 12 ;NUMBE O 12 BYT BLOC I TH SYSTE 2.21b DSTYP = 0Eh ;Vixen dsdd type 841001 DSSEC = 5 ;Vixen dsdd sectors/trk 841001 NDISKS = 2 ;Maximum supported disk drives SECSIZ = 128 ;SIZE OF CP/M LOGICAL SECTOR CONI = 1 ;CONSOLE INPUT FUNCTION CONO = 2 ;CONSOLE OUTPUT FUNCTION PAGE ; ; BDOS function numbers: ; PR_STR_FN = 9 ;BDOS print string function O!A"',32+5 ,32+20 ,32+12 ,32+80 ; ; Window 2 is used for completion or error message reporting: ; DB ESC,VWDEF,'2',32+20 ,32 ,32+23 ,32+80 ; ; Window 3 is used for execution status while performing commands ; (such as copy or format): ; DB ESC,VWDEF,'3',32+13,32,32+19,32+80 ; ; Window 5 is used for general directions applicable to all commands: ; DB ESC,VWDEF,'5',32+10,32+0,32+16,32+80 ; ; Window 6 is used for command specific directions: ; DB ESC,VWDEF,'6',32+13,32+0,32+16,32+80 ; ; Reselect window zero after defining windows: ; DB ESC,'s','0','Z'-040h D 0 ; ; String to disable fn. key xlate: ; XL_OFF: IF TVI950 DB 0 ENDIF IF TVI912 DB ESC,'f',0 ENDIF ; ; String to define window 4: ; W_STR: DB ESC,VWDEF,'4' ;String to define window used for W_PCH_1: DB 32+6,32+20 ;displaying cmd string in reverse W_PCH_2: DB 32+15,32+80,0 ;video PAGE MOVE_UP: ; User entered cursor up key. Make selection above the current in menu scription (not used in COPY). ; PROC LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD HL,O_SUB_MN ;Load address of last-displayed ;command description. STC CMC SBC HL,DE ;Is it same as new one? JZ :NO_DSP ;Yes, don't re-display it ; ;No. Display it STO DE,O_SUB_MN ;Save description as last LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return ; :NO_DSP: RET ;Current same as last, so don't display it ; ; ; Local S_VER_FN = 12 ;BDOS version number function SRC_FIRST = 17 ;BDOS search for first matching file ; ; Macro definitions: ; PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; ; Character definitions: ; CTRL_G = 'G' - 40h CTRL_H = 'H' - 40h CTRL_J = 'J' - 40h CTRL_K = 'K' - 40h CTRL_L = 'L' - 40h CTRL_S = 'S' - 40h CTRL_Z = 'Z' - 40h ;Control-Z ; ; Executive definitions: ; CP_RG_CH = CTRL_S ;Copyright character ;VEGH ;Clear Graphics mode esc seqn defined in ;systext ;VSGH ;Set Graphics mode esc seqn defined in ;systext ;VWDEF ;Define window escape seqn defined in systext ; ; CP/M definitios: ; WBOOTE = 0000H ;Warm boot emtry point TPA_Base = 0100h ;Base of TPA EOF_Mark = CTRL_Z ;CP/M logical end-of-file marker CPM_PLUS = 30h ;Value returned by function 12 is greater than ;or equal to this if running CP/M Plus. ; ; Console definitions: ; BELL_Char = CTRL_G ;Char to ring bell. CLR_SCR = CTRL_Z ;Char to clear screen (or current window) ; ; Keyboard definitions: ; RAW_UP = 8ah ;Untranslated cursor up char RAW_DOWN = 8ch ;Untranslated cursor down char PAGE ORG TPA_Base ;Start code at base of TPA JMP START ;Jump around copyright and version stamp ;to start of code. JMP SETW0 ;Utility to set window 0 for debugging 841004 ; ; Copyright and version stamp: ; DB cr,lf DB ' Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation,',cr,lf DB ' 26538 Danti Court, Hayward, CA 94545.',cr,lf DB ' V1.2',EOF_Mark SETW0: LK HL,W0SET ; 841004 CALL OUT_STRING ; 841004 RET ; 841004 W0SET: DB ESC,'s0',0 ; 841004 PAGE START: ;Start of COPY main program. LDK SP,STACK ;Set up local stack PROC ; ; Make sure CP/M Plus is running. ; LK C,OS_VER_FN ;Get OS version # CALL BDOS MOV A,H ;Check for H = 0 OR A JNZ :OS_BAD ;H ne 0, not running CP/M ; MOV A,L ;Check for L => 30 CMP CPM_PLUS ; JNC :OS_OK ;L => 30... ; :OS_BAD: ;Not running CP/M 3.X or greater LK HL,OS_BAD_MSG ;Print message and quit CALL OUT_STRING JMP 0 ;Warm Boot... ; :OS_OK: ;OS ok, continue... LK E,0FFh ;Set BDOS error mode to RETURN ERROR LK C,2Dh CALL SYS ; ; Fall through to screen driver... ; PAGE ; Menu screen driver begins here: ; BDOS EQU 0005h ;BDOS entry point UP EQU CTRL_K ;TVI character for cursor up DOWN EQU CTRL_J ;TVI char for cursor down RIGHT EQU CTRL_L ;TVI char for cursor right LEFT EQU CTRL_H ;TVI char for cursor left ENTER EQU cr ;Char entered by user to execute command PAGE PROC START1: ; ; Driver initialization code: ; CALL SET_STUFF ;Initialize windows used by driver LK HL,SCR_TOP ;Display program name and vers num CALL OUT_STRING LK HL,COPYR_MSG ;Display copyright message CALL OUT_STRING CALL SET_M1 ;Make current menu menu #1: main "A#menu: ;Select copy or format :COPYSYS: ; ; Return point for driver function execution ; ; ; See if current menu has already been displayed: ; LD DE,MAIN ;Load address of current menu LD HL,OLD_MN ;and compare with address of last ;menu displayed. STC CMC SBC HL,DE JZ :NO_DSP ;Menu already displayed, don't re- ;display. ; STO DE,OLD_MN ;Menu must be displayed. Save address ;of menu as last displayed. INC DE ;Bump ptr past address of command INC DE ;string table to start of menu display ;data. LK C,PR_STR_FN ;Tell BDOS to print it. CALL BDOS LD A,Y_COORD ;Hilight default selection CALL HI_CURR LK HL,DIR_MSG ;Display arrow key directions CALL OUT_STRING CALL CMD_DESC ;Display command description for ;this menu's default selection CALL SET_CURSOR ;Set cursor next to default selection. ; ; Branch point if current menu already displayed: ; :NO_DSP: LK DE,:COPYSYS ;Load address of top of driver loop  PUSH DE ;and push on stack as return address ;for the next user command. ; ; Wait for user to enter char and process accordingly: ; :GET_CH: ;Return here if invalid char entered. CALL GET_CHAR ;Wait for char to A CMP UP ;Is it TVI cursor up char? JZ MOVE_UP ;Yes, move up. ; ;No. CMP RAW_UP ;Is it raw (untranslated) up char? JZ MOVE_UP ;Yes, move up. ; CMP DOWN ;Is it TVI move down? JZ MOVE_DOWN ;Yes... ; ;No. CMP RAW_DOWN ;Is it raw down char? JZ MOVE_DOWN ;Yes... ; ; CMP RIGHT ;Horizontal motion not supported. ; JZ MOVE_RIGHT ; CMP 08Bh ; JZ MOVE_RIGHT ; CMP LEFT ; JZ MOVE_LEFT ; CMP 08Dh ; JZ MOVE_LEFT ; CMP ENTER ;Is it enter command? JZ DO_COMMAND ;Yes, process current command. ; CALL BEEP ;Char invalid. Ring bell. JMP :GET_CH ;and wait for another char... ; ; Local storage to save address of last menu displayed. ; OLD_MN: DW 0 PAGE SET_STUFF: ; Initialize driver: set up necessary windows. Disable function key ; translation. ; ; ENTRY: ; None. ; EXIT: ; Windows initialized. ; LK HL,INIT_STRING ;Point at window init string. CALL OUT_STRING ;Send it to console LK HL,XL_OFF ;Point at fn key xlate off string CALL OUT_STRING ;send it RET ;and return. ; INIT_STRING: ;Windows for screen driver. Window 4 is defined on ;the fly to display command string in reverse video. ; ; Window 1 is used for current menu: ; DB ESC,VWDEF,'1',32+5 ,32+20 ,32+12 ,32+80 ; ; Window 2 is used for completion or error message reporting: ; DB ESC,VWDEF,'2',32+20 ,32 ,32+23 ,32+80 ; ; Window 3 is used for execution status while performing commands ; (such as copy or format): ; DB ESC,VWDEF,'3',32+13,32,32+19,32+80 ; ; Window 5 is used for general directions applicable to all commands: ; DB ESC,VWDEF,'5',32+10,32+0,32+16,32+80 ; ; Window 6 is used for command specific directions: ; DB ESC,VWDEF,'6',32+13,32+0,32+16,32+80 ; ; Reselect window zero after defining windows: ; DB ESC,'s','0','Z'-040h D 0 ; ; String to disable fn. key xlate: ; XL_OFF: IF TVI950 DB 0 ENDIF IF TVI912 DB ESC,'f',0 ENDIF ; ; String to define window 4: ; W_STR: DB ESC,VWDEF,'4' ;String to define window used for W_PCH_1: DB 32+6,32+20 ;displaying cmd string in reverse W_PCH_2: DB 32+15,32+80,0 ;video PAGE MOVE_UP: ; User entered cursor up key. Make selection above the current in menu ; the new current selection if the top most selection is not already ; current. In other words, move up if not at tup. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC L HL,Y_COOR ;Poin a lin o curren selection ;for 'main' menu. LD A,SIDE ;What side are we on (left or right)? CMP 0 ; JRZ :LEFT ;We're on left (main) side... ; ;We're on right scription (not used in COPY). ; PROC LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD HL,O_SUB_MN ;Load address of last-displayed ;command description. STC CMC SBC HL,DE ;Is it same as new one? JZ :NO_DSP ;Yes, don't re-display it ; ;No. Display it STO DE,O_SUB_MN ;Save description as last LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return ; :NO_DSP: RET ;Current same as last, so don't display it ; ; ; Local #A$on. ; ; ENTRY: ; SIDE = 0 if on main menu side (always true in COPY) ; PUT_CURSOR is a cursor positioning string which is patched with ; the line number of the current selection (relative 32) in Y_COORD. ; ; EXIT: ; None. ; PROC LK HL,PUT_SUB_COORD ;Point at cursor positioning ;string for sub menu LD A,SIDE ;Are we on sub menu side? CMP 1 ; JRZ :SUB_SIDE ;Yes...position cursor there ; ;No. LK HL,PUT_CURSOR ;Point at cursor positioning ;string for main menu. :SUB_SIDE: CALL OUT_STRING ;Position cursor RET ;and return PAGE CMD_DESC: ; Display command description for currently selected command. ; Command description is NOT re-displayed if it has already been ; displayed. ; ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; den the screen. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,CLR_SCR LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE GET_CHAR: ; Wait for user to enter char. ; Uses BDOS direct console I/O so no chars are filtered. ; ; ENTRY: ; None. ; EXIT: ; A = character entered. ; LK E,0FFh ;Ask BDOS for a char LK C,6 CALL BDOS ;BDOS returns 0 if no chars CMP 0 ;Is there a char? JRZ GET_CHAR ;No, ask again. RET ;Yes. Return. PAGE OUT_STRING: ; Send string pointed to by HL to console. String is terminated in a ; byte of 0. ; ; ENTRY: ; HL ==> string ; EXIT: ; None. ; LD A,[HL] ;Load current char INC HL ;Bump ptr to next char CMP 0 ;Is current byte 0 (end of string)? RZ ;Yes, return ; LK C,2 ;No, tell BDOS to send char to console MOV E,A PUSH HL ;Save ptr to next char in string CALL BDOS POP HL ;Restore ptr JR OUT_STRING ;and do next char... PAGE SET_CURSOR: ; Place the cursor next to the currently selected optire old line # CALL UN_HI_CR ;Un highlight current LD A,Y_COORD ;load line # of current CALL HI_CURR ;Highlight it CALL CMD_DESC ;Display description for current ;command CALL SET_CURSOR ;Place cursor next to current RET ;selection and return. ; :AT_BOTTOM: ;Current selection is the bottom one. ;Can't move down any more. CALL BEEP ;Ring bell RET ;and return. PAGE MOVE_RIGHT: ; Move right not implemented. ; LD A,NUM_SUB_CMDS CMP 0 JRZ :6 ;NO SUB MENU ! LD A,SIDE CMP 1 JRZ :6 LK A,1 STO A,SIDE LK A,32 STO A,Y_SUB_COORD CALL SET_CURSOR RET :6: CALL BEEP RET PAGE MOVE_LEFT: ; Move left not implemented. ; LD A,SIDE CMP 0 JRZ :7 LK A,0 STO A,SIDE CALL SET_CURSOR RET :7: CALL BEEP RET PAGE BEEP: ; Ring the bell as a warning. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,BELL_Char LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE CLS: ; Clear the current window o ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC LK HL,Y_COORD ;Point at line # for main menu LD A,SIDE ;Are we on the main menu side? CMP 0 JRZ :LEFT ;Yes... ; ;No. LK HL,Y_SUB_COORD ;Point at line # for sub-menu LD A,NUM_SUB_CMDS ;Load # of sub-commands. ADD A,31 ;Bias by 32 MOV B,A ;and save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same (are we at bottom)? JRZ :AT_BOTTOM ;Yes... ; JR :9 ;No... ; :LEFT: ;Main menu is current. ; ; Are we at bottom? ; LD A,NUM_OPTIONS ;Load total # of commands ADD A,31 ;Bias by 32 MOV B,A ;save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same? JRZ :AT_BOTTOM ;Yes...at bottom already... ; :9: ;Not at bottom yet. PUSH AF ;Save line # of old setting INC A ;Bump to next one down STO A,[HL] ;Save in appropriate data structure ;(main or sub) POP AF ;Resto(sub command side) LK HL,Y_SUB_COORD ;Point at line # for sub menu. :LEFT: LD A,[HL] ;Load line # of current selection CMP 32 ;Are we at top? JRZ :AT_TOP ;Yes... ; ;No. PUSH AF ;Save line number of old selection DEC A ;Compute and save new selection STO A,[HL] POP AF ;Restore line # of old selection CALL UN_HI_CR ;Un highlight it LD A,Y_COORD ;Load line # of current CALL HI_CURR ;and highlight it CALL CMD_DESC ;Print description for new command CALL SET_CURSOR ;Place cursor next to current selection RET ;and return ; :AT_TOP: ;Can't go up 'cause we're already at ;top. CALL BEEP ;Ring the bell RET ;and return PAGE MOVE_DOWN: ; User entered cursor down key. Make selection below the current in menu ; the new current selection if the botttom most selection is not already ; current. In other words, move down if not at bottom. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen.$A% ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC LK HL,Y_COORD ;Point at line # for main menu LD A,SIDE ;Are we on the main menu side? CMP 0 JRZ :LEFT ;Yes... ; ;No. LK HL,Y_SUB_COORD ;Point at line # for sub-menu LD A,NUM_SUB_CMDS ;Load # of sub-commands. ADD A,31 ;Bias by 32 MOV B,A ;and save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same (are we at bottom)? JRZ :AT_BOTTOM ;Yes... ; JR :9 ;No... ; :LEFT: ;Main menu is current. ; ; Are we at bottom? ; LD A,NUM_OPTIONS ;Load total # of commands ADD A,31 ;Bias by 32 MOV B,A ;save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same? JRZ :AT_BOTTOM ;Yes...at bottom already... ; :9: ;Not at bottom yet. PUSH AF ;Save line # of old setting INC A ;Bump to next one down STO A,[HL] ;Save in appropriate data structure ;(main or sub) POP AF ;Restore old line # CALL UN_HI_CR ;Un highlight current LD A,Y_COORD ;load line # of current CALL HI_CURR ;Highlight it CALL CMD_DESC ;Display description for current ;command CALL SET_CURSOR ;Place cursor next to current RET ;selection and return. ; :AT_BOTTOM: ;Current selection is the bottom one. ;Can't move down any more. CALL BEEP ;Ring bell RET ;and return. PAGE MOVE_RIGHT: ; Move right not implemented. ; LD A,NUM_SUB_CMDS CMP 0 JRZ :6 ;NO SUB MENU ! LD A,SIDE CMP 1 JRZ :6 LK A,1 STO A,SIDE LK A,32 STO A,Y_SUB_COORD CALL SET_CURSOR RET :6: CALL BEEP RET PAGE MOVE_LEFT: ; Move left not implemented. ; LD A,SIDE CMP 0 JRZ :7 LK A,0 STO A,SIDE CALL SET_CURSOR RET :7: CALL BEEP RET PAGE BEEP: ; Ring the bell as a warning. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,BELL_Char LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE CLS: ; Clear the current window on the screen. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,CLR_SCR LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE GET_CHAR: ; Wait for user to enter char. ; Uses BDOS direct console I/O so no chars are filtered. ; ; ENTRY: ; None. ; EXIT: ; A = character entered. ; LK E,0FFh ;Ask BDOS for a char LK C,6 CALL BDOS ;BDOS returns 0 if no chars CMP 0 ;Is there a char? JRZ GET_CHAR ;No, ask again. RET ;Yes. Return. PAGE OUT_STRING: ; Send string pointed to by HL to console. String is terminated in a ; byte of 0. ; ; ENTRY: ; HL ==> string ; EXIT: ; None. ; LD A,[HL] ;Load current char INC HL ;Bump ptr to next char CMP 0 ;Is current byte 0 (end of string)? RZ ;Yes, return ; LK C,2 ;No, tell BDOS to send char to console MOV E,A PUSH HL ;Save ptr to next char in string CALL BDOS POP HL ;Restore ptr JR OUT_STRING ;and do next char... PAGE SET_CURSOR: ; Place the cursor next to the currently selected option. ; ; ENTRY: ; SIDE = 0 if on main menu side (always true in COPY) ; PUT_CURSOR is a cursor positioning string which is patched with ; the line number of the current selection (relative 32) in Y_COORD. ; ; EXIT: ; None. ; PROC LK HL,PUT_SUB_COORD ;Point at cursor positioning ;string for sub menu LD A,SIDE ;Are we on sub menu side? CMP 1 ; JRZ :SUB_SIDE ;Yes...position cursor there ; ;No. LK HL,PUT_CURSOR ;Point at cursor positioning ;string for main menu. :SUB_SIDE: CALL OUT_STRING ;Position cursor RET ;and return PAGE CMD_DESC: ; Display command description for currently selected command. ; Command description is NOT re-displayed if it has already been ; displayed. ; ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; de;.Date: 10/22/84 ;.Last modified: David Andrew Berg ;.Title: COPYSYS ;.Comments: Rev 1.2 ; ; +---------------+ ; | | ; | COPYSYS | ; | | ; +---------------+ ; ; (c) 1983 Osborne Computer Corporation, ; 26538 Danti Court, ; Hayward, CA 94545 ; ; This revision copies all three system tracks (120 128 byte logical ; sectors) of an OCC double density disk and copies the file CPM3.SYS ; from the source to the destination drive. ; ; Since the file copy routine uses BDOS functions supported only ; under CP/M Plus, the program will abort if CP/M Plus is not ; running. ; ; Revision history: ; 3/15/83: ; a. Implemented redesign to handle all error conditions within program. ; This program should never exit to CP/M unexpectedly. Per SPRs #127, 162 ; ; b. Read and write error messages were made consistent, per SPR #137 ; ; 3/16/83: ; a. Changed all ESC-w references to ESC-VWDEF. VWDEF is defined in the ; systext file for the correct Window Define char. Per SPR #225 ; ; b. In%A&stalled code to verify system tracks for correctness as does ; the ROM boot loader. Per SPR # ; ; c. Removed (c) from sign-on message, per SPR #103 ; ; d. Changed character wait routines to only accept character specified ; in message on screen (e.g., only RETURN is accepted if it is ; specified). Per SPR # ; ; e. Installed final release version numbers. ; ;3/21/83: ; a. Installed new, clearer error messages indicating operation has ; been aborted. ; ; b. Final release of V1.0 (3.080) ; ;10/1/84: ; a. Installed support for Vixen compatible dsdd disks. ; ;10/22/84: ; a. Accomodated flaw in BDOS. When CCP.COM and ALTFONT.SYS are ; opened to read the system, the corresponding FCB is set according ; to the file status of the existing file. Thus, if ; the source file is R/O and SYS (as it normally is), when it is ; opened for writing on the destination drive, it is opened R/O ; and SYS. When the file is written to, the write fails since the ; file is R/O. This is fixed by always resetting the FCB to ; R/W and DIR. ; page ; Assembly Constants and definitions. LINK RAMS10.ASM ;RAM memory locations and constants 2.21 ; ; Conditional assembly equates: ; ; ; Generation toggles: ; BETA_TEST = true ; ; ROM terminal emulation supported: ; IF BETA_TEST TVI950 = false ENDIF IF NOT BETA_TEST TVI950 = true ENDIF TVI912 = not TVI950 ; ; ROM entry points: ; SEN_RTN = 160h ;SENDEN RD_RTN = 15Ah ;Read WRT_RTN = 15Dh ;Write DOUBTYP = 0CH ;DOUBLE DENSITY OSBORNE SAVTYP DOUBSEC = 5 ;# OF SECTORS/TRACK FOR OSBORNE DOUBLE DENSITY N128B 12 ;NUMBE O 12 BYT BLOC I TH SYSTE 2.21b DSTYP = 0Eh ;Vixen dsdd type 841001 DSSEC = 5 ;Vixen dsdd sectors/trk 841001 NDISKS = 2 ;Maximum supported disk drives SECSIZ = 128 ;SIZE OF CP/M LOGICAL SECTOR CONI = 1 ;CONSOLE INPUT FUNCTION CONO = 2 ;CONSOLE OUTPUT FUNCTION PAGE ; ; BDOS function numbers: ; PR_STR_FN = 9 ;BDOS print string function OS_VER_FN = 12 ;BDOS version number function SRC_FIRST = 17 ;BDOS search for first matching file ; ; Macro definitions: ; PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; ; Character definitions: ; CTRL_G = 'G' - 40h CTRL_H = 'H' - 40h CTRL_J = 'J' - 40h CTRL_K = 'K' - 40h CTRL_L = 'L' - 40h CTRL_S = 'S' - 40h CTRL_Z = 'Z' - 40h ;Control-Z ; ; Executive definitions: ; CP_RG_CH = CTRL_S ;Copyright character ;VEGH ;Clear Graphics mode esc seqn defined in ;systext ;VSGH ;Set Graphics mode esc seqn defined in ;systext ;VWDEF ;Define window escape seqn defined in systext ; ; CP/M definitios: ; WBOOTE = 0000H ;Warm boot emtry point TPA_Base = 0100h ;Base of TPA EOF_Mark = CTRL_Z ;CP/M logical end-of-file marker CPM_PLUS = 30h ;Value returned by function 12 is greater than ;or equal to this if running CP/M Plus. ; ; Console definitions: ; BELL_Char = CTRL_G ;Char to ring bell. CLR_SCR = CTRL_Z ;Char to clear screen (or current window) ; ; Keyboard definitions: ; RAW_UP = 8ah ;Untranslated cursor up char RAW_DOWN = 8ch ;Untranslated cursor down char PAGE ORG TPA_Base ;Start code at base of TPA JMP START ;Jump around copyright and version stamp ;to start of code. JMP SETW0 ;Utility to set window 0 for debugging 841004 ; ; Copyright and version stamp: ; DB cr,lf DB ' Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation,',cr,lf DB ' 26538 Danti Court, Hayward, CA 94545.',cr,lf DB ' V1.1',EOF_Mark SETW0: LK HL,W0SET ; 841004 CALL OUT_STRING ; 841004 RET ; 841004 W0SET: DB ESC,'s0',0 ; 841004 PAGE START: ;Start of COPY main program. LDK SP,STACK ;Set up local stack PROC ; ; Make sure CP/M Plus is running. ; LK C,OS_VER_FN ;Get OS version # CALL BDOS MOV A,H ;Check for H = 0 OR A JNZ :OS_BAD ;H ne 0, not running CP/M ; MOV A,L ;Check for L => 30 CMP CPM_PLUS ; JNC :OS_OK ;L => 30... ; :OS_BAD: ;Not running CP/M 3.X or greater LK HL,OS_BAD_MSG ;Print message and quit CALL OUT_STRING JMP 0 ;Warm Boot... ; :OS_OK: ;OS ok, continue... LK E,0FFh ;Set BDOS error mode to RETURN ERROR LK C,2Dh CALL SYS ; ; Fall through to screen driver... ; PAGE ; Menu screen driver begins here: ; BDOS EQU 0005h ;BDOS entry point UP EQU CTRL_K ;TVI character for cursor up DOWN EQU CTRL_J ;TVI char for cursor down RIGHT EQU CTRL_L ;TVI char for cursor right LEFT EQU CTRL_H ;TVI char for cursor left ENTER EQU cr ;Char entered by user to execute command PAGE PROC START1: ; ; Driver initialization code: ; CALL SET_STUFF ;Initialize windows used by driver LK HL,SCR_TOP ;Display program name and vers num CALL OUT_STRING LK HL,COPYR_MSG ;Display copyright message CALL OUT_STRING CALL SET_M1 ;Make current menu menu #1: main &A'menu: ;Select copy or format :COPYSYS: ; ; Return point for driver function execution ; ; ; See if current menu has already been displayed: ; LD DE,MAIN ;Load address of current menu LD HL,OLD_MN ;and compare with address of last ;menu displayed. STC CMC SBC HL,DE JZ :NO_DSP ;Menu already displayed, don't re- ;display. ; STO DE,OLD_MN ;Menu must be displayed. Save address ;of menu as last displayed. INC DE ;Bump ptr past address of command INC DE ;string table to start of menu display ;data. LK C,PR_STR_FN ;Tell BDOS to print it. CALL BDOS LD A,Y_COORD ;Hilight default selection CALL HI_CURR LK HL,DIR_MSG ;Display arrow key directions CALL OUT_STRING CALL CMD_DESC ;Display command description for ;this menu's default selection CALL SET_CURSOR ;Set cursor next to default selection. ; ; Branch point if current menu already displayed: ; :NO_DSP: LK DE,:COPYSYS ;Load address of top of driver loop  PUSH DE ;and push on stack as return address ;for the next user command. ; ; Wait for user to enter char and process accordingly: ; :GET_CH: ;Return here if invalid char entered. CALL GET_CHAR ;Wait for char to A CMP UP ;Is it TVI cursor up char? JZ MOVE_UP ;Yes, move up. ; ;No. CMP RAW_UP ;Is it raw (untranslated) up char? JZ MOVE_UP ;Yes, move up. ; CMP DOWN ;Is it TVI move down? JZ MOVE_DOWN ;Yes... ; ;No. CMP RAW_DOWN ;Is it raw down char? JZ MOVE_DOWN ;Yes... ; ; CMP RIGHT ;Horizontal motion not supported. ; JZ MOVE_RIGHT ; CMP 08Bh ; JZ MOVE_RIGHT ; CMP LEFT ; JZ MOVE_LEFT ; CMP 08Dh ; JZ MOVE_LEFT ; CMP ENTER ;Is it enter command? JZ DO_COMMAND ;Yes, process current command. ; CALL BEEP ;Char invalid. Ring bell. JMP :GET_CH ;and wait for another char... ; ; Local storage to save address of last menu displayed. ; OLD_MN: DW 0 PAGE SET_STUFF: ; Initialize driver: set up necessary windows. Disable function key ; translation. ; ; ENTRY: ; None. ; EXIT: ; Windows initialized. ; LK HL,INIT_STRING ;Point at window init string. CALL OUT_STRING ;Send it to console LK HL,XL_OFF ;Point at fn key xlate off string CALL OUT_STRING ;send it RET ;and return. ; INIT_STRING: ;Windows for screen driver. Window 4 is defined on ;the fly to display command string in reverse video. ; ; Window 1 is used for current menu: ; DB ESC,VWDEF,'1',32+5 ,32+20 ,32+12 ,32+80 ; ; Window 2 is used for completion or error message reporting: ; DB ESC,VWDEF,'2',32+20 ,32 ,32+23 ,32+80 ; ; Window 3 is used for execution status while performing commands ; (such as copy or format): ; DB ESC,VWDEF,'3',32+13,32,32+19,32+80 ; ; Window 5 is used for general directions applicable to all commands: ; DB ESC,VWDEF,'5',32+10,32+0,32+16,32+80 ; ; Window 6 is used for command specific directions: ; DB ESC,VWDEF,'6',32+13,32+0,32+16,32+80 ; ; Reselect window zero after defining windows: ; DB ESC,'s','0','Z'-040h D 0 ; ; String to disable fn. key xlate: ; XL_OFF: IF TVI950 DB 0 ENDIF IF TVI912 DB ESC,'f',0 ENDIF ; ; String to define window 4: ; W_STR: DB ESC,VWDEF,'4' ;String to define window used for W_PCH_1: DB 32+6,32+20 ;displaying cmd string in reverse W_PCH_2: DB 32+15,32+80,0 ;video PAGE MOVE_UP: ; User entered cursor up key. Make selection above the current in menu ; the new current selection if the top most selection is not already ; current. In other words, move up if not at tup. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC L HL,Y_COOR ;Poin a lin o curren selection ;for 'main' menu. LD A,SIDE ;What side are we on (left or right)? CMP 0 ; JRZ :LEFT ;We're on left (main) side... ; ;We're on right (sub command side) LK HL,Y_SUB_COORD ;Point at line # for sub menu. :LEFT: LD A,[HL] ;Load line # of current selection CMP 32 ;Are we at top? JRZ :AT_TOP ;Yes... ; ;No. PUSH AF ;Save line number of old selection DEC A ;Compute and save new selection STO A,[HL] POP AF ;Restore line # of old selection CALL UN_HI_CR ;Un highlight it LD A,Y_COORD ;Load line # of current CALL HI_CURR ;and highlight it CALL CMD_DESC ;Print description for new command CALL SET_CURSOR ;Place cursor next to current selection RET ;and return ; :AT_TOP: ;Can't go up 'cause we're already at ;top. CALL BEEP ;Ring the bell RET ;and return PAGE MOVE_DOWN: ; User entered cursor down key. Make selection below the current in menu ; the new current selection if the botttom most selection is not already ; current. In other words, move down if not at bottom. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen.'A