w% %:(<%R$Hͥ:(>(~c!o#~E%^#V)$G#~#~!%~ b%% k%%##N#F#^#V#~#fo~o!o#~>T}! 6**#K" G*~ xr ͐-xą@7(͚S!ʀq&&͋"&@6,͚%Xͤ͋&͗wO~<:( g&~w#w#6##)͋&@ * g&~?G++N͆p# Þ&͐*6!¿&?~p*6 &>2ͱ ! ! ͷ w*o!(s#r#p*k(N#F*m(^#V#F*(:(O}|y9*( +"*( }|yP#9*( *(DM"(*k(s#r*m(s#r#pyoxg͝DM*(0MD"(!*MD$:(Oë!(N:( «G>O:( ù* :(n` ~#foͤ2(O"(}:(O*( "(2("(:(O:(G2(!(w*~zWw+ !z?#~*!* *G!O~2(~m͗O~t>2(?:(2(O:(w:Ғ4~:(w?r##rp# ä |g}oì*g( #G ¾1*q(:(*w***> r ~Gw#* #~$%+@*9> # #>? ;*~ w-xąH"(0 *(#ĊH( ,ˆʀHÈ2(xą ):(@O~#w͚ʀôb_++V@* )͗Os++r!x>w~6:(6~#+w#w+~;wɯ2 K,OFq-yl?Npg&:(ʓ~†wŒ~è# # x ͗w w@ ~wb͐Ú̀!~$6:03i"!~6*e(>=)Q!(QX<k*{(}<^#V{!~! _*o(~s̓  2@ !()#w*~"!!(Fw̓ :(w̚":>#2(̓ *~wć"#Fx T]## #~ ȷ   *4 # '  4 !( *~^ ^ 33G# P v :dv 6 y #*~w>2 *p@! ~*"v@*w# ) 6# ͙   !N(w'ͧ B pͧ ,Úgsr ͐-ͤ͜!S')_'ͤ̓ ~?w͐s-?F͜p!'̓ ¡'>2ͱ ?~¾'¾''''>w'͙ =2(͜!:(wÚ~̓ ʑ'pá'!(6NN!(r )!(N !)z<*)$"!" :X(*:(w:(w#:(w*2* }D#cdfg!"()*)e(:(O!*c(:(Oͫ}@2æ  ~á *g(:(o$*~K6?~wKw**i({#zir+s{ozg*(*(|g͸*u(*(  R>22Z$w*q(>ww:(c( *(#*i(s#r*:(!(:G~#<*q(#~!;(!(!(!~6k!"2(*q(N1q*{(]*{([*y(}<^#V(t6 ^#V}e ^#V#~2(>â9͆>!"(*y(³*(X)*ÿ͂"*g(*K! ~<:wb##>w#w> r !~#<!"*>o+"! *!b("": r#~?w#>r# L=J! Lv w,b ?~O ͆=: <>w##~2( 4~?¹:(<üAX2(r K:(w++~=wv 4͗O5:(2(X:(!(v q: v v Mڂ?Ͷ >T͓Â!"(>(Â:(G:(O:(h=2(7ryy/W!(:(lڈ>F6:(_/G:(ʧ:(ڨ|OͤG:(_OzW{|:(*(}|BKN zyG)@ u :G*g(`~!x_<_@!*o(y<:(/G?~##~? 6!K@?F6##N6 2 p##q:r !Z$2!"ög:(2T͐-:ʹ!>2<2(!!(w: >2(*6!O~2(+A@2! ͚A=: <%~?¯"k"?~?ʾ"ZT͐"*>o"͒"!:O"(Ý"͐6͚ ; CALLVERS program bdos equ 5 ; entry point for BDOS prtstr equ 9 ; print string function vers equ 12 ; get version function cr equ 0dh ; carriage return lf equ 0ah ; line feed org 100h mvi d,5 ; Perform 5 times loop: push d ; save counter mvi c,prtstr lxi d,call$msg ; print call message call bdos mvi c,vers call bdos ; try to get version # ; CALLVERS will intercept mov a,l sta curvers pop d dcr d ; decrement counter jnz loop mvi c,LOADER 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#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# !( | title 'Character I/O handler for z80 chip based system' ; Character I/O for the Modular CP/M 3 BIOS ; limitations: ; baud rates 19200,7200,3600,1800 and 134 ; are approximations. ; 9600 is the maximum baud rate that is likely ; to work. ; baud rates 50, 75, and 110 are not supported public ?cinit,?ci,?co,?cist,?cost public @ctbl maclib Z80 ; define Z80 op codes maclib ports ; define port addresses maclib modebaud ; define mode bits and baud equates max$devic0 jmp bdos call$msg: db cr,lf,'**** CALLVERS **** $' curvers db 0 end function cr equ 0dh ; carriage return lf equ 0ah ; line feed org 100h mvi d,5 ; Perform 5 times loop: push d ; save counter mvi c,prtstr lxi d,call$msg ; print call message call bdos mvi c,vers call bdos ; try to get version # ; CALLVERS will intercept mov a,l sta curvers pop d dcr d ; decrement counter jnz loop mvi c,;!"Ï:= 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 !PROF !( : 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 #:es equ 6 cseg ?cinit: mov a,c ! cpi max$devices ! jz cent$init ; init parallel printer rnc ; invalid device mov l,c ! mvi h,0 ; make 16 bits from device number push h ; save device in stack dad h ! dad h ! dad h ; *8 lxi d,@ctbl+7 ! dad d ! mov l,m ; get baud rate mov a,l ! cpi baud$600 ; see if baud > 300 mvi a,44h ! jnc hi$speed ; if >= 600, use *16 mode mvi a,0C4h ; else, use *64 mode hi$speed: sta sio$reg$4 mvi h,0 ! lxi d,speed$table ! dad d ; point to counILE.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 $No File$ required$ERASE $ (Y/N)? $ Press RETURN to Continue $ (User 0)$NON-SYSTEM FILE(S) EXIST$: $$$ SUB<Ü 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 #:ter entry mov a,m ! sta speed ; get and save ctc count pop h ; recover lxi d,data$ports ! dad d ; point at SIO port address mov a,m ! inr a ! sta sio$port ; get and save port lxi d,baud$ports-data$ports ! dad d ; offset to baud rate port mov a,m ! sta ctc$port ; get and save lxi h,serial$init$tbl jmp stream$out cent$init: lxi h,pio$init$tbl stream$out: mov a,m ! ora a ! rz mov b,a ! inx h ! mov c,m ! inx h outir jmp stream$out ?ci: ; character input mov a,b ! 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#wEMP lda V3FLG cpi TRUE lda TEMP jnz TRK2 ; mvi a,00h sta BREG ;zero out B register mov a,c ;Acc = track # sta CREG ;set up PB mvi a,SETTRK ;settrk func # sta BIOSFC mvi c,DRBIOS lxi d,BIOSPB jmp BDOS TRK2: lhld WBOOT lxi d,SETTRK call MLTBY3 dad d pchl ;gone to set track ; SEC: ; Set up sector number sta TEMP lda V3FLG cpi TRUE lda TEMP jnz SEC2 ; mvi a,00h sta BREG ;zero out BREG mov a,c ; Acc = C sta CREG ;CREG = sector # mvi a,SETSECading CRLF push d call CRLF pop d ;drop through to OUTMSG OUTMSG: mvi c,9 jmp BDOS ; SELCT: ; Select disk given by rA mvi c,0Eh jmp BDOS ; DWRITE: ; Write for file copy mvi c,DWRITF jmp BDOS ; DREAD: ; Disk read function mvi c,DREADF jmp BDOS ; OPEN: ; File open function mvi c,OPENF jmp BDOS ; CLOSE: mvi c,CLOSEF jmp BDOS ; MAKE: mvi c,MAKEF jmp BDOS ; DELETE: mvi c,DELTEF jmp BDOS ; ; ; DSTDMA: mvi c,26 jmp BDOS ; SOURCE: lxi d,GETPRM ;s already selected lxi h,LOADP ;load point in RAM for DMA address shld DMADDR ; ; ; ; ; Clear track 00 mvi a,-1 ; sta TRACK ; RWTRK: ; Read or write next track lxi h,TRACK inr m ;track = track+1 lda OST ;# of OS tracks cmp m ;=track # ? jz ENDRW ;end of read/write ; ; Otherwise not done mov c,m ;track number call TRK ;set to track mvi a,-1 ;counts 0,1,2,...,25 sta SECTOR ; RWSEC: ; Read or write a sector lda SPT ;sectors per track lxi h,SECTOR inr mnumber to check compatability mvi c,12 ;version check call BDOS mov a,l ;version in Acc cpi 30h ;version 3 or newer? jc OLDRVR ; mvi a,TRUE sta V3FLG ; jmp FCBCHK OLDRVR: mvi a,FALSE sta V3FLG ; ; Check for default file liad instead of get FCBCHK: lda FCB+1 ;blank if no file cpi ' ' jz GETSYS ;skip to system message lxi d,FCB ;try to open it call OPEN inr a ;255 becomes 00 jnz RDOK ; ; File not present lxi d,NOFILE call CRMSG jmp REBOOT ; ;file prese sta BIOSFC ;set up bios call mvi c,DRBIOS lxi d,BIOSPB jmp BDOS SEC2: lhld WBOOT lxi d,SETSEC call MLTBY3 dad d pchl ; DMA: ; Set DMA address to value of BC sta TEMP lda V3FLG cpi TRUE lda TEMP jnz DMA2 ; mov a,b ; sta BREG ; mov a,c ;Set up the BC sta CREG ;register pair mvi a,SETDMA ; sta BIOSFC ;set up bios # mvi c,DRBIOS lxi d,BIOSPB jmp BDOS DMA2: lhld WBOOT lxi d,SETDMA call MLTBY3 dad d pchl ; READ: ; Perform read operation staask user for source drive call CRMSG call GETCHAR ;obtain response cpi CR ;is it CR? jz DFLTDR ;skip if CR only cpi CTLC ;isit ^C? jz REBOOT ; sui 'A' ;normalize drive # cpi NDISKS ;valid drive? jc GETC ;skip to GETC if so ; ; Invalid drive call BADDISK ;tell user bad drive jmp SOURCE ;try again ; GETC: ; Select disk given by Acc. adi 'A' sta GDISK ;store source disk sui 'A' mov e,a ;move disk into E for select func call SEL ;select the disk jmp GETVER ; ;set to next sector cmp m ;A=26 and M=0,1,..,25 jz ENDTRK ; ; Read or write sector to or from current DMA address lxi h,SECTOR mov e,m ;sector number mvi d,0 ;to DE lxi h,TRAN mov b,m ;tran(0) in B dad d ;sector translated mov c,m ;value to C ready for select push b ;save tran(0) call SEC pop b ;recall tran(0),tran(sector) mov a,c ;tran(sector) sub b ;--tran(sector) call MULTSEC ;*sector size xchg ;to DE lhld DMADDR ;base DMA dad d mov b,h mov c,l nt RDOK: xra a sta FCBCR ;current record = 0 lxi h,LOADP RDINP: push h mov b,h mov c,l call DMA ;DMA address set lxi d,FCB ;ready fr read call DREAD pop h ;recall ora a ;00 if read ok jnz PUTSYS ;assume eof if not ; More to read continue lxi d,SECSIZ dad d ;HL is new load address jmp RDINP ; GETSYS: call SOURCE ;find out source drive ; xra a ;zero out a sta RW ;RW = 0 to signify read call GETPUT ;get or read system lxi d,DONE ;end message of get or TEMP lda V3FLG cpi TRUE lda TEMP jnz READ2 ; mvi a,READF sta BIOSFC mvi c,DRBIOS lxi d,BIOSPB jmp BDOS READ