IMD 1.18: 9/11/2012 10:32:38 install II sb8-6.2-d2 cp/m-86 hinet serial# dasoft  *!>G :22!!:_ o(!!8>G^!:!q@'@>y>ycwcwF } (КϫҐ>8M P DMSZCPR Ver 1.1d (c) 1984 by Digital Microsystems, Inc.CҭF;˟* K*ѭ? ,>íCOM$$$  SUB_͌> ͒> Ò> Ò͘~#͌ì DIR LISTmTYPEqUSERDFU GO ERA GSAVEREN GET JUMP21wy_[2-y2o(#2-z>/=/2-:۷ )1wͭAʹYݷ( 8 >1ʹ0ʹ}2o:޷u~#fo: !޶No Fil> ʹ> _t(>(ʹ ͭ~ʹ~#  _2<!-~6z>_ Y݇!oݶ2>2a{_:-(Ez/(;:=2 /!P!6#5z6(>)ʹ!E=E_>>ʹ n!F#~tw6!"Y Qͭ*[~(ʹ#ݿE= 8=_.:;<>[Y o$! ~+ H(+!~ (#0 0Wy8 88Oy! ~ (-H()08 80#OzW{_W{_}!L~ɯ2:o#>=!oݾ!ۯ2?S[( @G:(:owx2p2F. Fg#6SY:۷"(#* 6?mw?m"#6 :<2!  # ### !~ ??(SYS > D 2>2W:̢(g=`O> բ J{ ͭ | x  >  (> ʹx 0 >.ʹ A 6?# AllY=ͭP>2?2("Y(ͭ>2!6!~8 8w4!L~  8 ( > x (=Æ!5 6>P(ʎQo&X1(:2?S()SY|(+! 6< :Delete FileYŽPX:!?= (#"Y G!~(p p21͢Æ_[Ñ2͏( 2_[!ޯ‚6!>ڼ8 =Ful>VVVVV!HIDOS11fs1K!""S{2!Ry)K!K_^#V*:(*6:( w:2{*}D:5y<( < ) m :!q$O͈2>>"ö!""2!"~?(~?Ě*"9 <('ͼ(R.p͆6ͱͼ9< ͼNÝ *Fp<(p ͧ9Ý*B:öSͼ(R*(*#͑ <(  ͧ9:Ͷ*": :ö2@~ *!r#r#r<( ͉͆_y#x#{8s+p+q9*}/_|/*W}_*"}o|g">2~Bdos Err On : $Bad Sector$Select$File R/O$ Not Locked$No Locks$ SHRALLOC$ͦ!T!{!s C :  :y!4 5~y 5 6y 0 ^C@Oy  C: ͢  #C<:! C:2*N# ʊ ʊ x(:2M x(~+v       <2 !>w :!05͚ ͧ 3ͧx( #Nx:!2͚!5 #wOx~x p Cͼ!bk6+!!"J6 !" `}* +" | !" **ͼf}*rror at !1YM+++Y!:: !Y~&oZ ^#V ZZ: 4   4       (%W͉!*ì:!͉!f::#:#*":2?2}FyE*+"}*"{WM!F !}F!"{$!F !!"yE!"{!"}>2{2z2zx2:2!L6 :NG 632 ÁÌ×âÿú1Ò×Üýæ %.á1m* f( # 4~?(#< :<(͒:<( Ϳ öͺà>2>2 :!8 2: ( = !ú>22~*s :Һd͔ͼ(R͸(d͊2(O ͧDMPYy( 0*{z0BK0O: ('* :(n& ^#V͊Oͧ"Ϳ}:*)= ":O:o"x2* *1>G^"":222O2M:2N:2H!@6#>2G!1:(!+ !2!" !# >+>@+>#># :(>22!:>( >3>3>3>3>P0>Z > > >*>*>+>+!1! M CP/M 2.249f L2:2!s:w+x!"X!w8>2!:( >82w2a:!L:o(5OXg( 5OKG(5OA:o(5O4W(5O*(5O G(5Og(5O O(OO!M4>82w2T]>2~0~#!A=1>G^>2!"20"12!"%1ͺ͗͜ ͒͗͜͡ ͡͡:O!Nv˶@N`:`|:`:N:_~#fovvvvvvvvvvvvvvvv !} >öͼN"* ::(͌sO s#r:@(ͼ(͑w!>222Ϳ::== :y== 3*Ww#*"=%*:G# "=%:!8w4 ͑w : !!~ =26!2[!!~!~2~2:2: O:w:w:O <:!<=()yoxg*8}!N#FE"͆ ~*Y* *:o$*~͑6͑w* ͆.%KK$*[!~#>2% (Xϫvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvs1!@:H4 6#><4 6#4 w#>4 w##4:w !~(5 g#{Ms1'(2͗{M(O*}&q<2*|<G>@(h&~!p*(y(+>j()+(y)">͆( "(y #>͢(!#(y!@@(  y:(w y yW~#~O~G#~G~. ^z[! w! y !x(6.:<(*! q!p͸:< . (͒.:<(ö͑6}2àN! ~态O~G!~G~0* ͉!!q#p#w:!w*:O2*[MD*":2:G[!N40MD!K$:  %*"͆ :(N N#Fy(*B@#>22!q*" :(TEE >1f(!M *** HALTed at !1+Yv~O͗#N͗# ͗ ͗~`#|`}i0:8O×:w /2w *** error key to abort, to retry, or to ignore FDC buf: Cmd Dsk Trk Hd Sec Den Max .+~L xy2.+~S y( 82!2.+~!Z( ( :!p#q2!yCy2CC.+~(`i# n&!".+~( (:2!o3w+:!u:G#*|!6(6*8}KE"ͼ(<>!>!>*!" "!6 <(2* *<#DM*6# x [*s#r͆>(: #~$ =2ͱ:w>2*~=20:2~2w:*wF+F+ F*#~O#y "&''[o|g""R(:(k*[R 2([͆:Oy(/?($x ( ( N:/GyO # :2!~:w>ö͚<~͆[ ͠! N!Fwyx(>8>*w~#+w#ÿ.<2!|/!:ހo&!!!9^#V!^)ZUA/!!9^#V!^!KU\/!!!/0*du{/!#~/!!9^#V!^+#V*ͱt!!9^#V#*ͱt!9^#V!^*s!9^#V!^*s!9^#V!^* Gap Len StatusENRDYfDATApTRACENDT ID ORUNSECTPROTDENS}MADRI/O ! ~#~# (####:NG >2L R}!1;!1R(!1!1!C!L6 !1͌   *** CALL error at !1! *** INT e(O3 xHH(,xo( y(:a:NG a> x aO#}y*"{*+"}2*":2:(:k[*R :G: [!W͉:!8![:(:r:0%W*"*"*W!FFSFFSSFFFFFFFFFFFFCopyright (c) 1983 Digital Microsystems vvvvvvvvw|8v2͹!6͚~͔:@p*#!""<(!w# ! w ͧ͠2:<* ~<w( G:!     SYSLIB1 OVRElmnop),3(dst(0)) endm codemacro FSTP dst:Mb segfix dst db 0d9h modrm 3,dst endm codemacro FSTP dst:Mw segfix dst db 0ddh modrm 3,dst endm codemacro FSTP nolist ; ***************************** ; * Codemacros for 8087 * ; * numeric data processor: * ; *************************** ; ; stack references: st equ 0 ; stack top (= register LMCMD CMD(UVWLMCMD COMXY8087 LIB[SB8-62 D2 SYSLIB2 OVRqrGIOSHNS 24OI789:;LDCPM A86,RST dst:Db(0,7) db 0ddh dbit 5(1bh),3(dst(0)) endm codemacro FSTPTR dst:M segfix dst db 0dbh modrm 7,dst endm codemacro FXCH dw 0c9d9h endm codemacro FXC0) st0 equ 0 ; register 0 st1 equ 1 ; register 1 st2 equ 2 ; register 2 st3 equ 3 ; register 3 st4 equ 4 ; register 4 st5 equ 5 ; register 5 st6 equ 6 INSTALL COM\<=>?@ARANDOM A868[\]^GENDEF CMDL-./01GENDEF COML23456LDCOPY A86ZLMNOPQSYSLIB7 OVRxyCBIOS A86RCMAP816 10 COPYDISKA86 !COPYDISKA86 "MSTEST ZCMAPHNS 10 SYSLIB COM`abcdefgSYSLIB COM?hijkH dst:Db(0,7) db 0d9h dbit 5(19h),3(dst(0)) endm codemacro FILD src:Mb segfix src db 0dbh modrm 0,src endm codemacro FILDLI src:Mw segfix src db ; register 6 st7 equ 7 ; register 7 ; ; codemacro FLD src:Mb segfix src db 0d9h modrm 0,src endm codemacro FLD src:Mw segfix src db 0ddh modrm 0LDBIOS A86BCDEFGHILDBIOS A86JKTBIOS A86z{|}~TBIOS A860SINGLES DEF_TRACK A868DISKCHK COM , 0dfh modrm 5,src endm codemacro FILD src:Mw segfix src db 0dfh modrm 0,src endm codemacro FIST dst:Mb segfix dst db 0dbh modrm 2,dst endm codema,src endm codemacro FLD src:Db(0,7) db 0d9h dbit 5(18h),3(src(0)) endm codemacro FLDTR src:M segfix src db 0dbh modrm 5,src endm codemacro FST dst:Mb BIOS A86 BIOS A86SYSLIB6 OVRwSYSLIB3 OVR)stucro FIST dst:Mw segfix dst db 0dfh modrm 2,dst endm codemacro FISTP dst:Mb segfix dst db 0dbh modrm 3,dst endm codemacro FISTPLI dst:Mw segfix ds segfix dst db 0d9h modrm 2,dst endm codemacro FST dst:Mw segfix dst db 0ddh modrm 2,dst endm codemacro FST dst:Db(0,7) db 0ddh dbit 5(1ahCPM86 #CPM86 13D{$%&'()*+SYSLIB4 OVRv     t db 0dfh modrm 7,dst endm codemacro FISTP dst:Mw segfix dst db 0dfh modrm 3,dst endm codemacro FBLD src:Mb segfix src db 0dfh modrm 4,s dw 0f8d9h endm codemacro FRNDINT dw 0fcd9h endm codemacro FXTRACT dw 0f4d9h endm codemacro FABS dw 0e1d9h endm codemacro FCHS dw 0e0d9h endm co) endm codemacro FDIVP dst:Db(0,7),src:Db(0) db 0deh dbit 5(1eh),3(dst(0)) endm codemacro FIDIV src:Mb segfix src db 0dah modrm 6,src endm codemacro FIDIV src:o FMUL dw 0c9d8h endm codemacro FMUL dst:Db(0),src:Db(0,7) db 0d8h dbit 5(19h),3(src(0)) endm codemacro FMUL src:Mb segfix src db 0d8h modrm 1,src e modrm 4,src endm codemacro FSUB dst:Db(0,7),src:Db(0) db 0dch dbit 5(1ch),3(dst(0)) endm codemacro FSUBP dst:Db(0,7),src:Db(0) db 0deh dbit 5(1ch),3(dst(0)) endm codemacrrc endm codemacro FBSTP dst:Mb segfix dst db 0dfh modrm 6,dst endm codemacro FADD dw 0c1d8h endm codemacro FADD dst:Db(0),src:Db(0,7) db 0d8h dbit demacro FCOM dw 0d1d8h endm codemacro FCOM src:Db(0,7) db 0d8h dbit 5(1ah),3(src(0)) endm codemacro FCOM src:Mb segfix src db 0d8h modrm 2,src endm Mw segfix src db 0deh modrm 6,src endm codemacro FDIVR dw 0f9d8h endm codemacro FDIVR dst:Db(0),src:Db(0,7) db 0d8h dbit 5(1fh),3(src(0)) endm codemacro ndm codemacro FMUL src:Mw segfix src db 0dch modrm 1,src endm codemacro FMUL dst:Db(0,7),src:Db(0) db 0dch dbit 5(19h),3(dst(0)) endm codemacro FMULP dst:Db(0o FISUB src:Mb segfix src db 0dah modrm 4,src endm codemacro FISUB src:Mw segfix src db 0deh modrm 4,src endm codemacro FSUBR dw 0e9d8h endm  5(18h),3(src(0)) endm codemacro FADD src:Mb segfix src db 0d8h modrm 0,src endm codemacro FADD src:Mw segfix src db 0dch modrm 0,src endm codemacro F codemacro FCOM src:Mw segfix src db 0dch modrm 2,src endm codemacro FCOMP dw 0d9d8h endm codemacro FCOMP src:Db(0,7) db 0d8h dbit 5(1bh),3(src(0))  FDIVR src:Mb segfix src db 0d8h modrm 7,src endm codemacro FDIVR src:Mw segfix src db 0dch modrm 7,src endm codemacro FDIVR dst:Db(0,7),src:Db(0) d,7),src:Db(0) db 0deh dbit 5(19h),3(dst(0)) endm codemacro FIMUL src:Mb segfix src db 0dah modrm 1,src endm codemacro FIMUL src:Mw segfix src db 0d codemacro FSUBR dst:Db(0),src:Db(0,7) db 0d8h dbit 5(1dh),3(src(0)) endm codemacro FSUBR src:Mb segfix src db 0d8h modrm 5,src endm codemacro FSUBR src:Mw ADD dst:Db(0,7),src:Db(0) db 0dch dbit 5(18h),3(dst(0)) endm codemacro FADDP dst:Db(0,7),src:Db(0) db 0deh dbit 5(18h),3(dst(0)) endm codemacro FIADD src:Mb segfix src endm codemacro FCOMP src:Mb segfix src db 0d8h modrm 3,src endm codemacro FCOMP src:Mw segfix src db 0dch modrm 3,src endm codemacro FCOMPP db 0dch dbit 5(1fh),3(dst(0)) endm codemacro FDIVRP dst:Db(0,7),src:Db(0) db 0deh dbit 5(1fh),3(dst(0)) endm codemacro FIDIVR src:Mb segfix src db 0dah modrm eh modrm 1,src endm codemacro FDIV dw 0f1d8h endm codemacro FDIV dst:Db(0),src:Db(0,7) db 0d8h dbit 5(1eh),3(src(0)) endm codemacro FDIV src:Mb segfix src  segfix src db 0dch modrm 5,src endm codemacro FSUBR dst:Db(0,7),src:Db(0) db 0dch dbit 5(1dh),3(dst(0)) endm codemacro FSUBRP dst:Db(0,7),src:Db(0) db 0deh  db 0dah modrm 0,src endm codemacro FIADD src:Mw segfix src db 0deh modrm 0,src endm codemacro FSUB dw 0e1d8h endm codemacro FSUB dst:Db(0),src:Db(w 0c9deh endm codemacro FICOM src:Mb segfix src db 0dah modrm 2,src endm codemacro FICOM src:Mw segfix src db 0deh modrm 2,src endm codemacro FICOM 7,src endm codemacro FIDIVR src:Mw segfix src db 0deh modrm 7,src endm codemacro FSQRT dw 0fad9h endm codemacro FSCALE dw 0fdd9h endm codemacro FPREM  db 0d8h modrm 6,src endm codemacro FDIV src:Mw segfix src db 0dch modrm 6,src endm codemacro FDIV dst:Db(0,7),src:Db(0) db 0dch dbit 5(1eh),3(dst(0) dbit 5(1dh),3(dst(0)) endm codemacro FISUBR src:Mb segfix src db 0dah modrm 5,src endm codemacro FISUBR src:Mw segfix src db 0deh modrm 5,src endm codemacr0,7) db 0d8h dbit 5(1ch),3(src(0)) endm codemacro FSUB src:Mb segfix src db 0d8h modrm 4,src endm codemacro FSUB src:Mw segfix src db 0dch      P src:Mb segfix src db 0dah modrm 3,src endm codemacro FICOMP src:Mw segfix src db 0deh modrm 3,src endm codemacro FTST dw 0e4d9h endm codemacro  ;| | lsts equ 41h ;2651 No. 0 on BLC8538 status port ldata equ 40h ; " " " " " data port blc_reset equ 60h ;reset selected USARTS on BLC8538 ;| | ;-----* Loader_bios is true if assembling the * ;* LOADER BIOS, otherwise BIOS is for the * ;* CPM.SYS file. Blc_list is true if we * ;* have a serial printer attached to BLC8538 * ;* Bdos_int is interrupt used for earlier * ;* versions.  endm FNSTSW equ FSTSW codemacro FCLEX dw 0e2dbh endm FNCLEX equ FCLEX codemacro FSAVE dst:M segfix dst db 0ddh modrm 6,dst endm FNSAVE equ FSAVE codemacro  FXAM dw 0e5d9h endm codemacro FPTAN dw 0f2d9h endm codemacro FPATAN dw 0f3d9h endm codemacro F2XM1 dw 0f0d9h endm codemacro FYL2X dw 0f1d9h ---------------------------------------- ENDIF ;blc_list ;********************************************* ;* * ;* Intel iSBC 204 Disk Controller Ports * ;* * ;* * ;* * ;********************************************* loader_bios equ false blc_list equ true bdos_int equ 224 ;reserved BDOS Interrupt IF not loader_bios ;------------------ title '8086 Disk I/O Drivers' ;********************************************* ;* * ;* Basic Input/Output System (BIOS) for * ;* CP/M-86 Configured for iSBC 86/12 with * ;* the iSBC 204 Floppy Disk Co FRSTOR src:M segfix src db 0ddh modrm 4,src endm codemacro FSTENV dst:M segfix dst db 0d9h modrm 6,dst endm FNSTENV equ FSTENV codemacro FLDENV src:M endm codemacro FYL2XP1 dw 0f9d9h endm codemacro FLDZ dw 0eed9h endm codemacro FLD1 dw 0e8d9h endm codemacro FLDPI dw 0ebd9h endm codemacro FLDL2T ******************************************** base204 equ 0a0h ;SBC204 assigned address fdc_com equ base204+0 ;8271 FDC out command fdc_stat equ base204+0 ;8271 in status fdc_parm equ base204+1 ;8271 out parameter fdc_rslt equ base204+1 ;8271 in --------------------------- ;| | bios_code equ 2500h ccp_offset equ 0000h bdos_ofst equ 0B06h ;BDOS entry point ;| | ;--------------------------------------------- ntroller * ;* * ;* (Note: this file contains both embedded * ;* tabs and blanks to minimize the list file * ;* width for printing purposes. You may wish* ;* to expand the blanks before performing * segfix src db 0d9h modrm 4,src endm codemacro FINCSTP dw 0f7d9h endm codemacro FDECSTP dw 0f6d9h endm codemacro FFREE dst:Db(0,7) db 0ddh db dw 0e9d9h endm codemacro FLDL2E dw 0ead9h endm codemacro FLDLG2 dw 0ecd9h endm codemacro FLDLN2 dw 0edd9h endm codemacro FINIT dw 0e3dbh endm FNINIresult fdc_rst equ base204+2 ;8271 out reset dmac_adr equ base204+4 ;8257 DMA base address out dmac_cont equ base204+5 ;8257 out control dmac_scan equ base204+6 ;8257 out scan control dmac_sadr equ base204+7 ;8257 out scan address dmac_mode equ baseENDIF ;not loader_bios IF loader_bios ;--------------------------------------------- ;| | bios_code equ 1200h ;start of LDBIOS ccp_offset equ 0003h ;base of CPMLOADER bdos_ofst equ 0406h ;stripped BDOS ent ;* major editing.) * ;********************************************* ; Copyright (C) 1980,1981 ; Digital Research, Inc. ; Box 579, Pacific Grove ; California, 93950 ; ; (Permission is hereby granted to use ; or abstractit 5(18h),3(dst(0)) endm codemacro FNOP dw 0d0ddh endm FWAIT equ WAIT list T equ FINIT codemacro FDISI dw 0e1dbh endm FNDISI equ FDISI codemacro FENI dw 0e0dbh endm FNENI equ FENI codemacro FLDCW src:Mw segfix src db 0d9h 204+8 ;8257 out mode dmac_stat equ base204+8 ;8257 in status fdc_sel equ base204+9 ;FDC select port (not used) fdc_segment equ base204+10 ;segment address register reset_204 equ base204+15 ;reset entire interface max_retries equ 10 ;max retries ory ;| | ;--------------------------------------------- ENDIF ;loader_bios csts equ 0DAh ;i8251 status port cdata equ 0D8h ; " data port IF blc_list ;--------------------------------------------- the following program in ; the implementation of CP/M, MP/M or ; CP/NET for the 8086 or 8088 Micro- ; processor) true equ -1 false equ not true ;********************************************* ;* * ; modrm 5,src endm codemacro FSTCW dst:Mw segfix dst db 0d9h modrm 7,dst endm FNSTCW equ FSTCW codemacro FSTSW dst:Mw segfix dst db 0ddh modrm 7,dst      n disk i/o ;before perm error cr equ 0dh ;carriage return lf equ 0ah ;line feed cseg org ccpoffset ccp: org bios_code ;********************************************* ;* * ;* BIOS Jump Vecto | ;--------------------------------------------- ENDIF ;blc_list ret LISTST: ;poll list status IF blc_list ;--------------------------------------------- ;| | in al,lsts and al,81h ;look ax ;get our data segment mov bx,offset int_trp call pmsg hlt ;hardstop ;| | ;--------------------------------------------- ENDIF ;not loader_bios ;********************************************* ;*  * ;********************************************* mov al,0FFh out blc_reset,al ;reset all usarts on 8538 mov al,4Eh out ldata+2,al ;set usart 0 in async 8 bit mode mov al,3Eh out ldata+2,al ;set usart 0 to 9600 baud mov al,37h  * ;********************************************* INIT: ;print signon message and initialize hardware mov ax,cs ;we entered with a JMPF so use mov ss,ax ; CS: as the initial value of SS:, mov ds,ax ; DS:, mov es,ax ; and ES: ;use local stacr for Individual Routines * ;* * ;********************************************* jmp INIT ;Enter from BOOT ROM or LOADER jmp WBOOT ;Arrive here from BDOS call 0 jmp CONST ;return console keyboard statust both TxRDY and DTR cmp al,81h jnz zero_ret ;either false, printer is busy or al,255 ;both true, LPT is ready ;| | ;--------------------------------------------- ENDIF ;blc_list ret PUNCH: ;not im * ;* CP/M Character I/O Interface Routines * ;* Console is Usart (i8251a) on iSBC 86/12 * ;* at ports D8/DA * ;* * ;********************** out ldata+3,al ;enable Tx/Rx, and set up RTS,DTR ;| | ;--------------------------------------------- ENDIF ;not loader_bios IF loader_bios ;--------------------------------------------- ;| k during initialization mov sp,offset stkbase cld ;set forward direction IF not loader_bios ;--------------------------------------------- ;| | ; This is a BIOS for the CPM.SYS file. ; Setup all inte jmp CONIN ;return console keyboard char jmp CONOUT ;write char to console device jmp LISTOUT ;write character to list device jmp PUNCH ;write character to punch device jmp READER ;return char from reader device jmp HOME ;move to trk 00 onplemented in this configuration READER: mov al,1ah ret ;return EOF for now GETIOBF: mov al,0 ;TTY: for consistency ret ;IOBYTE not implemented SETIOBF: ret ;iobyte not implemented zero_ret: and al,0 ret ;return zero in AL and fl*********************** CONST: ;console status in al,csts and al,2 jz const_ret or al,255 ;return non-zero if RDA const_ret: ret ;Receiver Data Available CONIN: ;console input call const jz CONIN ;wait for RDA in al,cdata and a | ;This is a BIOS for the LOADER push ds ;save data segment mov ax,0 mov ds,ax ;point to segment zero ;BDOS interrupt offset mov bdos_offset,bdos_ofst mov bdos_segment,CS ;bdos interrupt segment pop ds ;restorrrupt vectors in low ; memory to address trap push ds ;save the DS register mov ax,0 mov ds,ax mov es,ax ;set ES and DS to zero ;setup interrupt 0 to address trap routine mov int0_offset,offset int_trap mov int0_segment,CS mov di,4  cur sel drive jmp SELDSK ;select disk for next rd/write jmp SETTRK ;set track for next rd/write jmp SETSEC ;set sector for next rd/write jmp SETDMA ;set offset for user buff (DMA) jmp READ ;read a 128 byte sector jmp WRITE ;write a 128ags ; Routine to get and echo a console character ; and shift it to upper case uconecho: call CONIN ;get a console character push ax mov cl,al ;save and call CONOUT pop ax ;echo to console cmp al,'a' jb uret ;less than 'a' is ok cml,7fh ;read data and remove parity bit ret CONOUT: ;console output in al,csts and al,1 ;get console status jz CONOUT ;wait for TBE mov al,cl out cdata,al ;Transmitter Buffer Empty ret ;then return data LISTOUT: ;list device output e data segment ;| | ;--------------------------------------------- ENDIF ;loader_bios mov bx,offset signon call pmsg ;print signon message mov cl,0 ;default to dr A: on coldstart jmp ccp ;jump to colmov si,0 ;then propagate mov cx,510 ;trap vector to rep movs ax,ax ;all 256 interrupts ;BDOS offset to proper interrupt mov bdos_offset,bdos_ofst pop ds ;restore the DS register ;********************************************* ;*  byte sector jmp LISTST ;return list status jmp SECTRAN ;xlate logical->physical sector jmp SETDMAB ;set seg base for buff (DMA) jmp GETSEGT ;return offset of Mem Desc Table jmp GETIOBF ;return I/O map byte (IOBYTE) jmp SETIOBF ;set I/O p al,'z' ja uret ;greater than 'z' is ok sub al,'a'-'A' ;else shift to caps uret: ret ; utility subroutine to print messages pmsg: mov al,[BX] ;get next char from message test al,al jz return ;if zero return mov CL,AL call CONOUT  IF blc_list ;--------------------------------------------- ;| | call LISTST jz LISTOUT ;wait for printer not busy mov al,cl out ldata,al ;send char to TI 810 ;| d start entry of CCP WBOOT: jmp ccp+6 ;direct entry to CCP at command level IF not loader_bios ;--------------------------------------------- ;| | int_trap: cli ;block interrupts mov ax,cs mov ds,a * ;* National "BLC 8538" Channel 0 for a serial* ;* 9600 baud printer - this board uses 8 Sig-* ;* netics 2651 Usarts which have on-chip baud* ;* rate generators. * ;* map byte (IOBYTE) ;********************************************* ;* * ;* INIT Entry Point, Differs for LDBIOS and * ;* BIOS, according to "Loader_Bios" value * ;*       ;print it inc BX jmps pmsg ;next character and loop ;********************************************* ;* * ;* Disk Input/Output Routines * ;* * ;********************************** send_com: in al,fdc_stat test al,80h ;insure command not busy jnz send_com ;loop until ready ;see if we have to initialize for a DMA operation mov al,1[bx] ;get command byte cmp al,12h jne write_maybe ;it_ready jz nrdy01 ;now loop until drive ready jmps retry ;then go retry without decrement zret: and al,0 ret ;return with no error code wboot_l: ;can't make it w/ a short leap jmp WBOOT ;********************************************* ;*busy" and al,0fh cmp al,0ch ;unless there isn't mov al,0 ja exec_exit ; any result ;poll for bits in CH, exec_poll: ; toggled with bits in CL in al,fdc_stat ;read status and al,ch xor al,cl ; isolate what we want to poll jz exec_p GETSEGT: ;return address of physical memory table mov bx,offset seg_table ret ;********************************************* ;* * ;* All disk I/O parameters are setup: the * ;* Read and Write entry****************************************** SELDSK: ;select disk given by register CL mov bx,0000h cmp cl,2 ;this BIOS only supports 2 disks jnb return ;return w/ 0000 in BX if bad drive mov al, 80h cmp cl,0 jne sel1 ;drive 1 if not zero f not a read it could be write mov cl,40h jmps init_dma ;is a read command, go set DMA write_maybe: cmp al,0ah jne dma_exit ;leave DMA alone if not read or write mov cl,80h ;we have write, not read init_dma: ;we have a read or write operatio * ;* The i8271 requires a read status command * ;* to reset a drive-not-ready after the * ;* drive becomes ready * ;* * ;*****************oll ;and loop until it is done ;Operation complete, in al,fdc_rslt ; see if result code indicates error and al,1eh jz exec_exit ;no error, then exit ;some type of error occurred . . . cmp al,10h je dr_nrdy ;was it a not ready drive ?  points transfer one * ;* sector of 128 bytes to/from the current * ;* DMA address using the current disk drive * ;* * ;********************************************* READ: mov al,12h ;basic read sectormov al, 40h ;else drive is 0 sel1: mov sel_mask,al ;save drive select mask ;now, we need disk parameter address mov ch,0 mov bx,cx ;BX = word(CL) mov cl,4 shl bx,cl ;multiply drive code * 16 ;create offset from Disk Parameter Base add bx,on, setup DMA controller ; (CL contains proper direction bit) mov al,04h out dmac_mode,al ;enable dmac mov al,00 out dmac_cont,al ;send first byte to control port mov al,cl out dmac_cont,al ;load direction register mov ax,dma_adr ou**************************** test_ready: mov dh, 40h ;proper mask if dr 1 test sel_mask,80h jnz nrdy2 mov dh, 04h ;mask for dr 0 status bit nrdy2: mov bx,offset rds_com call send_com dr_poll: in al,fdc_stat ;get status word test al ;no, dr_rdy: ; then we just retry read or write dec rtry_cnt jnz retry ; up to 10 times ; retries do not recover from the ; hard error mov ah,0 mov bx,ax ;make error code 16 bits mov bx,errtbl[BX] call pmsg ;print appropriate message  command jmps r_w_common WRITE: mov al,0ah ;basic write sector command r_w_common: mov bx,offset io_com ;point to command string mov byte ptr 1[BX],al ;put command into string ; fall into execute and return execute: ;execute command strffset dp_base return: ret HOME: ;move selected disk to home position (Track 0) mov trk,0 ;set disk i/o to track zero mov bx,offset hom_com call execute jz return ;home drive and return if OK mov bx,offset bad_hom ;else print call pmsg ;"t dmac_adr,al ;send low byte of DMA mov al,ah out dmac_adr,al ;send high byte mov ax,dma_seg out fdc_segment,al ;send low byte of segment address mov al,ah out fdc_segment,al ;then high segment address dma_exit: mov cl,[BX] ;get count ,80h jnz dr_poll ;wait for not command busy in al,fdc_rslt ;get "special result" test al,dh ;look at bit for this drive ret ;return status of ready ;********************************************* ;* *  in al,cdata ;flush usart receiver buffer call uconecho ;read upper case console character cmp al,'C' je wboot_l ;cancel cmp al,'R' je outer_retry ;retry 10 more times cmp al,'I' je z_ret ;ignore error or al,255 ;set code for permanent erring. ;[BX] points to length, ; followed by Command byte, ; followed by length-1 parameter bytes mov last_com,BX ;save command address for retries outer_retry: ;allow some retrying mov rtry_cnt,max_retries retry: mov BX,last_com call senHome Error" jmps home ;and retry SETTRK: ;set track address given by CX mov trk,cl ;we only use 8 bits of track address ret SETSEC: ;set sector number given by cx mov sect,cl ;we only use 8 bits of sector address ret SECTRAN: ;translate  inc BX mov al,[BX] ;get command or al,sel_mask ;merge command and drive code out fdc_com,al ;send command byte parm_loop: dec cl jz exec_exit ;no (more) parameters, return inc BX ;point to (next) parameter parm_poll: in al,fdc_stat t ;* Send_com sends a command and parameters * ;* to the i8271: BX addresses parameters. * ;* The DMA controller is also initialized * ;* if this is a read or write * ;* * ;**************or exec_exit: ret dr_nrdy: ;here to wait for drive ready call test_ready jnz retry ;if it's ready now we are done call test_ready jnz retry ;if not ready twice in row, mov bx,offset nrdymsg call pmsg ;"Drive Not Ready" nrdy01: call tesd_com ;transmit command to i8271 ; check status poll mov BX,last_com mov al,1[bx] ;get command op code mov cx,0800h ;mask if it will be "int req" cmp al,2ch jb exec_poll ;ok if it is an interrupt type mov cx,8080h ;else we use "not command sector CX using table at [DX] mov bx,cx add bx,dx ;add sector to tran table address mov bl,[bx] ;get logical sector ret SETDMA: ;set DMA offset given by CX mov dma_adr,CX ret SETDMAB: ;set DMA segment given by CX mov dma_seg,CX ret ;     est al,20h ;test "parameter register full" bit jnz parm_poll ;idle until parm reg not full mov al,[BX] out fdc_parm,al ;send next parameter jmps parm_loop ;go see if there are more parameters ;********************************************* ;* --------------------- ENDIF ;loader_bios cseg org ccpoffset ccp: org bios_code ;********************************************* ;* * ;* BIOS Jump Vector for Individual Routines * ;*  * ;* Revisions : * ;* * ;********************************************* true equ -1 false equ not true cr equ 0dh ;carriage return lf equ 0ah ;line feed ;********** * ;********************************************* dseg 0 ;absolute low memory org 0 ;(interrupt vectors) int0_offset rw 1 int0_segment rw 1 ; pad to system call vector rw 2*(bdos_int-1) bdos_offset rw 1 bdos_segment rw 1 lf,'Drive Not Ready :',0 er9 db cr,lf,'Write Protect :',0 erA db cr,lf,'Trk 00 Not Found :',0 erB db cr,lf,'Write Fault :',0 erC db cr,lf,'Sector Not Found :',0 erD equ er0 erE equ er0 erF equ er0 nrdymsg equ er8 rtry_cnt db 0 ;disk  * ;* Data Areas * ;* * ;********************************************* data_offset equ offset $ dseg org data_offset ;contiguous with  * ;********************************************* jmp INIT ;Enter from BOOT ROM or LOADER jmp WBOOT ;Arrive here from BDOS call 0 jmp CONST ;return console keyboard status jmp CONIN ;return console keyboard char jmp *********************************** ;* * ;* Loader_bios is true if assembling the * ;* LOADER BIOS, otherwise BIOS is for the * ;* CPM.SYS file. * ;*  END error retry counter last_com dw 0 ;address of last command string dma_adr dw 0 ;dma offset stored here dma_seg dw 0 ;dma segment stored here sel_mask db 40h ;select mask, 40h or 80h ; Various command strings for i8271 io_com db 3 ;length rdcode segment IF loader_bios ;--------------------------------------------- ;| | signon db cr,lf,cr,lf db 'CP/M-86 Version 2.2',cr,lf,0 ;| | ;-------------------CONOUT ;write char to console device jmp LISTOUT ;write character to list device jmp PUNCH ;write character to punch device jmp READER ;return char from reader device jmp HOME ;move to trk 00 on cur sel drive jmp SELDSK ;select disk for ne * ;********************************************* loader_bios equ false bdos_int equ 224 ;reserved BDOS interrupt IF not loader_bios ;--------------------------------------------- ;| | _wr db 0 ;read/write function code trk db 0 ;track # sect db 0 ;sector # hom_com db 2,29h,0 ;home drive command rds_com db 1,2ch ;read status command ; System Memory Segment Table segtable db 2 ;2 segments dw tpa_seg ;1st seg starts after BIO-------------------------- ENDIF ;loader_bios IF not loader_bios ;--------------------------------------------- ;| | signon db cr,lf,cr,lf db ' System Generated - 11 Jan 81',cr,lf,0 ;| xt rd/write jmp SETTRK ;set track for next rd/write jmp SETSEC ;set sector for next rd/write jmp SETDMA ;set offset for user buff (DMA) jmp READ ;read a 128 byte sector jmp WRITE ;write a 128 byte sector jmp LISTST ;return list status bios_code equ 2500h ccp_offset equ 0000h bdos_ofst equ 0B06h ;BDOS entry point ;| | ;--------------------------------------------- ENDIF ;not loader_bios IF loader_bios ;--------------------------------- title 'Customized Basic I/O System' ;********************************************* ;* * ;* This Customized BIOS adapts CP/M-86 to * ;* the following hardware configuration * ;* Processor: S dw tpa_len ;and extends to 08000 dw 2000h ;second is 20000 - dw 2000h ;3FFFF (128k) include singles.lib ;read in disk definitions loc_stk rw 32 ;local stack for initialization stkbase equ offset $ lastoff equ offset $ tpa_seg equ (last | ;--------------------------------------------- ENDIF ;not loader_bios bad_hom db cr,lf,'Home Error',cr,lf,0 int_trp db cr,lf,'Interrupt Trap Halt',cr,lf,0 errtbl dw er0,er1,er2,er3 dw er4,er5,er6,er7 dw er8,er9,e jmp SECTRAN ;xlate logical->physical sector jmp SETDMAB ;set seg base for buff (DMA) jmp GETSEGT ;return offset of Mem Desc Table jmp GETIOBF ;return I/O map byte (IOBYTE) jmp SETIOBF ;set I/O map byte (IOBYTE) ;**************************------------ ;| | bios_code equ 1200h ;start of LDBIOS ccp_offset equ 0003h ;base of CPMLOADER bdos_ofst equ 0406h ;stripped BDOS entry ;| | ;------------------------ * ;* Brand: * ;* Controller: * ;* * ;* * ;* Programmer: off+0400h+15) / 16 tpa_len equ 0800h - tpa_seg db 0 ;fill last address for GENCMD ;********************************************* ;* * ;* Dummy Data Section * ;* rA,erB dw erC,erD,erE,erF er0 db cr,lf,'Null Error ??',0 er1 equ er0 er2 equ er0 er3 equ er0 er4 db cr,lf,'Clock Error :',0 er5 db cr,lf,'Late DMA :',0 er6 db cr,lf,'ID CRC Error :',0 er7 db cr,lf,'Data CRC Error :',0 er8 db cr,     ******************* ;* * ;* INIT Entry Point, Differs for LDBIOS and * ;* BIOS, according to "Loader_Bios" value * ;* * ;************************************************************************************* ;* * ;* Data Areas * ;* * ;********************************************* data_offset equ offi/o to track zero rs 10 ;(fill-in) ret SETTRK: ;set track address given by CX mov trk,CX ret SETSEC: ;set sector number given by cx mov sect,CX ret SECTRAN: ;translate sector CX using table at [DX] mov bx,cx add bx,dx ;add sector t) ret CONOUT: ;console output rs 10 ;(fill-in) ret ;then return data LISTOUT: ;list device output rs 10 ;(fill-in) ret LISTST: ;poll list status rs 10 ;(fill-in) ret PUNCH: ;write punch device rs 10 ;(fill-in) ret REAax,0 mov ds,ax ;point to segment zero ;BDOS interrupt offset mov bdos_offset,bdos_ofst mov bdos_segment,CS ;bdos interrupt segment ; (additional LOADER initialization) pop ds ;restore data segment ;| |*** INIT: ;print signon message and initialize hardware mov ax,cs ;we entered with a JMPF so use mov ss,ax ;CS: as the initial value of SS:, mov ds,ax ;DS:, mov es,ax ;and ES: ;use local stack during initialization mov sp,offset stkbase clset $ dseg org data_offset ;contiguous with code segment IOBYTE db 0 disk db 0 ;disk number trk dw 0 ;track number sect dw 0 ;sector number dma_adr dw 0 ;DMA offset from DS dma_seg dw 0 ;DMA Base Segment IF loader_bios ;-------------------o tran table address mov bl,[bx] ;get logical sector ret SETDMA: ;set DMA offset given by CX mov dma_adr,CX ret SETDMAB: ;set DMA segment given by CX mov dma_seg,CX ret ; GETSEGT: ;return address of physical memory table mov bx,offseDER: rs 10 ;(fill-in) ret GETIOBF: mov al,IOBYTE ret SETIOBF: mov IOBYTE,cl ;set iobyte ret ;iobyte not implemented pmsg: mov al,[BX] ;get next char from message test al,al jz return ;if zero return mov CL,AL call CONOUT  ;--------------------------------------------- ENDIF ;loader_bios mov bx,offset signon call pmsg ;print signon message mov cl,0 ;default to dr A: on coldstart jmp ccp ;jump to cold start entry of CCP WBOOT: jmp ccp+6 ;direct entry to CCP d ;set forward direction IF not loader_bios ;--------------------------------------------- ;| | ; This is a BIOS for the CPM.SYS file. ; Setup all interrupt vectors in low ; memory to address trap -------------------------- ;| | signon db cr,lf,cr,lf db 'CP/M-86 Version 1.0',cr,lf,0 ;| | ;--------------------------------------------- ENDIF ;loader_bios It seg_table ret ;********************************************* ;* * ;* All disk I/O parameters are setup: * ;* DISK is disk number (SELDSK) * ;* TRK is track number (SETTRK;print it inc BX jmps pmsg ;next character and loop ;********************************************* ;* * ;* Disk Input/Output Routines * ;* * ;****at command level IF not loader_bios ;--------------------------------------------- ;| | int_trap: cli ;block interrupts mov ax,cs mov ds,ax ;get our data segment mov bx,offset int_trp call pmsg push ds ;save the DS register mov IOBYTE,0 ;clear IOBYTE mov ax,0 mov ds,ax mov es,ax ;set ES and DS to zero ;setup interrupt 0 to address trap routine mov int0_offset,offset int_trap mov int0_segment,CS mov di,4 mov si,0 ;then propagatF not loader_bios ;--------------------------------------------- ;| | signon db cr,lf,cr,lf db 'System Generated 00/00/00' db cr,lf,0 ;| | ;-----------------------) * ;* SECT is sector number (SETSEC) * ;* DMA_ADR is the DMA offset (SETDMA) * ;* DMA_SEG is the DMA segment (SETDMAB)* ;* READ reads the selected sector to the DMA* ;* address, and WRITE writes the data from * ;* the DMA***************************************** SELDSK: ;select disk given by register CL ndisks equ 2 ;number of disks (up to 16) mov disk,cl ;save disk number mov bx,0000h ;ready for error return cmp cl,ndisks ;n beyond max disks? jnb return ;retuhlt ;hardstop ;| | ;--------------------------------------------- ENDIF ;not loader_bios ;********************************************* ;* * ;* CP/M Character Ie mov cx,510 ;trap vector to rep movs ax,ax ;all 256 interrupts ;BDOS offset to proper interrupt mov bdos_offset,bdos_ofst pop ds ;restore the DS register ; (additional CP/M-86 initialization) ;| | ---------------------- ENDIF ;not loader_bios int_trp db cr,lf db 'Interrupt Trap Halt' db cr,lf ; System Memory Segment Table segtable db 2 ;2 segments dw tpa_seg ;1st seg starts after BIOS dw tpa_len ;and extends to 08000 dw 2000h ;s address to the selected sector * ;* (return 00 if successful, 01 if perm err)* ;* * ;********************************************* READ: rs 50 ;fill-in ret WRITE: rs 50 ;(fill-in) ret ;**rn if so mov ch,0 ;double(n) mov bx,cx ;bx = n mov cl,4 ;ready for *16 shl bx,cl ;n = n * 16 mov cx,offset dpbase add bx,cx ;dpbase + n * 16 return: ret ;bx = .dph HOME: ;move selected disk to home position (Track 0) mov trk,0 ;set disk /O Interface Routines * ;* * ;********************************************* CONST: ;console status rs 10 ;(fill-in) ret CONIN: ;console input call CONST jz CONIN ;wait for RDA rs 10 ;(fill-in;--------------------------------------------- ENDIF ;not loader_bios IF loader_bios ;--------------------------------------------- ;| | ;This is a BIOS for the LOADER push ds ;save data segment mov       econd is 20000 - dw 2000h ;3FFFF (128k) include singles.lib ;read in disk definitions loc_stk rw 32 ;local stack for initialization stkbase equ offset $ lastoff equ offset $ tpa_seg equ (lastoff+0400h+15) / 16 tpa_len equ 0800h - tpa_seg db 0 ;fill last address for GENCMD ;********************************************* ;* * ;* Dummy Data Section * ;* * ;********************************************* dseg 0 ;absolute low memory org 0 ;(interrupt vectors) int0_offset rw 1 int0_segment rw 1 ; pad to system call vector rw 2*(bdos_int-1) bdos_offset rw 1 bdos_segment rw 1 END  @GTHIS IS A HEADER*# w# w# wc ͭ!8 G͙(O#:#* ͣ((O (\(6(O 8.(&0 @G #?##w^#U#ͭ!R(@THIS IS A HEADER*# w# w# wc ͭ!8 G͙(O#:#* ͣ((O (\(6(O 8.(&0@ #?##w^#U#ͭ!R(       title 'COPYDISK 1 Feb 82' ver equ 20 ; Version 2.0 -jrp ; COPYDISK duplicates entire diskettes using all of the ; available storage as a multiple track buffer. ; This program must be built with a large extra segment ; as follows: ; ASMss mov si,offset reading_message ; point to read message mov ax,offset read ; and proper subroutine mov cl,source ; select source diskette call track_block mov si,offset writing_message ; point to write message mov ax,offset write ; ack,ax ; save value ; compute number of tracks that will ; fit in our data segment mov ax,extra_length ; get low 16 bits of DS length mov dl,extra_length_H ; get other 8 bits mov dh,0 ; zero rest of 32 bit divisor div track_sizelection call seldsk ; select destination drive test bx,bx ; insure drive exists jz drive_err ; no, go error out mov di,ES:word ptr 10[bx] ; point to destination DPB mov si,offset disk_def ; point to source drives def mov cx,15 ; leeldsk ; select it test bx,bx ; insure the drive exists jz drive_err ; no, fatal mov si,ES:word ptr 10[bx] ; get pointer to DPB ; create local copy of disk definition push ds ! push es ; save segments pop ds ! pop es ; and exchan86 COPYDISK ; GENCMD COPYDISK EXTRA[M0200,XFF00] ; This allows COPYDISK to utilize all the left-over memory in your ; system as its buffer. cseg ; code segment start: mov si,offset signon_message call pmsg ; print signon message nextnd proper subroutine mov cl,dest ; select destination call track_block mov si,offset verify_message ; point to verify message mov ax,offset verify mov cl,dest ; reselect destination call track_block mov ax,base_track sub ax,nts  ; divide buff_len / track_size mov NTS,ax ; save this value. cmp ax,2 ; must be at least 2 tracks jae adequite_memory ; ok, continue mov si,offset memory_message ; else print call pmsg ; error message aborting: ; here if exitinngth of a definition cld ! rep cmpsb ; compare the definitions je next_2 ; must be equal. jmp different_type ; else go print error next_2: mov dx,es:word ptr 00[bx] ; get secttran table address mov cx,0 ; logical sector zero call sge them mov di,offset disk_def ; point to local disk def table mov cx,15 ; diskdef is 15 bytes long cld ! rep movsb ; copy it push ds ! push es ; swap back pop ds ! pop es ; segment registers mov dx,es:word ptr 00[bx] ; get se_copy: ; reload local stack for retries. pushf ; save interrupt flag in stack pop bx ; put it in bx cli ; disable interrupts mov ax,ds ; get our data segment mov ss,ax ; and use as stack segment mov sp,offset stack_end ; ; adjust base track by number we copied mov base_track,ax jmps next_block next_block_x: ; here, we are done with a sucessful copy mov si,offset done_message ; print message call pmsg ; announcing success another: mov si,offset anotg because of error mov si,offset abort_message call pmsg jmp another adequite_memory: mov si,offset ready_message ; insure this is correct call get_yn ; print request jc aborting ; if NO, then get new input mov si,offset copy_mesectran ; find out first sector number cmp bx,base_sector ; make sure its the same je next_3 ; the same is OK, jmp different_type ; no, fatal error next_3: ; determine track capacity mov ax,spt ; get the sectors per track mov dcttran table address mov cx,0 ; logical sector zero call sectran ; find out first sector number mov base_sector,bx ; save this for track reads mov si,offset dest_message ; prompt for destination call get_drive ; get the drive code  set stack pointer push bx ; flags back into stack popf ; restore interrupt status mov si,offset source_message ; prompt for source drive call get_drive ; request drive code cmp al, cr - 'A' ; see if it was a jne next_1 ; nher_message call getyn ; see if we want another copy jc exit ; no, go exit next_copy_v: ; convienient for short jumps jmp next_copy ; back for another disk copy exit: ; here, we are exiting mov si,offset exit_message call psage ; else tell user OK. call pmsg mov ax,max_track ; get maximum track number mov base_track,ax ; save as outer loop index next_block: mov ax,base_track ; get loop index cmp ax,0 ; see if we are outside limits jl next_block_x l,128 ; length of a sector mul dl ; get track capacity mov track_size,ax ; save it ; determine number of tracks on diskette mov al,blm ; get block mask inc al ; plus 1 gives sectors/block mov ah,0 ; make 16 bits mov dx,0 cmp al,source ; see if same as source jne not_same ; no, go see if > max mov si,offset same_message ; can't have same drive call pmsg ; so we print message jmp another ; and go try again not_same: cmp al,drive_cnt ; is dest > mao, continue jmp exit ; yes, we should exit next_1: cmp al,drive_cnt ; see if valid drive code jb save_source ; yes, go save it drive_err: mov si,offset bad_drive ; else, print call pmsg ; a bad drive message jmp another ; and tmsg mov cl,13 int BDOS mov cl,0 ; reboot mov dl,0 ; CP/M-86 int BDOS different_type: mov si,offset type_error_message call pmsg jmp aborting track_block: mov message_pointer,si ; save pointer to message mov disk_functio; yes, terminate loop sub ax,nts ; lower by number of tracks per buffer inc ax ; and adjust by 1. jns not_neg ; check to make sure its positive mov ax,0 ; no, zero is floor not_neg: mov btr,ax ; save as last track for this copy pa ; make 32 bits mul dsm ; total sectors/data area add ax,spt ; force round up dec ax ; by adding SPT-1 div spt ; compute number of tracks add ax,off ; add in operating sys tracks dec ax ; number of last track mov max_trax? jnb drive_err ; go print invalid drive error mov dest,al ; save destination drive add al,'A' ; make ascii drive code mov dest_ascii,al ; save for messages mov cl,dest ; get destination drive mov dl,0 ; force first time sery to get another save_source: mov source,al ; save it as the source drive add al,'A' ; make ascii drive code mov source_ascii,al ; save for messages mov cl,source ; get source drive mov dl,0 ; force first time selection call s      n,ax ; save pointer to read/write mov selected_disk,cl ; save drive select code mov dl,1 ; tell bios have selected before call seldsk ; select diskette drive mov ax,base_track ; get base track number for this pass mov trk,ax ; save a no carry cmp al,'N' ; see if was 'N' jne get_yn ; no, invalid. reprompt stc ; set carry for a NO get_yn_x: ret get_char: ; read a line from CONIN and return first char mov cl,10 ; function for line in mov dx,offset line_buff jmps bios_call setsec: mov al,11 jmps bios_call setdma: mov al,12 jmps bios_call setdmab: mov al,17 jmps bios_call read: mov al,13 jmps bios_call write: mov al,14 jmps bios_call sectran: mov al,16 jmps bios_call  new disks next_5: call crlf no_disk_error: pop cx ; recover sector number inc cx ; sector = sector + 1 cmp cx,spt ; see if past last sector jae next_6 ; done, exit jmp next_sector ; else, continue next_6: dec trk ; track nt,dx ; save DMA segment mov cx,dx ; put in argument register call setdmab ; pass to CBIOS mov cx,dma_offset ; get the offset again call setdma ; and pass it to BIOS also mov ax,sector ; fetch current sector number inc ax ; s loop index next_track: ; first inner loop... mov ax,trk ; get the index cmp ax,btr ; see if less than last jnl next_4 ; no, continue jmp next_track_x ; yeah, exit loop next_4: mov si,message_pointer call pmsg ; print " Track " mov ax,trk ; get the track number call pdec ; print as decimal mov si,offset space_message ; then, print some call pmsg ; spaces to blank any garbage mov cx,trk ; get desired track address call settrk ; give to biosreturn a ret crlf: ; print a mov si,offset crlf_message ; fall into pmsg pmsg: ; print message at [SI] to zero lods al ; get a character test al,al ; see if zero terminator jz pmsg_x ; yes, exit push s************* get_drive: ; print message and read drive code call pmsg ; first, print the message call get_upper ; then get an upper case letter sub al,'A' ; and normalize to 0... ret get_upper: ; get upper case console input w/ ea segment call setdmab ; point dma base address call read ; read 128 byte record push ax ; save read error in stack mov si,offset verify_buffer ; point to sector we just read les di,dword ptr dma_offset ; get pointer to one we wrote nction ; read/write/verify a sector test al,al ; check error return code jz no_disk_error ; see if we got a bad sector ; got fatal disk error mov si,offset disk_error_message call pmsg ; print disk error mov si,message_pointer ;  mov cx,0 ; start with logical sector 0 next_sector: push cx ; save current sector number mov sector,cx ; save sector number (0 org) add cx,base_sector ; correct for first sector number call setsec ; pass to cbios ; compute di ; save pointer call conout ; not done, print character pop si ; recover pointer jmp pmsg ; and loop pmsg_x: ret conin: ; get character from console into AL mov cl,6 mov dl,0FFh int BDOS test al,al jz conin ret cocho call get_char ; get console character cmp al,'a' ; see if lower case jb get_upper_x ; below, leave cmp al,'z' ; insure not > z ja get_upper_x ; not lower at all sub al,'a'-'A' ; make upper get_upper_x: ret get_yn: ; pmov cx,128 ; 128 byte record cld ! rep cmpsb ; compare them mov al,0 ; no error je verify_good ; so we are ok mov al,0FFh ; else, we got compare error verify_good: pop dx ; recover read error byte or al,dl ; merge into retuget pointer to read/write inc si ; skip leading call pmsg ; print that mov ax,trk ; get track number call pdec ; print it mov si,offset sector_message ; print ", Sector " call pmsg mov ax,sector ; get sector number (0 org) ma address and segment mov ax,base_track ; get starting track number sub ax,trk ; gives relative track of pass mov dx,0 ; make dword mul spt ; compute sector of track add ax,sector ; add in current logical sector adc dx,0 ; makenout: ; output character in AL to console mov dl,al mov cl,6 int BDOS ret pdec: ; print unsigned 16 bits in AX as decimal ; with zero suppresion mov cx,0 ; cx is digit counter pdec_1: ; here to divide out next digit sub dxrint message and get Y or N push si ; save message pointer call pmsg ; print the message call get_upper ; get a upper case letter pop si ; recover message pointer cmp al,'Y' ; see if response was 'Y' je get_yn_x ; yes, return w/rn code ret ; back to caller ; *********************************** ; * ; * BIOS direct entry points ; * ; *********************************** home: mov al,8 jmps bios_call seldsk: mov al,9 jmps bios_call settrk: mov al,10  add ax,base_sector ; correct if 1 origin call pdec ; print the sector number mov si,offset continue_message ; see if user wants to ignore call get_yn ; ask for a Y/N response jnc next_5 ; yes, continue jmp aborting ; NO, go ask for double precision add mov cx,128 ; length of a sector mul cx ; gives base offset as 32 bits mov dma_offset,ax ; gives base dma offset mov cl,12 ! shl dx,cl ; move to high nibble add dx,extra_base ; offset extra segment mov dma_segme      ,dx ; Zero DX mov bx,10 ; constant 10 div bx ; quotient to AX, remainder to DX add dl,'0' ; make remainder ascii digit push dx ; and stick onto stack inc cx ; bump digit counter test ax,ax ; see if any quotient left jnz pdec_1 ction db 0 ; force out data segment end de dest rb 1 ; destination drive select code selected_disk rb 1 ; current drive select code trk rw 1 ; current track number sector rw 1 ; current sector number (0 origin) nts rw 1 ; number of tracks per buffer full base_track rw 1 ; starting trac source_message db cr,lf,cr,lf,'Enter Source Disk Drive (A-D) ? ',0 dest_message db cr,lf,cr,lf,' Destination Disk Drive (A-D) ? ',0 ready_message db cr,lf,cr,lf,'Copying Disk ' source_ascii rb 1 db ': to Disk ' dest_ascii rb 1 db ':',cr,lf  ; yes, continue stacking digits pdec_2: pop ax ; get a digit from the stack push cx ; save count call conout ; print it pop cx ; restore count loop pdec_2 ; and continue if more in stack ret ; done. . . ; ** DATA SEGMENTk number for this pass track_size rw 1 ; size of each track in bytes btr rw 1 ; last track number of this pass dma_offset rw 1 ; current buffer offset dma_segment rw 1 ; current buffer segment base message_pointer rw 1 ; points to appropriate read/wr db 'Is this what you want to do (Y/N) ? ',0 memory_message db cr,lf,'Insufficient memory available for copy',0 abort_message db cr,lf,cr,lf,'Copy aborted',cr,lf,0 done_message db cr,lf,'Copy completed.',0 another_message db cr,lf,cr,lf,'Copy  ** dseg cr equ 0dh ; ascii carriage return lf equ 0ah ; ascii line feed drive_cnt equ 16 ; CP/M currently supports up to 16 drives BDOS equ 224 ; system call interrupt number ; CP/M-86 Page Zero code_length rw 1 ; low 16 bits ite message disk_function rw 1 ; points to '' '' '' subroutine base_sector rw 1 ; either 0 or 1 normally max_track rw 1 ; total number of tracks on disk line_buff db 80 db 0 rb 80 bios_function rb 1 ; bios function number bios_another disk (Y/N) ? ',0 copy_message db cr,lf,'Copy started',cr,lf,0 reading_message db cr,' Reading Track ',0 writing_message db cr,' Writing Track ',0 verify_message db cr,'Verifying Track ',0 space_message db ' ',0 bad_drive dbcode length code_length_H rb 1 ; high 8 bits '' '' code_base rw 1 ; base of the code segment model_8080 rb 1 ; 8080 memory model flag data_length rw 1 ; low 16 bits data length data_length_H rb 1 ; high 8 bits '' '' data_base rw 1 ; base cx rw 1 ; first argument for BIOS call bios_dx rw 1 ; second argument for BIOS call disk_def rs 0 ; disk definition table gets copied here spt rw 1 ; 128 byte sectors per track bsh rb 1 ; block shift factor blm rb 1 ; block mask exm rb 1 ;  cr,lf,'Illegal Diskette Drive',cr,lf,0 same_message db cr,lf,'Source and Destination cannot be the same' db cr,lf,0 type_error_message db cr,lf,'Source and Destination disks must be' db cr,lf,'the same type',cr,lf,0 continue_message db cr,lof the data segment rs 1 ; not used extra_length rw 1 ; low 16 bits extra length extra_length_H rb 1 ; high 8 bits '' '' extra_base rw 1 ; base of the extra segment org 005Ch default_FCB rs 35 ; default File Control Block org 00a cmaphns.10 y 0d000000 40 gioshns cpm86  y a gioshns.24o y 0080ff80 80 y a cpm86.13d y 0600ff80 2580 y a cmap816.10 y 0d000000 40 gios816 cpm86  y q extent mask dsm rw 1 ; disk size in blocks drm rw 1 ; directory size al0 rb 1 ; alloc 0 al1 rb 1 ; alloc 1 cks rw 1 ; checksum size off rw 1 ; directory offset rw 128 stack_end rw 0 verify_buffer rs 128 ; sector buffer for verify funf,'Ignore error (Y/N) ? ',0 sector_message db ', Sector ',0 disk_error_message db cr,lf,'Permanent Error ',0 crlf_message db cr,lf,0 exit_message db cr,lf,'COPY program exiting',cr,lf,0 ; VARIABLES source rb 1 ; source drive select co80h default_buffer rs 128 ; default record buffer org 0100h ; start of user data segment ; MESSAGES signon_message db cr,lf,'CP/M-86 Full Disk COPY Utility' db cr,lf,' Version ' db ver/10+'0', '.', (ver mod 10)+'0',cr,lf,0       2G)D(F+Fu +D+DF+F؉DYZ]ËGDEQRVSh/[:s Eu^ZY UVQ'#:*#s ;s F;w;FsްY^] U'#:*#s +Fu] U'#:*#s F+u\UUðTTÃ|tDD"">"u """, "<t<u"|uD< u ÃpuS5[T"ÃË%sá$##"$"$"ʱ3 ">$tuMT"p "Q?t$GOQp  =_.:;<>,DIRSUSERREN TYPEERA DIR NO FILEALL (Y/N)?FILE EXISTSMEMOR> ;t׋65 tu+: tE>( t5H ؋⹐ \ 7 < t tS[C?. t: u̻( ? u!Ê< t'C,0< suűrrruÀ? uCuûK؊': t$Ȼ9 :t: t Ȼ9 :uà9 ] û" u%l rPX< t< t < t<t< à" uKD$t8<u:1<t2">#u $$t>#u H&"à" uQYQYQ>$tY"<t< s t<u< uÊNs P^Y@ u "$u u€YY Ў"$0"&E "8t 0D&ED|tD&&e&>"u &e& ƒv"$$"$"$#<t >#wh##$%$ڊOW[3ۊ؁%$Y NOT AVAILABLEREAD ERROR CANNOT CLOSE NON-SYSTEM FILE(S) EXIST SYSTEM FILE(S) EXIST  *.$P.&'#.#PX.#.&'#XÐ$##$$>$ t  > t /.  u(? u ?CuR)uuȊȰ Es u p t bZR$PuzQYAj:e^:[V$< uXP<u $< t 5ŀ s u$XI*! COPYRIGHT (C) 1980, DIGITAL RESEARCH #":"s u n i<$tAQY""$&CSQS[Y< u< t<u t͠""Q<u t&K|<u QS"<u$<u["":sG<uK[~<u5Q?Y[SQ tC&QS[YS" t*"" "uC&QS$%#$.#>#GEE)#u >*#tsunD9GrGSyuX:*#sMHuD+9GrG-Su2u-kAu :*#suCn*#G2$ËG"""uσtlutc<uutGE&c%  ' ! !!!!!(!.!4!=!F!X!a!g!m!s!!!! WvD" $J  Ȏ؏$t r$$&$>$tȎм$$$&_tUWV%#^_]%#$&$$$ω$#3$'#u`Z. u!d  tC?YtC5 >( tg'HuL. uJ>( tCetr S#[uCJ<tS[uuE. :u: PtU'765 <=t<_u5F65 u+X:  t:ň/u/'͎ñ3б QYð Q[ uCS[';20 빱:뵱 뱊бñG'tù رԺ's ñ' V)#t#uñ$'#>)#st QD+Gu  D##!S)r 6ٷ. #<uU###jS$A##YPQ'#(#26$6$#>$$YXQ!Q$YPQ(#2$#>$>$YXñ"##ȎS"[PS\+\E+E;v[X++" "<tft')8o G( uW{ '>( u: tȢ9 1 t̠9 >0 t30'u=@t+؎%: S'[7G\'! t tqt9 L 2tVP 3. zC/5 ñ uñ ñ3 uð 9  u< sW; _Ê<u< tFC QYtC<*u?FtFø'S: 65  3"Ë# # t߻"o$###6"Rȋ6" #JY #T@"#*#Ë$ـ>#tًȵ#Ë# Ê"###"" ؉#Ë$ ú$#ڊ#""##<uYQVW*#Ȣ*#*t2ɋ_^YRW3ҵ:*#sD;rЊt _ZRW:*#sD+Gtr;sЊ߰t _ZËGSFF[UQ;r F;FrY] à*#*#+#URQ;uF;FuYQ<u"|t>D"|DtD"Q8RZY>$t1Q6Y"9DsD8\|t Ts [T t)"7T>$t5H;"wױ7="+,>###;uE# "8t ðÀ>"u "ډ"ð|t.|t\;\v+\ < tN tſ&E.&E.*. ?t.0 (, : uhCMD$$$ SUB67 t@|:t9 <w<w[9: FF<.uFC365 [ C??u ÿD (tKuÊ< uÌK5 .> u. 0 >,. 0 Q$ТX$9 .> u0 AsA+>&_9 .     2#ڠ#ù"2CQ$Y á"$$Ë""#B" ڊs "t"*"#Ë$ Ë$";rBR+ӋZñ##sQO#"Yt :t s_È3$ $2ȎVWF*77 u >)u[_^Ã?u[_^Sw˷㋟*[ع$Q0=9vGY؎<uäMË6Gt  SP+؋_ Ƙ؋t@[þ?þBڊF FFÈ؈؉C>$tÈ #>#uE> #u>6#>"3@### #Ê6""C:u###:rP$X<u>#u_Y$ uȢ#H#Q$!ڊ$PC$Ȋ$XC ۳ui ڈ ڊ*u ڊ " "$$~û$C:uû$Ë#$C$ds䠦$$QY# u&QYLр"ڊR$Y QȈYQZuR>#tQSQCS t ";r[CYϋ"Cˋ"C#""25)á*È)SػM[þQzþfsþ`lþeþr^þoWþcPþTIþ0BþW;þZ4þ]-þl&s`þi?? @Bdos Err On : $Bad Sector$Select$File R/O$*$tci.B$&LM/12Es~D]7~J@3[urg" "#$\\$#Gt g#`#$$Ȣ#<s$##$$$À>#`u$"u"3ۉ""$$N{>$t ##<#u#>#t#K$#`$Iau6$6#NT =t4Ok- t IRQ)sYZ;"sBQRsZY+[Z u̻ñ R$Y[ $u kt UtPSڋ$ RZ ڊڊ/[X:trcation: command: Sorry, call not implemented. ''' Do you wish to (R)etry, (A)bort or (I)gnore ? Digital Microsystems, Inc. CP/M-86 Version 1.1  T++T-T,+T/T.+(Ȏ؎R+м< )))ھ-m$gC+IN+CC+)!){C!)D|&E1&E3&Ed&E ڌȎм<1&G* 0 )þu t tÊ ÊttQ,Y#`u$G $u#~Z$$$??t??t=$$$$)"&$$J"" nl"$à##t u u:uGڋ;u3BCBCu¹هً:rهي #$6$$"U$t$ڱ2Cu ڈy2 # tT1T0+T3T2+T5T4+T7T6+T9T8+T;T:þà)È)û**PX$_) )^u!u<uðÉ)É )ûG+û*Êt S[CòX"#À>#t$$>#`uO# t ##>'#uSꡛ$#cuL 6$$ t* : $ $t""" #t &$t&!u #tut 2"#4# #w#:#r$u t y]# #$(###t     ! ͌~.#  7 C7E0OÌ!@w#:_:O͆|r" gÒ :O͆DISKCHK version 1.4b $checksumming on drive $ $Error---invalid drive chosen $checksummyyXَэ&P +ɋUVN]0102821100654321ing on currently logged in drive $ Disk suitable for use. $ BAD DISK---DO NOT USE. CheckSum is: $Error--Selected disk does not exist $DONE $Error---Disk too full to contain checksum $U~ v FA, FF0vc ]UFPF$P]UFPFP]UF0P! ]UFd1PF 11RF 1R]Us v ,P :^w-ȴÊ_< s#P 6>6 uʰ:P 6\dBAD DISK---DO NOT USE. CheckSum is: $Error--Selected disk does not exist $DONE $Error---Disk too full to contain checksum $>\u,Pt 6)HPg 9sP ]U\:Fu]UƋ^u \:u۰]U>\ t@ 9]Usx]UsP$P]]U>u>\u>t>v&PS #.PD5P ̀8Ò22!V!zt~ <#AiHi _ A2Y Ò Y"*NFC*~2Fnf"#>)2+"#|!5:4 N`: *"~*s$P9P{:vWQP"s:Pr[PPZP:_P2QP)?PoP6|PPPPPPPPPtS]U츺Pk ]U> wƇu\"*$"*'"*-"*"* "@: X:?2:2K}K̀̓I[S*R°: ˜*|˜*)"*#"S.!5>X#*^#VzKCK͉"!># # >     ,uP> t@Y rP}LJ,Ps P 5>\ t@P>\,t@Y ss>\t P };r;vQ>usP~ Ƈ~>u ;vȀ>u +9w>uU>uMu]U~ u~ u $~ r>rsF]Ut PBPX>u] P]U P| Pv]U Pk]U,P`]UF0PR]U;PE]UF t[F 1 1>t@"F`W뙠45764]U4XwXƇXum?$u2X>Xw&Xƻm,AY<s ƇXuӀ>e u e򤸀P\P >u P$P Pw897|XX<wƇ: ]UF1v uFFFF]Uv6 P@ v6 v@ ]U;P ? vk :P 0 v  ]UC ;P  P - P P P P s:PO P P <wiÊsW QP^ s:C>u3>u#> u>@u%>u >v>t;wZ>uUuvHs_㋇)sP Ρ ,>u%% u@P;w@Y sPw@Y"FsFs P6F 1F]U~ v F, AFF0v]UFPF$P]UFPFP]UvhPs]UFPPPdP]UvPP'P]UvPP'P]U7sE6s] ƇB XuƇ:$ P]]U>H u GNHoDPw]U8r38EPvV4*^ZZt P ?P]U~tv]U4:5r9s]Ê44]U^]s]\>\uZ>[ t>[u[4P P6C Pz P61 s:P[ P6  PM u P  P) C P/ 3 P : P +> P F P P[ Ps ]Us  P ]U>wƇu9r84  o P>\ tnw PMs|8s]Xs]À>uxsP s.x;P IP6@P62MP"P8P<PXP\PvPzP]À> s P ]á+@r3 s!;P6 PR6PD A6>5u]ð;P:5sȴW]U^?$t 7F]UvFPPPdPg]U)v]Uv]U> s;Pnv]Uq P]Ut P]Uv]Uv]Uvv]s\&s\>['u \[\9s P런r>[t2[^_È^v>\u]]ø P^[ [>\u>[$ts]뗀>\t >[$u[>s݀>[Ot>[Qu >[Hu>t[$>Bu X.  P P|+ Pp Pd 8 >\ t P+g]U1]UPFP]U P P]U Pv]Uv]UPv]UPv]UPv]U&;P >t 6P:P l PQ >t&&PP6P6 Ps>v @A&60 PAPA P6Q P6a Py>us 6r PY Error(s)$Uvv]U>\t>\u]À>\u>_;u >_ t_\]À>^v]Ê^㋇x Ê^ \>t[^w@˷_֋P:t@Y"sʈǂ>u]\^\]U[:Ft@s[] ^>Du^ :^wvȴÊ_t+袀sr@s\u>\u P\].>\u%>['u [<'t]À>[ u ! PZ]]Q]U[,0< vPv]UPv~]UPvn]UPv[]UPvK]U@v[]U9s]á@=vD>s0P\P_tƇЁ]US<u9S]UTTȢTvs 6 PHP PhHP P\P PbP PW1P P26 P'! P6 % P sP ) P < P @]U[APv@Y ]U[,A<v@]UPY ]U[\]]UPP8]U\. >ltlPYP>u2 P6]U졆H5t#V58VwVVu7]U45W<u:PAW< t@P>Wt@Y sI>W u P2>W u PI4uW< r<t,a<s&W_6W!661H9wl1 tj >tB >sg V PU ;r)u@s L P6 P P 1PX1 t6 T P k P6n o P 1P s P     @  !!4\  :!‡ *!! ~- /:0$_ i;͹O*!M\*!M\Diddd:6dÖ :! Җ O/!!!#"!:0$ i:! ;͹OW*!M\]D*!#M> _*! "!;͹O>!!7! *!DM*!&! ͷ M!!p+q:@$ң*!DM̀,U!!6:&!!p:!=O!& ~2! b#U*!M͘i*!MU!!45:U*&M:&–,U*&DMͳHU:&ң̀!!q!!:&¸ͭ>>!!p+q!!6:!<2!O*! ~2!>!!:&>:& !& Disk Parameter Blocks$dpe$xlt$Translate Table$Scratch Area$dirbuf,$dpb$Dir Buff, Parm Block$csv$alv$Check, Alloc Vectors$range $equ$ diskparm$delimit$missing$numeric$duplic $Alloc $no disk$Disk $ is the same as Disk $dpb$Equivalent Parameters$als$Sament, Command Form is: GENDEF x $ Where x.DEF Holds Disk Definitions With Optional Parameters : C: Create Diskdef Comment O: Generate Offset-Relative Labels Z: Z80, 8080, or 8085 (else 8086, 8088) x.LIB is Created Upon Com @?End-File$offset $bad val$dpbase$equ$Base of Disk Parameter Blocks$dpe$xlt$Translate Table$Scratch Area$dirbuf,$dpb$Dir Buff, Parm Block$csv$alv$Check, Alloc Vectors$range $equ$ diskparm$delimit$missing$numeric$duplic͈ :͹OD!"!>!!7!= *!M!! +s#r*!*! DM͕*!DM͕*!DM͕:!u !"!à !!:!Ҋ ! "!Ð !@"!*!#M!! +s#r*!DM͕*!#M> O͕*!DM͕*!DM!͕>!,! !!6:! *!DM2͕i*!E ͭ:G$$͹>!!0!!6H:&C*&!!sH!!6:!>!!He/ͭA:<$ҁ Æ$͹S!!6:!!!* :!=_ :G$Ҳ:͹x:!=_ UHSxHUH/Sx<:!=_D HS Allocation Vector Size$css$Same Checksum Vector Size$xlt$Same Translate Table$too few$Disk $ is CP/M 1.4 Double Density Compatible$65536$128 Byte Record Capacity$Kilobyte Drive Capacity$32 Byte Directory Entries$Checked Directory Entries$Records / Extentpletion. $Premature End-of-File$Length $Convert$Quote $ LIBno ".LIB" directory space$".LIB" disk full$cannot close ".LIB"$dw$db$ DISKSENDEFMACLIBDISKDEF $Alloc $no disk$Disk $ is the same as Disk $dpb$Equivalent Parameters$als$Same Allocation Vector Size$css$Same Checksum Vector Size$xlt$Same Translate Table$too few$Disk $ is CP/M 1.4 Double Density Compatible$65536$128 Byte Record Capacity$Kilobyte Driv IA MS*!DMbͧ*! Nt*! N*!!!s!!:!R!!5:!l*!& Nv*!M*!+DMͧ*!+DMͧ*!|O*!}O*!!ͷ BKͧ*!DMͧ*! A:!\S S!"!"!*!DM*!x:!=_] U:!=_a eS!!4‘z/!!6> !!R *!&! 6!!47 !!6!&6,:! H *!&!) >w#6,ͤڗ / :& :&,H*!&! w *!& ~ / :& / *!&) &!!*!&) +$Records / Block$Sectors / Track$Reserved Tracks$Sector Skew Factor$dpb$equ$Disk Parameter Block$Sectors Per Track$Block Shift$Block Mask$Extnt Mask$1.4 Compatible$Disk Size - 1$Directory Max$Alloc0$Alloc1$Check Size$Offset$xlt$equ$No Translate Table$Trane Capacity$32 Byte Directory Entries$Checked Directory Entries$Records / Extent$Records / Block$Sectors / Track$Reserved Tracks$Sector Skew Factor$dpb$equ$Disk Parameter Block$Sectors Per Track$Block Shift$Block Mask$Extnt Mask$1.4 Compatible$Disk Size -0*!ͷ "!*!"!!"!*!+!!:!*!!ͷ >!DUg>!!7!RD!$!dgx*!*!DMr*!*!"!!!:!ڗ!!!+s#r*!+"!>!·*!#"!"!*!"!*!"!D*!  A*!!ͷ "!*!͹ >!*!#"!*!D!!H + :!6 *&! ~* /*&! 6 :!!&!/HW + :!!!!!&:!H~ + :! &$!œ !"& &$!² !"& &$! !"&  &$! !"& @&$! !"& + :!slate Table$als$equ$Allocation Vector Size$css$equ$Check Vector Size$ds$rs$Uninitialized Scratch Memory Follows:$begdat$equ$Start of Scratch Area$dirbuf$Directory Buffer$alv$als$Alloc Vector$csv$css$Check Vector$enddat$equ$End of Scratch Area$datsiz$equ$-b 1$Directory Max$Alloc0$Alloc1$Check Size$Offset$xlt$equ$No Translate Table$Translate Table$als$equ$Allocation Vector Size$css$equ$Check Vector Size$ds$rs$Uninitialized Scratch Memory Follows:$begdat$equ$Start of Scratch Area$dirbuf$Directory Buffer$alv$alMrS*!+ /A*!!ͷ BKr3S!!r+s+p+q*!*!ͷ "!>!T*!*!"!*!"!:!!r+s+p+q*!DM*! A*!DM*! *!DMS!!r+s+p+q;͹O*!DM͈:͹O*!DMDi;͹OKDiqxA |S:G$:͹> !&:!>!,!H& + ; *!) &!; + :!´ >&ͪ >!] + ñ !"!*&"!*!+|ڱ *!) !!!+s#r*!}ҝ /!"!î !!! "!i :!>&ͪ >!!&!HH + *!&!) *&s#rͭ:&egdat$Size of Scratch Area$Marks End of Module$program$No Stmt$ maclib$ macpar$ disks$ diskdef$extra $!!q> !!҈:!A 2!Ð:!02!*!MU!!q:!On:!On!!p+q*!|O͘*!}O͘!!q:!0OU!!q*!&!dͷ K*!&! ͷ ! ͷ M1!͒0102821100654321@ ? @End-File$offset $bad val$dpbase$equ$Base ofs$Alloc Vector$csv$css$Check Vector$enddat$equ$End of Scratch Area$datsiz$equ$-begdat$Size of Scratch Area$Marks End of Module$program$No Stmt$ maclib$ macpar$ disks$ diskdef$extra $ DISKDEF Table Generator, Vers 1.0 $DEF No Input File Prese     ͽ\S!!6>!!ڄ*!&! ~}*! :G$A:͹ͽ*! S*! :G$j:͹ͽ*! S!!4A SA S:G$EAHA!!6>!!*!&! 6!!4!!6:&ڑ Error(s)$ ^#V|g}o !_{ozgi`N#Fogo&og_{_z#W2&!&6$̀V:& (!&6N#6o&̀!&p+q:&=!&6&͹*&DM̀!&:&2&:&=2&O>s U]?U!&q:&ʌ*&M͹!&:&ڧV:&Ҥ>Í*&&`& ~2':&<2&:'!'6!&6+~!&6!&6:&K:& :&H͍2 $DEF No Input File Present, Command Form is: GENDEF x $ Where x.DEF Holds Disk Definitions With Optional Parameters : C: Create Diskdef Comment O: Generate Offset-Relative Labels Z: Z80, 8080, or 8085 (else 8086, 8088!&6ͭ͞/:& ʋ7ͻ,</Ë*!M!u ^#VͭDͭM}ͭV}]2 }ͭ}<Q`l:& ʋf/c$ LIBno ".LIB" directory space$".LIB" disk full$cannot close ".LIB"$dw$db$.!&;L!&6;-#!&6;:&'6!&6+6;!&6:&H':&ʆ*&&& :&w <`iwO>҆:&{!&6=/!&6:&2'͍2&:&¶:&$ª!&6óX/ҳ):&:&$!&69/:&O:&QH!'6:&H!) x.LIB is Created Upon Completion. $Premature End-of-File$Length $Convert$Quote $!H$q*H$& U U!J$p+q*I$ !L$p+qe*K$DMp!O$p+q*N$2M$!Q$p+q*P$2M$!S$p+q*R$!U$p+q*T$!W$p+q*V$!Y$p+q*X$2M$![$p+\ -.! -:l(:l2!!͸!:M$B!!6!"$}2!!&6!$!+!$s{l!"$!$6:$!$ڲ*$" DM !ʞ*$"$:$<2$w!"$!$q:$ !!6:$ :!2!:$ :!<2!$$!W*$"'6>!'!&6G:'B+:&=2&!'6G:'DB:&=2&!'6 G!'6 !"&!'6:&!':'=O!& ~2'A}:'A 2'Å:'02':'2'O:'ژ!&6*&"'*'&"&:'*')"':'2'*'*&"&!&6æ:'<2'R:&E/!&6):&q*Z$!]$p+q*\$!&p+qe*&DM̀:&:>*^&#"^&!N͠!"^&^&$!Җ*^&^$ DM \ʉ*^&^$ 6!"^&Ó*^&"^&T!"^&͠*^&^$ ~2&µ!&6:&!&p+q!&6:&=2&*&&*&~2& !&60:&<*&&*&wO>9 * :$w*$#"$!!6*$},:!<2!͹W!ͥ:M$C ͹ ͹ ͹,͹!$q:$0O͹;͹D! $r+s+q+q+p+q> $,!*$* $ͷ ! ͷ ! $s~!$>! $7!H2$: $/ ͹* $M[* $! ͷ " $Ä! $q> ! $: $ A::-LR8/=6.PYv cFKL'TS(:&'͍2&':& %M/)K:&0O> /-:&AO>/H:&AO>/-LH!"&}2&2&!&6DISKSENDEFMACLIBDISKDEFvwxyz{Ϳ:&:&H:&:&;:& Ϳ:&2&>!&*&&&&*&60!&6:&P&̀>!&P!&6:&=!&P*&&`& NU!&41!&6!&6#602&&͹:& :&H:& š :& ½ :&<ʺ ç:& :&:&a:&_2&*&M02&r:&<2&!&6+6!2 $: $02 $* $M͹!$q:$O:$O!$p+q*$|O*$}O!$p+q*$DM1h͹!$q*$&dr!$p+q*$'r!$p+q*$'r:&:&ҭ!&6:&»;͹O!$6:$<2$!&:$=O!`& N͹D!$p+q*$~$ *$Ni RG)K VUP2X]^UW_]ˌȎ؎м؎646666 6 6 >  643ڹ %5GG&FF&GG oAr lȣj ) ^#V" '~2 '*&& ~2&>! 'z ! '5:&#w>! '~=O!& * '&* ' H\ ! '5, : 'e !&4:& '͝ +s#r !&6!'q!':&#wҙ !&6: '_og_ogDM!>))덑o|g =¾ DM!>)) = _{ozg~ ^#V)&6!&q:&!&D*&&.$ 6!&4):m$€!&6>!&ڀ*&&m ~A2&y*&&.$ 6!&4Q:e ˜.e - \͒:M$̀$U>p!&6#6!&6!|6!"^&!&6>!&*&&& 6 *&&& 6 :&<*$#"$!$s+p+q*$DM*$&dr!$p+qO*$DM!!$p+q* $DM/O!#$p+q:! gOY;͹*"$DMDAA!%$p+qx*$$DMr!&$q*&$M\!*$r+s+p+q*'$DM͆*)$DMS!-$r+s+q*+$M͘*,$DMS DISKDEF Table Generator, Vers 1.0     ؾd3[ M`$FF[u>is[Sm` t[S[^Cuڹzr{V2M3һ ڋ;u ulhj VW‹Z _^‹ٹw&CC&؎‹G 5G5G 58@HPX`dhlptx| X t$ott u >uà}àSR@xs uZ[ ÌڻZ[SR5st uNEȰDZ[3ø t?u[Sw˷㋟[ڹ$Q0=9vGY؎<uäMQR>&tG G G3ÉÉ ҋtڊ2à++6@3ñÊ%:u;u;u :uڻ t6Ɯ>bM   ڹ3[ td .dS>u!t&uQRZY[y4DN$Pt4 à$33tâڰSQRd(Y^& ËuCCCCCs~>nڋF<r&Y&o؊D [icPk$r8G uG tq|X<`u/P7rk$:rXutYðf&O&OAuis@r sð32wG :t3[uN&nuͰÌڻ rh& _P䆨t SQ=Y[f X䖨䒨 t䚨@t uta t$t$ta$3$$䚨 u 䚨@t愀3ttP3$<Xt2VQ Y ^Ê F t %.7DKRYbread write read1k spool assign who timedatehd stat net info(un)lockwrite rq Sorry, no room for spooling... Spooled... 24O Z t3.䀰悰S䂨uWVWVV䂨u 䀰悰>&5ItG&It G&iQ3Yn'ǜ63àtuqS[ruS~G [ZtֻN t2u@%l %ItG&t 䂢>&u\uMUttDPuqttuq<t4<s>vt's0U<u G :u G 8ruG 8suUr>vtlOhOaq<upP<u? Á>u"s (>u  >tàxr(ڻx rt.uڻL ru?r&` ru:u y i/o error loc: num: cmd: typ: vol: par: trk: sec: *** waiting at **_YX3 System call made is implemented on the DMS-816 only  tþ t8QV<ZYQ t-RQYZ u#>u YZ+ы3Ì>2þËbôw؃' tu uڹ  ڋيOW_|}Sg|!} H&yor&3o؎ŽعLsuÌڻgs o1PX:u6s.rw:O u :o u:W t <u :vtvG M> ûw8G uG ÉÉø6}fXHHrmsOt S[Cò2VWF77 mu[_^ÃÊ2ú t ts3t "$ $_rXڻ r=' >u3>tà"$ Ģiu8s&G <     * *** i/o error at location: command: COMMON BIOS for DMS HNS-86 and 5086 Version 2.4O Signing off... Digital Microsystems, Inc.  Drive A cannot be written to. Partition is a HIDOS partition. Partition is R{ % % G {  !9s! ,H !9^! ,H !9^#V^ +!9!9^#V!T;  +! 9^#V".!9!9^#V! ; DM!*.s`i +! 9^#V*.#".+s!+& +!9N#F!9^#V!!9s#r!9^#V!9s#r#+^zʉ^!^+!! 9^#Vs!! 9^#Vs*b3 +*`23!"b3 +!!9^#Vy*#>%*,)h3s#rzʔ! 9^#V*,)h3^#V)*,#",!I *** Internal error: out of memory  +! !9^#V!9^#V͒*!|Y!9s!9^! +ead Only. Partition is already owned by you on another drive. Partition is owned by user named . You don't have write ownership of it. Wrtie attempted to partition locked by user . Illegal interrupt called at 0000:0000 Please r%+b!!9s!!9s#r! !9s#r!'!9s#rn&-+a !!9s#r#+^0+ʆ !0!9s#r#+^*+ !9~#fo##s#r++^#V!9s#r#+^ !!9s#r#+^!s.#^!+ !9^#V! y+!9^! +! 9^#V^!9~#V!9~#fo+s#r!9^*!9~#fo#s#r+s +! 9~#fo+s#r#|ʁ!T`^ +!9^#VY!P! 9*!9s#r!9^#VZ*!T!9^#VI Ô!9^#V +!P! 9!X9s#r!X9 +! ! !!!I ! 9! 9^#V!3,J!9^#V##^#V"\2P!,"\2! 9^#V!3,u!9^#V!^#V"^2{!,"^2!!!b2͒*lʤ*\2!I !!*,)h3s#r:2o&+!h3*^2͌!Install Utility -- version %d.%d%c%c Caneset the computer !9s#r .+ʫ #+^!*+[ !9~#fo##s#r++^#V!9s#r#+^ë !!9s#rw #+^s.#^!+ʫ !9^#V! y+!9s#ri !!9s#rl+ #+^!!9s#r h+ #+^ !^#V*y+!!X9^#V*n+.!!T!^9^#VI  +! 9^#VY +! 9^#V~#ʋ! 9~#fo##s#r++^#VI _z +!!!9͒*!9^#V!9s#r!9~#fo##s#r!9^#V~#ö!9^#V$!!9^#VF! 9s#rz not open input file %s  +͗: 2o&Ó!2ú!2!2ú!2;ú!2ͻú!2ú!2!2!2ú!2Dú0úú_,c_d.fIijq9rsTw*b3| +! 9^#V!I %s +!! 9!9^!9s#r3 ! !9s#r3 !!9s#r3 !!9s#r!9^#V!9!9^#V!9^#V͒!9!9s#r!9^#V!9~#fos#r !9~#fo##s#r++^#V!9s#ry*!9s#r !9~#fo##s#r++^#V!9!9s#rs _,c d( o sy u x !9!9~#f!!9~#fo++s#r##!9~#fo,ʨ!9^#V^#V!!9g !$!9y*!9#s!9^#V^#Vy*!9s! 9^#V!!!9!9!,ʥ! 9^#V3!! 9^#V?+!!w %s +! !9^#V!9^#V͒*!9^#V! 9s#r!9^#V+! 9^#V;:!,;:!"9^#V;:_,Y +*f3"d3!!9^#V!,)͗{!!,! 2ͬ){]*b3|ʐ*d3!I *** Error: EOF while processing line %d  +!!9^#V^!b2s +!!9^#V^!b2s +! 9^#VoV,!9s#r!9^#V!9~#fo3,/!9^#V!9s#r!9~#ʉK!9~#fo#s#r!9~#fo+s#r#!9~#fo3,ʉ!9^#V`i++ʆ!<!!9s#ræ!9~#fo#s#r!9^#V~!9^#V!9~#fo2,!9~#fo#s#r+^`i++!×!9^#V!9~! 9s#r! 9~# ! 9s! 9^ !!9~#fo#s#r+s!9^#V^! 9~#fo+s#r#|x !T! T!TG ! 9^#V!9~#fo, !T! T!T! !9~#fo+s#rs! 9~#fo#s#r ! 9^!9~#fo#s#r+s! 9~#fo+s#r _,^!b2^!+#!9^#V;/!9^#V; +/!! 9K +!! ;(!! ;( +!*\2F"`2|ʑ!"b3!!r +*f3#"f3*`2!P! 2v¿!"b3*b3|+! 2!9s#r!9~#fo#s#r!9^#V^! ,!9^#V     #fos#r!9~#_%!9~#fo#s#r!9~#fo+s#r#!9~#fo3,_! `i++\!Æ`i++w!!9~#fo#s#r !9^#V!",",! 9~2,G+V+^+6",+N+V+^!,w#ºy/w#!,>^)|g, ^#V*2,z$!!;(!!;(".4+<$*.4+^$!".4!!!͒*!"2!*.4|j$!`i"2!! ^#V"2! +! 9^#V)))-^H+!å$H+"*.!".*.$*.!4$#4*.+".}¦$$$o&".4*. +!9!6^#V!9^#V!$ ^!ͮ*!$ ^!9~#fo+!$ s{P`i!~#fo#s#r! +:0!}20!}21}20!0! ;(! !;(:1o&+ʧ!}20!:i.o:0o#}20&0#s!"2:0o&DM!9~#fo3,!9^#VBK!9^#V*20ͮ*`i*9~#fo#s#r! 9^#V! 2,/nfm+9!".4!!.DMI`iDM`i~#j!9^#V`i^#V͡)jA! ^#V!9^#V!+#!9s#r!9^#V!+ʯnu}¯!".4!!9^#V!+nu}!".4!! ^#Vsrnunu!}ut!9^#V! ^m +?!`in+s!`is#r! s#r!!9^#V!+v!`in+s!`is#r! s#r!`i~#‡c! ^#V!+!!9! ^m +!9^#V! ^#V`is#r! ^#V! ^#V! s#r!`in+s!9^#Vs+=Z!6~*,+",w!,#!*,4+6-0123456789ABCDEF +DM|Z!!9^#V!9^#Vr +!9^#V3!,DMÔ`iDMx£!".4!!9^#V͡)ʷÌ! ^#V!9^#V+!!9^#V!s!!9^#V!s!9^#VO(DM|)!9!;(DM͕)`i+:%!".4!! +! 9^#V!9~#foy+DM%|y%!!9^#V͒* +!9N#F! ^#V+))!9s#r͋'!9^#V%|%PY,%!9^#V!9~#fo͕,%!9^#V%!9^#Vͮ* +!2"2`i:0oV,}20`i +!9N#F!4 #!9~#fo2,i ! 9^#V;(`i#DM+s!+i -  +! 9^#V)))-DM!9^#V!9^#V! ^#V! ^)j.^#V+ +!DM!9^#Vn&&|)$~"!n$&!V,DM!9~#fo͕,!!!9^#V!9^#Vnf+! 9!2,6!mut!! 9^#V +! 9^#V!2,e! 9^#V! 3,o!".4!! 9^#V)))-DM! ^#V! ^#V+! 9s#r!! s! s! s`is!m! s#r! 9^#V +!/DM`i'DM`i0͔,`i%~!".4!`i~#fo#s#r+s!+ +! -DM`i~I`i DM-͆,F!%!`is#r! s#r! s#r`i +!9N#F! ^~$ʙ!! s#r`i! s#r!%!9s#rz!! s#r!`in+s!9^#V! s#r!.:s# y*"04*-"249^#V +! 9N#F!9^#V!9~#foy+!9#͔,m!9^#V`i#DM+^ͯ+j!2!9^#V +! 9^#V!9~#fo+s#r!3,!9^#VDM,`i#+s`i +Æ!u`i+! 9~#fo+!! 9^#V9^#V###ͻ+#!9s#r* 2|/&!2"2" 2nfDMH&`i! ^#VBK! ^#V`i,ʤ&! ^#V`i^#V))PY+ʤ&! ^#V^#V`i~#fos#r! ^#V##^#V! s#rH&`i^#V!9~#fo͆,@'`i^#V!9~#fo+&! ^#Vsr('!9^#V))PY" 2* 2ut! ^#V* 2##9^#VBK!9^#V!"!͕)!!9^#V`iV,ͻ+! 9s#rzʗ!! 9^#V!9^#V`i͠$!9s#rzʗ!͕)! 9^#V!9~#foV,ͫ+PYDM|”!!`i! 9^#V!ͫ+PYDM`i!9~#fo͔,!!9^#V`iV,!9^#V`i!!͕)`i͕)!9^#V +! 9N#F#!9^#VO(!9s#r!+)!".4!!9^#V!+Dm)!9s#r!9^#V|)!9^#V!+j!;(!;(+ʰ!9^#V!+ʠ!;(+ʭ!".4͕)!!9^#V!++!".4͕)!!!! s#r!# s!$ s!9^#V!& s`i!9^#V!- +!!D/!ͮ*!:o&+D/s!"/!D/DM!"/*/2,`i^! +x`i^! +ʀ`i#DM\`i~`i^!>+ʞ!ò`i^!<+ʇ!`i#DM^! +`i^! +ò`i`i#DM~`i^! +`i^! +! +! - +! 9N#Fz,v!+c`i~#fo+s#r!`in+s!_,` `<v +! 9N#F! ^#V`i^#V͆,;! ^!+ʯ!!`in+s`i~#c! ^#V! ^#V! ^p,#s#r`i^#V!9~#foV,* 2s#r!9^#V`is#r" 2!! s#r`i`i* 2+ʇ'!3)DM+c'!!`is#r!! s#r`i͋'* 2DM:& +! 9^#V!##~#ʮ'!* 2DMÿ'! ^#VBK`i͕,'! ^#V͕,(! ^#V`i͆,(PY͕,(! 2,"!!9^#V!$ ^!!9^#Vͮ*!";(".4|G"!!$ ^!9~#fo+!$ s{y"`i!~#fo#s#r! +!9N#F!9^#V+#|"`i^! +ʼ"! !;(`i#DM+^!;(Ô"!9^#V +!9N#F!9^#V+#|#`s#r!9^#V!+#!% s!I!9^#V!s#r!9^#V!+B"#͕)! +! 9N#F#!;(!!% s! +! 9^#V)))-DM!9^#V!9^#V! ^#V`i^)a.^#V+ +!DM!9^#Vn&&|)$~#n$&!V,DM!9~#fo͕,!`i#DM+s?|0!͹>!+ʄ!!)!*!!*!! ;(! `i*/#"/+)/s#r`i#DM~`i^! +`i^! +!`i#DM+sÛO!/*/!Can't open file for| !!`in+s!! ^#V`is#r! s#r`i~#fo#s#r+^!+ +!-!9^#Vl +! 9N#F!9^#V`i +ʦ! ͯ+ʦ!ͯ +!9N#F! ^#V`i^#V͆,! 9^#V!+ͬ! 9^#V`i~#fo#s#r+s^#V͔,(ö'! ^#Vsr! s#r`i" 2!H+>(H+*.DM*.og!9N#F#^#V f( j([(kb6#> 6 #=q(>6#=z( ')ڛ(0_zWÅ(/¥(è( : >( A)[(@(a){)`w# .()()w#({o|g )i#DM+^!9^#V;("!9^#V +! 9N#F!#;(`i!~#R#!!$ s!`i!~#fo+s#r#o#!!͕,ʢ#+^!,ʟ##â#u#!$ s!+#`i!~#fo#s#r!!$ s! +!"2 +! 9N#F*2PY, $!!9^#VBK!9^#V#͕)!!9^#V`iV,ͻ+! 9s#rzʋ! 9^#V!9^#V`i͘$!9s#rzʋ͕)! 9^#V!9~#foV,ͫ+PY! 9^#V!ͫ+PYDM`i!9~#fo͔,!9^#V`iV,!9^#V`i͕)`i͕)!9^#V +! 9N#F#!!9 redirection: $ +*.+!DM`i 2,<`i#DM+?"! 9~#_!;(+_!c$A:$$$.SUB +!".4! +!con:CON:lst:LST:prn:PRN:pun:PUN:rdr:RDR: +!9^#V!!9^#V +!-!! 9s#r ! !+ +! -DM`i-͔,2`i DM3 +! 9N#F!`i~ʟ! ^!+n!ͬ! ^?+! ^!+ʟ! ^#V͋'!! s +! 9N#F!".! ^!+!! ^!+?! ^#V`i^#VV,! ^#V     )w#(&jz!|*) >?a{ 0:1)7!9^#V*-W)*04}|W)*-"-|!=!9}_|#W"04H+ o&H+ 2r.:. _H+ :r._!9õ)!9F+N+V+^+~+ngx)))# þ)og!9V+^+~+ngw)#)|!9F+N+V+04+8 ;8257 out mode dmac_stat equ base204+8 ;8257 in status fdc_sel equ base204+9 ;FDC select port (not used) fdc_segment equ base204+10 ;segment address register reset_204 equ base204+15 ;reset entire interface max_retries equ 10 ;max retries ony ;| | ;--------------------------------------------- ENDIF ;loader_bios csts equ 0DAh ;i8251 status port cdata equ 0D8h ; " data port IF blc_list ;---------------------------------------------  the following program in ; the implementation of CP/M, MP/M or ; CP/NET for the 8086 or 8088 Micro- ; processor) true equ -1 false equ not true ;********************************************* ;* * ;^+~+ngx*w*# *|!91*!9F+N+V+^+~+ng対C*#;*xT*wT*# C*w|!9^#V#n~v*q*#d*!|!9~#foʎ*#Å*}!9^#V#N#F#nxʬ*s# á*! 9F+N+V+^+~+ng**}** +!9~a*{* o&!9~A+[ disk i/o ;before perm error cr equ 0dh ;carriage return lf equ 0ah ;line feed cseg org ccpoffset ccp: org bios_code ;********************************************* ;* * ;* BIOS Jump Vector ;| | lsts equ 41h ;2651 No. 0 on BLC8538 status port ldata equ 40h ; " " " " " data port blc_reset equ 60h ;reset selected USARTS on BLC8538 ;| | ;------* Loader_bios is true if assembling the * ;* LOADER BIOS, otherwise BIOS is for the * ;* CPM.SYS file. Blc_list is true if we * ;* have a serial printer attached to BLC8538 * ;* Bdos_int is interrupt used for earlier * ;* versions. + o&DM!99`i+|DM!99!"+`i~# x=+!9W+.~#^+!k+v+|DM!>))҉+ =+}{_ʸ+|+|7g}ož+{_ʸ+)³+}{_ʸ+|g}o+|g}o|/g}/o|g}o|g}o|,,},| for Individual Routines * ;* * ;********************************************* jmp INIT ;Enter from BOOT ROM or LOADER jmp WBOOT ;Arrive here from BDOS call 0 jmp CONST ;return console keyboard status --------------------------------------- ENDIF ;blc_list ;********************************************* ;* * ;* Intel iSBC 204 Disk Controller Ports * ;* * ;** * ;* * ;********************************************* loader_bios equ true blc_list equ true bdos_int equ 224 ;reserved BDOS Interrupt IF not loader_bios ;------------------- title '8086 Disk I/O Drivers' ;********************************************* ;* * ;* Basic Input/Output System (BIOS) for * ;* CP/M-86 Configured for iSBC 86/12 with * ;* the iSBC 204 Floppy Disk Co,!},|,!}|*,}|?>o&zo&|D,}|>o&|o&}/o|/g#}}o|gBK^#Vz,#yy,###g,#xt,#~#fo}|>?o&}|>o&l INSTALL.TXT$$$.SUB99rr+ww+a a+ x jmp CONIN ;return console keyboard char jmp CONOUT ;write char to console device jmp LISTOUT ;write character to list device jmp PUNCH ;write character to punch device jmp READER ;return char from reader device jmp HOME ;move to trk 00 on ******************************************* base204 equ 0a0h ;SBC204 assigned address fdc_com equ base204+0 ;8271 FDC out command fdc_stat equ base204+0 ;8271 in status fdc_parm equ base204+1 ;8271 out parameter fdc_rslt equ base204+1 ;8271 in r-------------------------- ;| | bios_code equ 2500h ccp_offset equ 0000h bdos_ofst equ 0B06h ;BDOS entry point ;| | ;--------------------------------------------- Entroller * ;* * ;* (Note: this file contains both embedded * ;* tabs and blanks to minimize the list file * ;* width for printing purposes. You may wish* ;* to expand the blanks before performing *x+44???????????}}}mmmmmmmcur sel drive jmp SELDSK ;select disk for next rd/write jmp SETTRK ;set track for next rd/write jmp SETSEC ;set sector for next rd/write jmp SETDMA ;set offset for user buff (DMA) jmp READ ;read a 128 byte sector jmp WRITE ;write a 128 esult fdc_rst equ base204+2 ;8271 out reset dmac_adr equ base204+4 ;8257 DMA base address out dmac_cont equ base204+5 ;8257 out control dmac_scan equ base204+6 ;8257 out scan control dmac_sadr equ base204+7 ;8257 out scan address dmac_mode equ base2NDIF ;not loader_bios IF loader_bios ;--------------------------------------------- ;| | bios_code equ 1200h ;start of LDBIOS ccp_offset equ 0003h ;base of CPMLOADER bdos_ofst equ 0406h ;stripped BDOS entr ;* major editing.) * ;********************************************* ; Copyright (C) 1980,1981 ; Digital Research, Inc. ; Box 579, Pacific Grove ; California, 93950 ; ; (Permission is hereby granted to use ; or abstractm}}}}.. . . . . . ....mT m "" 00000 @@@@@@@@@@@@@@@ @@@@@@@ @@@@@ @@@@      byte sector jmp LISTST ;return list status jmp SECTRAN ;xlate logical->physical sector jmp SETDMAB ;set seg base for buff (DMA) jmp GETSEGT ;return offset of Mem Desc Table jmp GETIOBF ;return I/O map byte (IOBYTE) jmp SETIOBF ;set I/O m al,'z' ja uret ;greater than 'z' is ok sub al,'a'-'A' ;else shift to caps uret: ret ; utility subroutine to print messages pmsg: mov al,[BX] ;get next char from message test al,al jz return ;if zero return mov CL,AL call CONOUT  IF blc_list ;--------------------------------------------- ;| | call LISTST jz LISTOUT ;wait for printer not busy mov al,cl out ldata,al ;send char to TI 810 ;|  start entry of CCP WBOOT: jmp ccp+6 ;direct entry to CCP at command level IF not loader_bios ;--------------------------------------------- ;| | int_trap: cli ;block interrupts mov ax,cs mov ds,ax * ;* National "BLC 8538" Channel 0 for a serial* ;* 9600 baud printer - this board uses 8 Sig-* ;* netics 2651 Usarts which have on-chip baud* ;* rate generators. * ;* ap byte (IOBYTE) ;********************************************* ;* * ;* INIT Entry Point, Differs for LDBIOS and * ;* BIOS, according to "Loader_Bios" value * ;* ;print it inc BX jmps pmsg ;next character and loop ;********************************************* ;* * ;* Disk Input/Output Routines * ;* * ;**** | ;--------------------------------------------- ENDIF ;blc_list ret LISTST: ;poll list status IF blc_list ;--------------------------------------------- ;| | in al,lsts and al,81h ;look at ;get our data segment mov bx,offset int_trp call pmsg hlt ;hardstop ;| | ;--------------------------------------------- ENDIF ;not loader_bios ;********************************************* ;*  * ;********************************************* mov al,0FFh out blc_reset,al ;reset all usarts on 8538 mov al,4Eh out ldata+2,al ;set usart 0 in async 8 bit mode mov al,3Eh out ldata+2,al ;set usart 0 to 9600 baud mov al,37h  * ;********************************************* INIT: ;print signon message and initialize hardware mov ax,cs ;we entered with a JMPF so use mov ss,ax ; CS: as the initial value of SS:, mov ds,ax ; DS:, mov es,ax ; and ES: ;use local stack***************************************** SELDSK: ;select disk given by register CL mov bx,0000h cmp cl,2 ;this BIOS only supports 2 disks jnb return ;return w/ 0000 in BX if bad drive mov al, 80h cmp cl,0 jne sel1 ;drive 1 if not zero m both TxRDY and DTR cmp al,81h jnz zero_ret ;either false, printer is busy or al,255 ;both true, LPT is ready ;| | ;--------------------------------------------- ENDIF ;blc_list ret PUNCH: ;not imp * ;* CP/M Character I/O Interface Routines * ;* Console is Usart (i8251a) on iSBC 86/12 * ;* at ports D8/DA * ;* * ;*********************** out ldata+3,al ;enable Tx/Rx, and set up RTS,DTR ;| | ;--------------------------------------------- ENDIF ;not loader_bios IF loader_bios ;--------------------------------------------- ;|  during initialization mov sp,offset stkbase cld ;set forward direction IF not loader_bios ;--------------------------------------------- ;| | ; This is a BIOS for the CPM.SYS file. ; Setup all interov al, 40h ;else drive is 0 sel1: mov sel_mask,al ;save drive select mask ;now, we need disk parameter address mov ch,0 mov bx,cx ;BX = word(CL) mov cl,4 shl bx,cl ;multiply drive code * 16 ;create offset from Disk Parameter Base add bx,oflemented in this configuration READER: mov al,1ah ret ;return EOF for now GETIOBF: mov al,0 ;TTY: for consistency ret ;IOBYTE not implemented SETIOBF: ret ;iobyte not implemented zero_ret: and al,0 ret ;return zero in AL and fla********************** CONST: ;console status in al,csts and al,2 jz const_ret or al,255 ;return non-zero if RDA const_ret: ret ;Receiver Data Available CONIN: ;console input call const jz CONIN ;wait for RDA in al,cdata and al | ;This is a BIOS for the LOADER push ds ;save data segment mov ax,0 mov ds,ax ;point to segment zero ;BDOS interrupt offset mov bdos_offset,bdos_ofst mov bdos_segment,CS ;bdos interrupt segment pop ds ;restorerupt vectors in low ; memory to address trap push ds ;save the DS register mov ax,0 mov ds,ax mov es,ax ;set ES and DS to zero ;setup interrupt 0 to address trap routine mov int0_offset,offset int_trap mov int0_segment,CS mov di,4 mfset dp_base return: ret HOME: ;move selected disk to home position (Track 0) mov trk,0 ;set disk i/o to track zero mov bx,offset hom_com call execute jz return ;home drive and return if OK mov bx,offset bad_hom ;else print call pmsg ;"Hgs ; Routine to get and echo a console character ; and shift it to upper case uconecho: call CONIN ;get a console character push ax mov cl,al ;save and call CONOUT pop ax ;echo to console cmp al,'a' jb uret ;less than 'a' is ok cmp,7fh ;read data and remove parity bit ret CONOUT: ;console output in al,csts and al,1 ;get console status jz CONOUT ;wait for TBE mov al,cl out cdata,al ;Transmitter Buffer Empty ret ;then return data LISTOUT: ;list device output  data segment ;| | ;--------------------------------------------- ENDIF ;loader_bios mov bx,offset signon call pmsg ;print signon message mov cl,0 ;default to dr A: on coldstart jmp ccp ;jump to coldov si,0 ;then propagate mov cx,510 ;trap vector to rep movs ax,ax ;all 256 interrupts ;BDOS offset to proper interrupt mov bdos_offset,bdos_ofst pop ds ;restore the DS register ;********************************************* ;*      ome Error" jmps home ;and retry SETTRK: ;set track address given by CX mov trk,cl ;we only use 8 bits of track address ret SETSEC: ;set sector number given by cx mov sect,cl ;we only use 8 bits of sector address ret SECTRAN: ;translate s inc BX mov al,[BX] ;get command or al,sel_mask ;merge command and drive code out fdc_com,al ;send command byte parm_loop: dec cl jz exec_exit ;no (more) parameters, return inc BX ;point to (next) parameter parm_poll: in al,fdc_stat te;* Send_com sends a command and parameters * ;* to the i8271: BX addresses parameters. * ;* The DMA controller is also initialized * ;* if this is a read or write * ;* * ;***************r exec_exit: ret dr_nrdy: ;here to wait for drive ready call test_ready jnz retry ;if it's ready now we are done call test_ready jnz retry ;if not ready twice in row, mov bx,offset nrdymsg call pmsg ;"Drive Not Ready" nrdy01: call test_com ;transmit command to i8271 ; check status poll mov BX,last_com mov al,1[bx] ;get command op code mov cx,0800h ;mask if it will be "int req" cmp al,2ch jb exec_poll ;ok if it is an interrupt type mov cx,8080h ;else we use "not command bector CX using table at [DX] mov bx,cx add bx,dx ;add sector to tran table address mov bl,[bx] ;get logical sector ret SETDMA: ;set DMA offset given by CX mov dma_adr,CX ret SETDMAB: ;set DMA segment given by CX mov dma_seg,CX ret ; st al,20h ;test "parameter register full" bit jnz parm_poll ;idle until parm reg not full mov al,[BX] out fdc_parm,al ;send next parameter jmps parm_loop ;go see if there are more parameters ;********************************************* ;* ****************************** send_com: in al,fdc_stat test al,80h ;insure command not busy jnz send_com ;loop until ready ;see if we have to initialize for a DMA operation mov al,1[bx] ;get command byte cmp al,12h jne write_maybe ;if_ready jz nrdy01 ;now loop until drive ready jmps retry ;then go retry without decrement zret: and al,0 ret ;return with no error code wboot_l: ;can't make it w/ a short leap jmp WBOOT ;********************************************* ;* usy" and al,0fh cmp al,0ch ;unless there isn't mov al,0 ja exec_exit ; any result ;poll for bits in CH, exec_poll: ; toggled with bits in CL in al,fdc_stat ;read status and al,ch xor al,cl ; isolate what we want to poll jz exec_po GETSEGT: ;return address of physical memory table mov bx,offset seg_table ret ;********************************************* ;* * ;* All disk I/O parameters are setup: the * ;* Read and Write entry  * ;* Data Areas * ;* * ;********************************************* data_offset equ offset $ dseg org data_offset ;contiguous with c not a read it could be write mov cl,40h jmps init_dma ;is a read command, go set DMA write_maybe: cmp al,0ah jne dma_exit ;leave DMA alone if not read or write mov cl,80h ;we have write, not read init_dma: ;we have a read or write operation * ;* The i8271 requires a read status command * ;* to reset a drive-not-ready after the * ;* drive becomes ready * ;* * ;******************ll ;and loop until it is done ;Operation complete, in al,fdc_rslt ; see if result code indicates error and al,1eh jz exec_exit ;no error, then exit ;some type of error occurred . . . cmp al,10h je dr_nrdy ;was it a not ready drive ? points transfer one * ;* sector of 128 bytes to/from the current * ;* DMA address using the current disk drive * ;* * ;********************************************* READ: mov al,12h ;basic read sector ode segment IF loader_bios ;--------------------------------------------- ;| | signon db cr,lf,cr,lf db 'CP/M-86 Version 1.1',cr,lf,0 ;| | ;--------------------, setup DMA controller ; (CL contains proper direction bit) mov al,04h out dmac_mode,al ;enable dmac mov al,00 out dmac_cont,al ;send first byte to control port mov al,cl out dmac_cont,al ;load direction register mov ax,dma_adr out*************************** test_ready: mov dh, 40h ;proper mask if dr 1 test sel_mask,80h jnz nrdy2 mov dh, 04h ;mask for dr 0 status bit nrdy2: mov bx,offset rds_com call send_com dr_poll: in al,fdc_stat ;get status word test al, ;no, dr_rdy: ; then we just retry read or write dec rtry_cnt jnz retry ; up to 10 times ; retries do not recover from the ; hard error mov ah,0 mov bx,ax ;make error code 16 bits mov bx,errtbl[BX] call pmsg ;print appropriate message command jmps r_w_common WRITE: mov al,0ah ;basic write sector command r_w_common: mov bx,offset io_com ;point to command string mov byte ptr 1[BX],al ;put command into string ; fall into execute and return execute: ;execute command stri------------------------- ENDIF ;loader_bios IF not loader_bios ;--------------------------------------------- ;| | signon db cr,lf,cr,lf db ' System Generated - 11 Jan 81',cr,lf,0 ;|  dmac_adr,al ;send low byte of DMA mov al,ah out dmac_adr,al ;send high byte mov ax,dma_seg out fdc_segment,al ;send low byte of segment address mov al,ah out fdc_segment,al ;then high segment address dma_exit: mov cl,[BX] ;get count 80h jnz dr_poll ;wait for not command busy in al,fdc_rslt ;get "special result" test al,dh ;look at bit for this drive ret ;return status of ready ;********************************************* ;* *  in al,cdata ;flush usart receiver buffer call uconecho ;read upper case console character cmp al,'C' je wboot_l ;cancel cmp al,'R' je outer_retry ;retry 10 more times cmp al,'I' je z_ret ;ignore error or al,255 ;set code for permanent errong. ;[BX] points to length, ; followed by Command byte, ; followed by length-1 parameter bytes mov last_com,BX ;save command address for retries outer_retry: ;allow some retrying mov rtry_cnt,max_retries retry: mov BX,last_com call send      | ;--------------------------------------------- ENDIF ;not loader_bios bad_hom db cr,lf,'Home Error',cr,lf,0 int_trp db cr,lf,'Interrupt Trap Halt',cr,lf,0 errtbl dw er0,er1,er2,er3 dw er4,er5,er6,er7 dw er8,er9,er************** ; * ; * getldr: get CP/M loader from 1st N tracks ; * ; ************************** getldr: mov dx,offset askget call crmsg ;which drive is source on ? call getchar ;must get from disk - not from memory mov ah,al ;save asci' jz gl ;check for file given on command line call getfile ;read ldr from file jmp ps gl: call getldr ;read ldr from 1st 2 tracks ps: call putldr ;put ldr on " " " jmp reboot ; *************************** ; * ; * getfile: get the  (either from a disk file, or from ; the system tracks of an existing CP/M-86 system diskette) to a new ; diskette. ; The following equates will require modification for different ; diskette formats. For convienence, they are only referenced ; by aff+0400h+15) / 16 tpa_len equ 0800h - tpa_seg db 0 ;fill last address for GENCMD ;********************************************* ;* * ;* Dummy Data Section * ;* A,erB dw erC,erD,erE,erF er0 db cr,lf,'Null Error ??',0 er1 equ er0 er2 equ er0 er3 equ er0 er4 db cr,lf,'Clock Error :',0 er5 db cr,lf,'Late DMA :',0 er6 db cr,lf,'ID CRC Error :',0 er7 db cr,lf,'Data CRC Error :',0 er8 db cr,li char sub al,'A' ;normalize drive number cmp al,ndisks ;valid drive? jb getc ;skip to getc if so call baddisk ;invalid drive number jmp getldr ;to try again getc: mov gdisk,ah ;ascii drive letter for message call sel ;to select the drfile specified in command tail into ram ; * ; *************************** getfile: cmp byte ptr .fcbtype,' ' jnz opn mov byte ptr .fcbtype, 'C' mov byte ptr .fcbtype + 1,'M' mov byte ptr .fcbtype + 2,'D' opn: mov dx,fcbaddr ;try to op pair of data bytes near the end of the data segment. ; In addition, the skew table in the data area will need modification. sdspt equ 26 ; number of sectors per track sdlt equ 2 ; " of tracks for loader ; *********** * ;********************************************* dseg 0 ;absolute low memory org 0 ;(interrupt vectors) int0_offset rw 1 int0_segment rw 1 ; pad to system call vector rw 2*(bdos_int-1) bdos_offset rw 1 bdos_segment rw 1 f,'Drive Not Ready :',0 er9 db cr,lf,'Write Protect :',0 erA db cr,lf,'Trk 00 Not Found :',0 erB db cr,lf,'Write Fault :',0 erC db cr,lf,'Sector Not Found :',0 erD equ er0 erE equ er0 erF equ er0 nrdymsg equ er8 rtry_cnt db 0 ;disk eive in al call crlf mov dx,offset getmsg call outmsg ;make sure right drive call getchar cmp al,cr ;user mistake, no cr jnz gboot call crlf mov rewr,0 ;set to read for getput call getput mov dx,offset done call outmsg ret gboot:en it call open inc al ;255 becomes 00 jnz rdok ;ok to read if not 255 mov dx,offset nofile call crmsg ;file not present, error and reboot jmp reboot rdok: mov byte ptr .fcbcr,0 ;current record = 0 mov dx,offset loadp ;base of buffer *************** ; * ; * global equates ; * ; ************************** bdosint equ 224 ;BDOS interrupt number false equ 0 true equ not false cr equ 0dh ;carriage return lf equ 0ah ;line feed sdndisks equ 16 ; maximum num END rror retry counter last_com dw 0 ;address of last command string dma_adr dw 0 ;dma offset stored here dma_seg dw 0 ;dma segment stored here sel_mask db 40h ;select mask, 40h or 80h ; Various command strings for i8271 io_com db 3 ;length rd_ jmp reboot ;back to cp/m ; ******************************* ; * ; * putldr: put CP/M loader on 1st N tracks ; * ; ******************************* putldr: mov dx,offset askput call crmsg ;what drive to put ldr call getchar cmp al,cr ; mov cx,maxsecs ;sector count rdinp: push cx push dx ;ready for dma call bdma ;bdos dma function mov dx,fcbaddr ;ready for read call dread pop dx ;recall dma address pop cx ;recall sector count cmp al,1 ;check for eof jz don dec ber of drives sdsecsiz equ 128 ; size of each sector tpa equ 100h fcbaddr equ 5ch fcbname equ fcbaddr + 1 ;1st char of file name fcbtype equ fcbaddr + 9 ;file type fcbcr equ fcbaddr + 32 ;current record cseg jmp start db ' COPYRIGHT (C) wr db 0 ;read/write function code trk db 0 ;track # sect db 0 ;sector # hom_com db 2,29h,0 ;home drive command rds_com db 1,2ch ;read status command ; System Memory Segment Table segtable db 2 ;2 segments dw tpa_seg ;1st seg starts after BIOSall done if cr jz pboot ;this is normal program exit point mov ah,al ;save ascii drive letter sub al,'A' ;make it a number cmp al,ndisks jb putc call baddisk ;invalid drive name jmp putldr ;to try again putc: mov pdisk,ah ;drive letcx ;don't read to far jz don or al,al ;0 if read ok jnz badrd add dx,secsiz ;inc dma by sector size jmp rdinp don: ret badrd: ;read error encountered in input file mov dx,offset badfile call crmsg jmp reboot ; ************1981, DIGITAL RESEARCH ' rs 100h ; Emergency Patch Area (DRI) ; *********************** ; * ; * program begins here ; * ; *********************** start: mov ax,ds mov es,ax mov dx,offset signon call outmsg cmp byte ptr .fcbname,'  title 'LDCOPY Ver 1.1 Oct 81' vers equ 10 ; Copyright, (C) 1981 ; Digital Research, Inc. ; P.O. Box 579 ; Pacific Grove, CA 93950 ; LDCOPY is used to generate and propagate bootable CP/M-86 systems. ; It copies a CP/M-86 Loader image dw tpa_len ;and extends to 08000 dw 2000h ;second is 20000 - dw 2000h ;3FFFF (128k) include singles.lib ;read in disk definitions loc_stk rw 32 ;local stack for initialization stkbase equ offset $ lastoff equ offset $ tpa_seg equ (lasto     ter in message call sel ;select dest drive in al mov dx,offset putmsg call crmsg ;check with user for ok call getchar cmp al,cr ;user mistake if not cr, reboot jnz pboot call crlf mov rewr,1 ;set to write for getput call getput ;to p* dma: ;set dma address to value of cx mov al,setdma jmp bios ;**** read: ;perform read operation mov al,readf jmp bios ;**** write: ;perform write operaton mov al,writf jmp bios ; ************************** ; * ; * data are dl,al mov cl,cono jmp bdos ;**** crlf: ;send carriage return, line feed mov al,cr call putchar mov al,lf call putchar ret ;**** crmsg: ;print message addressed by dx til zero ;with leading crlf push dx call crlf pop dx **** ; * ; * utility subroutines ; * ; **************************************** ; ;***** multsec: ;cx * sector size push dx ;return value in cx mov ax,secsiz mul cx mov cx,ax pop dx ret ;***** baddisk: mov dx,offset qdisk ;bad distran(0) call multsec ;cx * sector size add cx,dmaddr ;base of dma for this track ;+(tran(sector)-tran(0))*secsiz call dma ;dma address set from cx ;dma address set, clear retry count trysec: ;try tut loader back on diskette mov dx,offset done call outmsg jmp putldr ;for another put operation pboot: jmp reboot ;back to cp/m ; *********************** ; * ; * getput: get or put loader (rewr=0 for read, 1 for write) ; * disk is already as ; * ; ************************** dseg org 0100h ; skip past page zero ;messages signon db 'LDCOPY VERS ' db vers/10+'0','.',vers mod 10+'0','$' askget db 'Source Drive Name $' getmsg db 'Source On ' gdisk rs 1 ;filled in at get ;drop thru to outmsg0 ;**** outmsg: mov cl,prstr jmp bdos ;dx has string addr ;**** bdma: ;dx has address mov cl,setdmaf jmp bdos ;**** dread: ;disk read function mov cl,dreadf jmp bdos ;**** open: ;file open function mov ck name call crmsg ret ; ********************** ; * ; * bdos subroutines ; * ; ********************** bdos: int bdosint ret ;function numbers in cl reset equ 0 ;warm boot coni equ 1 ;console input cono equ 2 ;console output pro read or write current sector or rewr,0 ;read or write? jz tryread ; Start of Patch 02 3/08/82 by rld as per DRI instructions mov cl,00 mov ax,track inc ax cmp ax,nlt jne normal_write mov ax,sector inc ax cmp ax,spt jne normal_writselected ; * ; *********************** getput: mov bx,offset loadp ;load point in ram for cp/m during LDCOPY mov dmaddr,bx ;clear track to 00 mov track,-1 ;start with track equal -1 rwtrk: ;read or write next track inc track ;track =function db ', Then Type Return$' askput db 'Destination Drive Name (Or Return To Reboot) $' putmsg db 'Destination On ' pdisk rs 1 ;filled in at put function db ', Then Type Return$' errmsg db 'Permanent Error, Type Return To Ignore$' done db 'l,openf jmp bdos ;**** bios: mov fnum,al ;bios function number mov bcx,cx mov bdx,dx mov dx,offset(bds) mov cl,biosf jmp bdos ; **************************** ; * ; * bios utilities ; * ; **************************** seldsk equ 9 str equ 9 ;print string rconb equ 10 ;read console buffer self equ 14 ;select disk openf equ 15 ;disk open setdmaf equ 26 ;where data will go dreadf equ 20 ;disk read biosf equ 50 ;bios call reboot: mov al,0 call sel call crlf moe mov cl,01 Normal_Write: ; End of Patch 02 installed rld 8/30/82 ;must be write call write jmp chkrw ;check for error returns tryread: call read chkrw: or al,al jz rwsec mov dx,offset errmsg call outmsg call getchar cmp al, track + 1 mov cx,track cmp cx,nlt ;number of loader tracks = current track ? jnz nxttrk ;end of this routine > 128 bytes jmp endrw ;end of read or write ;otherwise notdone, go to next track nxttrk: mov cx,track call trk ;to set tracFunction Complete$' qdisk db 'Invalid Drive Name$' nofile db 'No Source File On Disk$' badfile db 'Source File Read Error$' ;translate table tran dw 1,3,5,7,9,11,13,15,17,19,21,23,25 dw 2,4,6,8,10,12,14,16,18,20,22,24,26 ;leave room ;wboot+24 for disk select settrk equ 10 ;wboot+27 for set track function setsec equ 11 ;wboot+30 for set sector function setdma equ 12 ;wboot+33 for set dma address readf equ 13 ;wboot+36 for read function writf equ 14 ;wboot+39 for write functiov cl,reset mov dl,0 ; release memory jmp bdos ;**** getchar: ;get an upper case char into al call getbuf ;use buffered console read cmp conbuf+1,0 ;just a crlf? mov al,cr jz ex mov al,conbuf+2 ;first char read cmp al,'a' ;translatecr jne reboot1 ;local jmp then to reboot, >128 ;typed a cr, ok to ignore call crlf jmp rwsec endtrk: ;end of track mov cx,spt ;sectors per track call multsec ;*secsiz mov bx,dmaddr ;base dma for this track add bx,cx k mov sector,-1 ;counts 0, 1, 2, . . . 25 ;sector incremented before read or write rwsec: ;read or write sector inc sector ;to next sector mov bx,sector ;current sector cmp bx,spt ;sectors per track jz endtrk ;read or write sectofor double density dw 0,0,0,0,0,0,0,0 dw 0,0,0,0,0,0,0,0 dw 0,0,0,0,0,0,0,0 dw 0,0,0,0,0,0,0,0 ; (64 extra bytes reserved) ; ************************* ; * ; * variables ; * ; ************************ bds: ;bios data structure fnumn sel: ;select disk given by register a mov cl,al mov al,seldsk jmp bios ;**** trk: ;set up track mov al,settrk ;offset for settrk entry jmp bios ;gone to settrk ;**** sec: ;set up sector number mov al,setsec jmp bios ;*** to upper case if lower jb ex cmp al,'z' ja ex and al,5fh ;it is lower, make upper ex: ret ;**** getbuf: ;read console buffer mov cl,rconb mov dx,offset conbuf jmp bdos ;**** putchar: ;write character from al to console mov ;+ spt * secsiz mov dmaddr,bx ;ready for next track jmp rwtrk ;for another track endrw: ;end of read or write, return to caller ret reboot1:jmp reboot ;farther than 128 bytes ; *************************************r to or from l_5: ;current dma address mov si,offset tran add bx,bx ; double sector number mov cx,[bx+si] ;xlate to physical sector push si push cx call sec ;set up sector number pop cx pop si mov bx,[si] sub cx,bx ;tran(sector)-      rb 1 ;storage for bios parameters bcx rw 1 ;the bdos bios func puts these bdx rw 1 ;in registers before jumping to bios nlt dw sdlt ;number of loader tracks spt dw sdspt ;sectors per track ndisks db sdndisks ;number of disks secsiz dw e 9 ? add al,'0' ;digit jmp prn p10: add al,'A'-10 ;char a-e prn: mov dl,al ;****** putchar: mov cl,coutf jmp sys_vec ;****** initlbdos: mov cl,seldsk ! mov dx,bootdrv ; select boot disk jmp sys_vec ;****** openfnc: mov cl,opeld from header mov ldseg,ax ; save it and mov dx,ax ! call setdmab ; set DMA segment for disk IO mov dx,offset segment ! call msg ; put memory map on console mov ax,ldseg ! call phex ; print base system segment ; mov dx,0 ;offset of C ; 128 bytes of CPM.SYS lbdosoff equ 406H ;location of LBDOS in LOADER bdos_int equ 224 ;lbdos interrupt number ; dummy section for interrupt vectors dseg 0 org 0 abs_zero rw 2*bdosint bdos_offset rw 1 bdos_segment rw 1 ; bdos  title 'CP/M-86 Loader' ; The CPMLDR consists of this module along with the ; LDRBDOS and LBIOS. ; CPMLDR resides on the first two tracks of a ; CP/M-86 system diskette and is brought into memory ; by the ROM bootstrap loader to load initiate CP/sdsecsiz ;sector size maxsecs dw sdlt * sdspt ;maximum sectors to read from file sdisk rb 1 ;selected disk for current operation track rw 1 ;current track rewr rb 1 ;read if 0,write if 1 sector rw 1 ;current sector dmaddr dw 0 ;current dma addenf ! mov dx,offset fcb ; fcb already initialized mov cl,openf jmp sys_vec ;******** ; setdma: ;set new dma addr in dx mov cl,dmaf jmp sys_vec ;******** ; setdmab: ; set new dma segment base from DX mov cl,dmabf jmp sys_vec ;PM in segment readit: call setdma ; set DMA offset for push dx ! call read ; next sector read cmp al,01H ! je done ; check for EOF cmp al,0 ! je prerr ; check for good write mov dx,offset rerr ! call msg ; print READ ERROR message function numbers coutf equ 2 pstrf equ 9 seldsk equ 14 openf equ 15 readsf equ 20 dmaf equ 26 dmabf equ 51 ;******************************* ;* ;* CPMLDR starts here ;* ;******************************* cseg org 0 ; JMPM-86 ; It opens the file 'CPM.SYS' using the LDRBDOS and LBIOS ; and then reads it into memory. Finally, a jump to the BIOS ; initialization entry point starts CP/M-86 ; The first 128 byte record of the CPM.SYS file is a header ; with the followinress retry rb 1 ;number of tries on this sector conbuf db 30 rb 32 ;console buffer ;make stack on even address loadp rs sdsecsiz*sdspt*sdlt db 0 ; force out last data segement byte end ****** ; pcrlf: mov dx,offset crlf ;print carriage return, line feed ;****** ; msg: ;print msg starting at dx until $ mov cl,pstrf ;print string function jmp sys_vec ;***** ; read: mov dx,offset fcb ! mov cl,readsf ; jmp sys_vec ; jmp stop ; hard stop on any error prerr: pop dx ! add dx,80h ; address for next record jmp readit done: mov dx,offset lenmsg ! call msg ; print length message pop ax ! dec ax ! call phex ; print last address call pcrlf ; and a crlf F to here from boot ROM jmp LBIOS ; allow loader BIOS to ; initialize start: ; loader BIOS jumps here xor ax,ax ! mov ds,ax ; temp DS at absolute zero mov bdos_offset,lbdosoff ; to patch in interrupt table mov bdos_segment,g format: ; ty rb 1 ;seg type (not used here) ; len rw 1 ;length (not used here) ; abs dw ldrstart ;absolute segment address for LOADER ; min rw 1 ;minimum mem (not used here) ; max rw 1 ;max mem needed (not used here) ; (This header record i****** ; sys_vec: int bdos_int ret ;****** ; stop: hlt ; hard stop 8086 for error jmp stop ;******************************** ;* ;* DATA AREA ;* ;******************************** nofile db cr,lf,'The File CPM.SYS Not Found On This  jmpf bios ; leap to BIOS initialization ;***************************** ;* ;* subroutines ;* ;***************************** ;****** phex: ;print 4 hex characters from ax mov cx,0404h ; 4 in both CH and CL lhex: rol ax,cl ; rotate lcs ; offset and segment mov ax,cs ! mov ss,ax ; make ss, ds, es = cs mov ds,ax ! mov es,ax mov sp,offset(stack) ; set up local stack call initlbdos ;warm up lbdos and lbios call openfnc ;open CPM.SYS cmp al,255 ! jne perr ; ins constructed automatically by the ; GENCMD utility). ; CPMLDR may be read into any segment that does not ; overlap the desired system load segment as it makes ; all memory references using copies of the CS: register ; it is entered with. false Disk$' rerr db cr,lf,'Error In Reading CPM.SYS$' segment db cr,lf,'Segment Address = $' lenmsg db cr,lf,' Last Offset = $' crlf db cr,lf,'$' ; vector for jmpf indirect to start CP/M bios dd abs_zero ; (dummy value) org offset bioseft 4 push cx ! push ax ; save crucial registers call pnib ; print hex nibble pop ax ! pop cx ; restore registers dec ch ! jnz lhex ; and loop four times ret pnib: ;print low nibble in AL as hex char and al,0fh ! cmp al,9 ja p10 ;abovsure good file mov dx,offset nofile ! call msg ; no CPM.SYS file jmp stop ; then halt the machine perr: mov dx,cs ! call setdmab mov dx,offset page1 ! call setdma ;read first page of CPM.SYS call read mov ax,word ptr page1+3 ;get abs fiequ 0 true equ not false cr equ 0dh lf equ 0ah lbios_offset equ 1200h ; offset of LBIOS biosoff equ 2500h ; offset of BIOS from start of CPM.SYS ; this is the entry point into CPM.SYS bootdrv equ 0 ; boot drive always zero       ; overlay preceding with DW's biosstart dw biosoff ; first word is BIOS offset ldseg rw 1 ; second is segment to put CPM.SYS fcb db 0,'CPM ','SYS',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 org (offset $+1) and 0FFFEh ; even address ft j%1jnunuƸiPPP<P\PtmP.%P]Up@;v P Fn6p]Up@;r@"sn6pp]UP6xP6pP1x;ps u!n6xUPFP]U P P]U~ v FA, F0P]UFPF$P]UFPFP]U Pv]Uv]UkPvsP6pJ]U츃P]UPv]UPv]UPv]Uor stack rw 32 stack equ offset $ dseg org stack page1 rb 128 ; dummy section for BIOS init label org lbios_offset lbios: end  COPYRIGHT (C) 1982, DIGITAL RESEARCH [], ERROR: $, LOAD ADDRESS $DISK WRITE$DICODE DATA EXTRASTACKX1 X2 X3 X4 8080 NZERONHEADCGROUPDGROUPEGROUPSGROUP0=x P]U6x7:P P]U6\Ptm%]U@|@;w ]UK&&]UtHtt Ppp;|vH|]UPPZPYp]U'>'w'(t'Pv]UPPz]UPvi]UPvY]UPvI]UPv9]UPv&]UFȈF'w;!<w!'طM:(t!u؀>!t뷰]à'1]U..:Fwt.u]Ulm6l< tl]UP> u]I0s>]t> ù>0u뿀>0 sf_F]UP> t]UFN ]U>w:fu]u]UF,0< vF,A<vF,A ]Ur6s(6jwBu]U3>3w1s 3Ƈ5 35P3u042>0 r@"4sW211<v@"2s'015:t21Ǡ2s40뗠4s00]U>]u@P> u@Y"sp>P,uPjPPÙ>tPfjƇjj]Uz|~$%|>wLJuxp<uAPPnt>uJt>tt4t"<uMu(hP0 Yn0P0 Yi뗀>Xu9P0 Yp4]cŀ>u&PPePaP$㉇J.t$>t;~te9~u@ÈPv@Y"rP>ttB~ȢP [JjP Yi.t뷀>u .t6t~<w3 ÃjUPP]UHĸpn@j\PP!P*PPPPw>uP(PePP\P\P\PF>u\P=>u-PV@]U]      install swap d d Remove the INSTALL II diskette and replace it with d the INSTALL III (MS-DOS) diskette. f 98 ; get into final instructions l 20 w install end d d Remove the INSTALL II diskette and replace it with d PSGROUPM*DMW pP *}5 W **Nͫ*#" k {{*DM:k k*4DM,\͡ʃ %!74!"4*4* iڵ m *4"4Î m W2;! w:;*+">f ͹ O͜ *#" p *+"͹ *#"{!6:}3*& Nk!4?k{*#":fX* ~> !q: k> :a}:_2:?O\2:  ?O\2Ë!s+q*&`:R!6>!*& :>!4½>! q: 0O> : 0: AO>the INSTALL IV (OFFLINE UTILITIES) diskette. f 98 ; force $$$.sub write and change disks l 98 s @ d d HIT RETURN WHEN THE DISKS HAVE BEEN CHANGED => r ; bye l 99 ͹ _H͡))))͹ _"!<6>!<D ͹ *<&= w*+"!<4 !<6>!<ڮ c :<2<I î !6!6>!ڠ :<!O! *&= ʙ !6!4m :« ñ U >:<<_!{!Cq!D6:C!D ͹ 2*+"!D4 !" ~2́* >: A !" ?2͸S*M28 J* ))))*& " ?2* *#"ip* ~!"!͋Õ*"v͑2 ¸* DM: * 6!"Å!":!"""}2627!62|o&1͈0102821100654321 COPYRIGHT (C) 1982, DIGITAL RESEARCH [], ERROR: $, LOAD ADDRESS $DISK WRITE$DISK READ$INSUFFICIENT MEMORY TO CREATE CMD FILE $; 5IMSTEST Version 1.2 10may84 (msh) ; ; test if ms-dos will be added to ; system control area. ; ; Version 1.1 Remove one question for MSDOS install ; ; Version 1.2 Tell user to keep hands of disk until ready l 00 d d DO NOT CH~2  *#" ́: } + :FT :]: HN M y :Fd !6y :F t !6y !6 !I6>!Iھ ͸Ҡ *I&K 6 ÷ *I&K :w?O\2!I4‚ !F6!J6!H6:F !J= !H6+6>!G/#' *G&K *F""2>!&*&$) >w#6!4 !"!"! 6͹ 2H͹ ͹ _H͡":¹͹ 2*+"!6>}ʹ*+"͹ 2« 2ʨ*& :wò*M !4r: ͹ ͹ _H͡*6& ) q#p*++"!64:­͹ o&"*LOAD ADDRESS $ERROR ADDRESS $BYTES READ:$RECORDS WRITTEN $ABSCANNOT OPEN SOURCE$CMDNO MORE DIRECTORY SPACE$CANNOT CLOSE FILE$!9"!!"!"!6#6!6!"\!;<:?Re\́\ͱ\<:ANGE DISKETTES UNTIL THE PROGRAM ASKS YOU TO d "HIT RETURN WHEN THE DISKS HAVE BEEN CHANGED" d d ; test if ms-dos to be loaded d d MS-DOS is an optional operating system. If you have d MS-DOS there will be a disk labeled &> *G& !H6$ !G4 :H6 !J6: !F4 :JI !F6:F:]: H ́:AŽ  *F&>+  q#p :M  *F&>+  q#p:F< *F&>+ Hq :X  *F&>+  q#p M i`N#F+"!6*& ~}:<2O>/H7 !5 >}ʭ͹ o&" *&>+  ͹ =2O!  !+  q#p:< *&>+ Hq*++"@: *++" *M 5!6>!g  *&>+  >͈`  *& U*  \O:*m{:222222222222222222!q*& k k!q> !ҡ:A Okê:0Ok!q:O͆:O͆!p+q*|Oͫ*}Oͫ!p+q* !p+q{*DM!INSTALL III (MS/DOS) d with your release materials. d d Do you have the INSTALL III diskette (y/n) => q 11 20 l 11 d d MS-DOS will be installed on your master ; set up for ms-dos disk change l 12 w syslib ))덑o|g8 =&DM!>))M =E_{ozg^#V) `_{ozgi`N#Fogo&og_{_z#WCODE DATA EXTRASTACKX1 X2 X3 X4 8080 NZERONHEADCGROUPDGROUPEGROU>+  > !+s#r *&>+  >͈`  *&>+  !N#Fq#p!4+,\͡ʇ %͈ *:7I_3`i Error (%d) in loading overlay %s.OVR: overlay file missing?not enough memory to load it!overlay appears corruptedfile i disks 2 diskdef 0,1,26,6,1024,243,64,64,2 diskdef 1,0 endef e after read conlin rs 32 ;length 32 buffer conlen equ offset $ - offset consiz ; rs 31 ;16 level stack stack rb 1 db 0 ;end byte for GENCMD end Product Table Add/Modify Q - QUIT Leave this program. Enter your choice --> X*0^DM`i~ʓ !!9^#V͟Wʓ `iDMk `i~ž !`iX*6^DM`i~ !!9^#V`i͟W `i`DMì `i~ !`iX!*0^Ds not an overlaycannot find itX!75:!CG Exiting program X!CGX!G!9s#r!9^#V~!5:!5:!CG!9^#V^!{]!/5:!d5:!5:!5:!5:2 This program will not work on a running Master.M`i^z, {], `iDM# X!*6^DM! ^zn {]n `i`DM#A X! !9s#r!9^#VDX!9^#V!! 9^#V͟Wʱ !!THIS IS A HEADERyX!!! 9s#r!x! 9s!! 9s!9! 9s#r! 9 You can run SYSLIB if you boot from a floppy. You are running this program on a network station. SYSLIB will read and write the tables from the LOCAL hard disk attached to this station. If you intended to work on the SHARED hard disk attached to the !9^!9s!9^!ͦ]$ !!DM6 !9n+s!9~L !PY\DM, `i^d `i ^j !|ʔ ! 5:! 5:! 5:!CG`i Error - the size of your Control Area is listed as %dk. SYSLIB only understands sizes of 256k or 512k  Master, you should abort this program now.X!!DM`iw!5:!5:J!5:JÊ!5:JÊ][HfiSYSLIB7 Sorry, you need that overlay in order to run SYSLIB. Not a Seperated Boot System Access Denied. X! EImpossible ProductZSBC-3 ComputersDSC-4DMS-1280DMS-3/C "Killer Bee"DMS-86 and DMS-5086DMS-5016DMS-816PC CardX! !!!b5:!9Y.͌&®!5:  "i!,^ !2^ !8^ DM7 !A!^!M!^!!for the Control Area. X9͋]< ! 9^#V##^K ! 9^#V##^#DM! 9^#V###^!9^#V!^#V!9^#V^#V!>%! 9X9͋]ʫ ! 9^#V##^ú ! 9^#V##^#DM! 9^#V###^!9^#V!^#V!9^#V^#V!>%! 9X!95:!5:!5:!5:!/5:!f5:!h5:!5:!5:!5:! 5:! 5:!F 5:!H 5:!! 9͠{]!9^ͧX SYSLIB MAIN MENU A - ADD/REPLACE Add or replace a Control Area Directory file E - ERASE ^!!^!!^!!^]AEL'MPQV^ SYSLIB %d.%d%c-- Maintain the System File Directory Hard disk not operational.SYSLIB1SYSLIB1SYSLIB2SYSLIB4SYSLIB3SYSLIB6X!"k!9^#V!      ^#V!͕\!]!9^#V!̀\!9~#fo^D]X!e 5:!! 9͠d !9^!l]d  Hit RETURN to continue, to abort: X! 5:!! 9͠ Press RETURN to continue --> X!! .V !!.V!!.Vͦ]D"`i)))! 9~#fo~A"`i)))! 9~#foͿ!"5:! ODD OS 0x%x CP/M 2.2 CP/M 86 HiDos MS-DOS 2.0MS-DOS 2.xMS-DOS 3.x !9^#V"T`"X!!R9s#r*T`! 9W!$! 9W!! 9 H!T99^#V*6^]`͎\! 9s#r0 +!9s#r! 9^#V!ͦ]J! 9^#V!9~#foͧ]\! 9^#V!5:!9^#V! 9~#fo]`\!9^#V!9^#V!`yX!!`! 9^#V!`\*6^]X **BUG** bad OS entry # %d in os_delete()X!! 9s#r!!9s#r!9^#V*DM!PYDM`iͦ]`i)))!9~#fo~`iA#`i###ͦ]ͦ])))!9~#fo~!È#ͦ]ʽ)))!9~#fo^!5:Á!5::ͦ])))!9~#fo~!5: File!!9^#Vͧ͠]*!5:! !]!9^#V]X!! 9^#VBKg#ͦ]ʡ`i^! ͦ]ʋ!"(^Þ`i^ͧX`i#DM+s` Too long! Re-enter --> X!DM`i#DM`iͦ]! 9~#fo#s#r+^!5:X!9^#V!p5:!! 9͠DM! 9^ͧX!9s`i{]!9^!Y{]b!9^!N{]!9^!Yl]%s (Y/N)? --> X! Is this correct X!#9^#V!ͧ]!#9^#V!5:!!DM`i#DM`iͦ]ʉ!c^A@!9s! {]ʉ!s#r!͋]I#!R9~#fo#s#r+|*#! $$!!$! 9W*T`! 9W"! !J9!X9^#V͢K {]q#!$$!H9^#V!{]ʉ#!$$!J9^#V!L9~#fo!N9~#fo*p^ʷ#!($$!J9^#V^#V}2m!J9^#V"n!L9^#V!L9^#V!X9^#V͢K!L9~#fo^$!0^{]ʠ!9~#fos#r!9^#V! ^#V! 9s#r!9^#V! ^#V!9^#V! ^!9s#r!9^#V!ͧ]ʎ!!9~#fo]s#r! 9~#fo#s#rV!9~#fos#r! 9^#V!9^#V! s#r!9^#V!9^#V! sX*<^DM!#(ͦ]`i^!ͧ]name Load Addr. Entry Off. Support Files -------- ---------- ----------- ------------- %c %8lx %4x %c X +!9s#r!9^#V!\*0^!"9~#fol]!"9^#V! ^#V! 9s#r!"9^#V! ^!9s#r!"9%cX!DM`i#DM`iͦ]W! 9^#V^! {]W! 9~#fo#s#r+^!X5:%cX!~5:! 9^#V!5: There is already a file named in the Control Area.X!|9^#V!̀\!n9s#r!!n9~#fò\s#r!n9^#V!ͧ]g!n9^#V9^s!9^`i! 9sÆx-!!15:xD!!45:`i+DM`i+DMÆxk!!!85:`i+DML`i+DMÆ]-L`il]ʰ!c^A@!9s! {]ʰÔ!#PYͦ]!#9~#foͦ]!9^!#9~#fo#s#r+sù`2$$!T9^#VqI!P9^#V.ovra:X*T`!^9^#V!$!9S:!9!9! .V!\9^#V! ̀\Î$!$DMå$!$DMå$!$DMå$!%DMå$!)%DMå$]n$v$~$$f$! .V! CGError %d loading overlay: %s $(File corrupted?)$(File not found)$(Hea`i^!ͦ]`iDMX!75:!q5: Entry Filename Track Sect Records Load Addr Exc Off ----- -------- ----- ---- ------- --------- -------X! 9^#VͿ! 9^#V!^#V!9^#V!XY|Y!9^#V! ^#V!9^#V! ^!9^^#V!"^#V!9s#r!"9^#V!$^! 9s#r +!9s#r!9^#V!\*0^!9s#r!9^#V! ^#V!9~#fo]!9s#r!9^#V! ^#V!9^#V! ^! 9~#fo]!9s#r!9^#V!]!9~#fo!9s#r!9^#V!ͧ]!9^#V!͋]!!9s#r!9^#V!9s#r!9^BK `i#DM`i!|9~#foͦ]d`i!n9~#fo]!l9s#rM!n9^#V!l9~#fo]s#r!l9^#V!͋]a!l9^#V!v9~#fo\!t9~#fo!l9^#V!n9~#fo!v9~#fo\!t9~#fo!x9~#fo^#V! 9s#r!x9~#fo^#V!9s#r!z9^#V!l] !! 9~#foD]s#r!!9i *BUG* call to dgets wants too many chars (%d)%c %c%c %cX!"*^"(^!!!9]X!9^#V! 9͠!9s#rz!"*^QY!9^#V!9~#foͦ]·!9^#V!9~#foͧ]!"(^QY! 9^!l]!"*^QY! 9X! 9QYder truncated)$(File isn't an overlay)$(Not enough memory)$X!9n#s!9^#V!͌]s%!9^#V!:&5:!:>^Š%͌&Š%!"Y^!!}2>^:V`o&%:V`o&!^&5:!DM%!&DM%!2DM%]%X%%x"&!9^#V!9^#V!9^!9^#V!9^`i#V! ^#V! 5:!9 %4x %2x %4x %8lx %4xX!P 5:! 5: Entry Filename OS Type Support Files Required ----- -------- ------- -------------------------------X! 9^#V!Ϳ!E"5:! 9^#V^Q!! 9^#V^#V! 9!9^#V!9^#V!>%! 9!9^#V! 9! 9^#V!9^#V!>%! 9!9^#V! 9~#fos#r!9^#V!9~#fos#r! 9^#V!ͧ]ʰ!! 9~#fo]s#r!9~#fo#s#r!9^#V!ͧ]!!9~#fo]s#r! 9~#fo#s#r!9^#V!9~#fo]s#rÿ~#foD]s#r!9^#V! 9~#fo ^a!v9^#V!9yX!v9^#VyX!v9^#V!9yX4XÀ! 9~#fo+s#r! 9^#V!ͧ]ʓqX!:!9^#V%XDM|¾! 9^#VBK`i#DM!#ͦ]`i~`i^!.{]`i#DM+^jY!DM!"(^!9^#V~ʧ`i#DM+ͦ]ʧ! 9QY͕YXY͸[jY!9~#fo#s#r+^ͯ!9s#r!9^#V!l]ʅ!"(^QY! 9! 9^#Vm\͕YXY ZjY! 9XYX! 9^ͧX! 9s! 9^!0͋]! 9^!9͌]! 9^!! 9^!A͋]X! 9~#&!"Y^&!"Y^(&!"Y^*Y^|6&!9&! *BUG* sector count = %d in hd_xfer *BUG* bad controller type 0x%x in hd_xfer()Xͬ&}2V`&Xl]ʨ&,3X!DM`i^!D]l]&!X!X!9^!9^#V^*!9^!D](!!I"5:p!!V"5:p!!a"5:p!!l"5:p!!w"5:p!!"5:p!!"5:p!]!!%!!0!";!#F! !"5:!DMÅ!`i#DM`iͦ]!`i)))! 9~#fo~!`i)))! 9~#foͿ`iͦ]!!"5:À!! 9^#V!?~D"!"5:!DM!`i#DM`iX! 9^#V*0^]͎\DM +`iͦ]=`iͧ]H!5:`ii#! 9~#fos#rͦ]ʣ!!9^#V!9^#V!yX! 9^#VP!!\*0^]X **BUG** bad SD entry # %d in sd_delete()X!9~#!X!9~#fo#s#r+s$#ͦ]K! !9~#fo#s#r+sX!5:!9~#l!"5:!35:!9~#ʆ!\5:!m5:!DMÛ`i#DM`iͦ]! 9^#V`i^!o5:Ö! 9^#V!XY|Y!r5:! 9^#V!^#V!5:!9~#!! 9^!F͌]! 9^!!X_!9~#fo+s#r#! 9~#fo#s#r+!9~#fo#s#r+!9^#V!ͧ]ʬ!9^#V^!9^#V^{]ʩ!9^#V^!9^#V^],!X!9^#V!9^#V!9^#V#l]X!ͦ]ͧ]-!     9^#V*E^{]'!9^*G^{]B'!!W`́+!9^#V"E^!9^+"G^! 9^Þ'! 9^!)5:!!9^#V!`yXí'!!`!9^#VyX!!W`+,í']_'x'M'!!9~#fos#r!9n#s!ͧ]'!!9s!9~#fo#s#r!9~#fo+s#r!9<#+^!*l]GQ xʔ8q8Rk8!!͚8!!98ʳ8¥8¥8:8=288!}!98888:8=288^#V#N#Fx28Axs!ͧ]&3!!9s!9~#fo#s#r×2:W^334X*Q^|^3!S"Q^|^3!35:!!DM!`is!! s:X^o! s!M! sg8ʒ3 8–3!! Hard disk i/o error: can't allocate 1k bufferX!!I9!}2g83 83!!!v8I9-͚/.!.0xinitXC.-.!!D1͍.?.!!X!!9s#rf.!9~#fo#s#r!9^#V!ͦ]ʉ.v1D]†.!W.!X!!9s#rð.!9~#fo#s#r!9^#V!ͦ].v1D].!á.!X[/!D1q/Xq/!AD1!9^!9^#V^*!9^#V!ͧ]7)!9^#V! *5:!9~#)!!W`́+!9^#V"E^!9^"G^! 9^)! 9^!A*5:!!9^#V!W`yX)!!W`!9^#VyX!!W`+,)]))o) *BUG* way = 0x%x in hd_xfer *BUG* way = 0x%x i9~#foͧ]>!9^#V!9s#r!9~#u>7>!9~#fo#s#r!9~#fo+s#r#!9~#foͧ]u>!9^#V`iXl]r>!(>!!9s#rÒ>!9~#fo#s#r!9^#V~>!9^#V!9~#foͦ]>!9~#fo#s#r+^`iXl]>!Ã>!9^#V!9~#fos#r!9~#K?X:X^o&DM! 9^#V}2X^`i!}!9^#V#N#F#~#foDM}!9~2C9o&!9~2U9##~o&X!95:2@!9s!l]ʍ9!95:!CG!9^ Hit RETURN to continue, to abort: Abnormal end at operator requestX9!9~#fo+s#r!!vX!!9s!}2:V^o&*T^͑624!!9^!ͦ]ʬ4!9n#s+}\4!"b4!"g8y4!!9nsé4!*Q^͚8 8¬4:o&@{]ʩ4!!9ns24!9^!͌]4!}2W^!08!X!9^+D]#!9s!9^#V*T^{]#5:V^o&X!:9D]//X.!!?^DM7/#ͦ]Z/`i#DM+^!I90/Xv1D]p/a/Xv1D]†/w/X.v1D]X͇/ {]ʸ/!/ʹ0!!:9DM.!:9`ix_stat_rcvX!9^#V!05:!;05:!!?n hd_xfer *BUG* blk = %d after we've done block xfer in hd_xfer *BUG* way = 0x%x in hd_xferX!9!9^+̀\m\|Y!9^#Vm\DY@͸[͊Y ZjY!9XYDY-\*!6+5:!9XY|Y!9^!9^#V!U+5:! 9!9XYDYZ|\D]}2@^!?!9~#fo#s#r!9~#fo+s#r#!9~#foͧ]K?! `iXl]H?!?r?`iXl]c?!!9~#fo#s#r:!9^#V!"_^"a^! 9~2]^G+V+^+6"[^+N+V+^!_^w#¦?y?/w#??!b^>^)|?g,?s+=?Z!"@~*9^#V!ͧ].:! 9~#fo#s#r+^!/:5:9%02x X!9!9^#V!Aͪ:X! 9^#V"Wa!9!9^#V!:ͪ:DM!*Was`iX! 9^#V*Wa#"Wa+s!D]&X!9N#F!9^#V!!9s#r!9^#V!9s#r#+^zu?%l]N?!!! 9^{]#5:S^o&:X^o&{]U5!9^!9^#Vͺ5!9^}2V^!9^#V"T^:X^o}2S^!9^!9^]]*Q^DM! 9^!l]ʣ5!!9^#VyX!}2W^ö5!!9^#VyX!X!!9s:W^545!!}2!9^!9^#V͑65!!^9!M05:!!r9 Xebec controller error at %s command buffer: status buffer: X!1!!!r$2X^0! 9^#V/͚/ʦ0!0ʹ0!!x_err_rcvX͇/!9s! 9^#V!05:!"15:!!?^9!9^!-15:[9 X9XYDYZ|\D]}2A^!9XYDY4Z|\}2B^ *** illegal sector requested trk = %x, sec = %x; xebec address = %06lxX!9^#V!͕\ʩ+!9^#V!+5:!9^#V!̀\}2C^!1!:C^o&!9^#V$2͚/+!!,0 *BUG* in just_read le[^+"[^w!_^?# @*[^ @+6-0123456789ABCDEFX!c^A@X! 9N#Fͬ@{]ʨ@!D]Õ@`i~#fo+s#r!`inT]s!N@]@ @n@@X! 9N#F! ^#V`i^#V]mA! ^!D]@!!`inD]s`i~#A9s!!9s#r! !9s#r!'!9s#rn&-l]M;!!9s#r#+^0l]r;!0!9s#r#+^*l]ʬ;!9~#fo##s#r++^#V!9s#r#+^;!!9s#r#+^!_#^!D];!9^#V! \!9s#r÷;.l]9^!ͦ]j6!9n#s+}'6!"-6!"g8D6!!9nsg6 8j6:o&@{]g6!!9ns5!9^!͌]ʊ6!*Q^8Í608!X!DM:X^o&)))))v! 9s#r!9^#V))))!9^+̀\! 9^#V###^! 9s! 9^#V!^#!9s! 9ebec controller fatal error in %s Command: SASI bus status: 0x%xX!!I9! 9^!I9!!I9o&>>@!?^@^6X!1͚/ʹ1!10do_recalX!1͚/1!10q_readyX! 9^}2?^.͇/ngth = 0x%x, not multiple of 256just_readX!9^#V!͕\S,!9^#V!,5:!9^#V!̀\}2C^! 1!:C^o&!9^#VT2͚/ʓ,!,0 *BUG* in just_write length = 0x%x, not multiple of 256just_writeXA-,!!! 9!I^yX!9"     ͕D! ^#V! ^#V! ^͢K͌]UA|>A!AA!`inT]s!! ^#V`is#r! s#r`i~#fo#s#r+^!D]X!n^!9^#V͞AX! 9N#F!9^#V`i l]A! Al]A!AX!9N#F! ^#V`i^#V]VéU! ^#Vsr! s#r`i"gd!Y1VY*M`DM*O`og!9N#F#^#V YV ]VNVkb6#> 6 #=dV>6#=mV WڎV0_zWxV/˜VÛV : >V AW[ҷV@VaW{W`w# .VVVWw#V{o|g VWw#V&jzP!9^#VX!9N#F!9^#V+#|KQ`i#DM+^!9^#V.V$Q!9^#VX! 9N#F!#.V`i!~#„Q!!$ s!`i!~#fo+s#rRʡQ!! ^Q+^!{]Q#QçQ!$ s!l]R`i!~#fo#s#r!oW$~ULn$&!]DM!9~#fo ^:L!9^#VBK!9^#VMUL͈W!!9^#V`i]/]! 9s#rzʽL! 9^#V!9^#V`iR!9s#rzʽL͈W! 9^#V!9~#fo]]PY! 9^#V!]PYDM`i!9~#fo^ M!9^#V`i]!9^#V`iMGFÁE!ea*!bx!CGCan't open file for redirection: $X*^_X!DM`i ͦ]nG`i#DM+qITG! 9~#ʑG!.VD]ʑG!G%S1EA:$$$.SUBX!"k!X!con:CON:lst:LST:prn:PRN:pun:PUN:rdr:RDR:X!9^#V!!B! 9^#V!D]B! 9^#V`i~#fo#s#r+s!D]X!c^DM`i^^dB`i DMeBDBX! 9N#F!`i~B! ^!D]ʠB!B! ^qIT]! ^!D]B! ^#V~U!! sX! 9N#F!9B"^_! ^!D]!|*W >?a{ 0:$W7!9^#V*^JW*}|JW*^"^|!=!9}_|#W"Y o&Y 2_:M` _Y :__!9èW!9F+N+V+^+~+ngxWWW# ñWog!9V+^+~+ngwW#W|!9W!9F+N+V+^+!$ s!X!"_dX! 9N#F*_dPY{]?R!! ^#V*ad{]ʬR!!.V!!.V"kl]nR*kl]ʐR!"k!!!]X!"_d!*k|ʜR!`i"_d!! ^#V"ad!X! 9^#V)))_^Y!RY"*O`!"O`*M`S*M`!4S M͈W`i͈W!9^#VX! 9N#FR.M!!9^#V!9^#V!$ ^!yX!$ ^!9~#foD]!$ s{‚M`i!~#fo#s#r!X:\cM!}2[c!}2]c}2\c![c! .V! !.V:]co&l]M!}2\c!:_o:\co#}2\c&[c#s!"]d:\co&DM!9^#V HX!_!! 9s#r?H! 9~#fo#s#r! 9^#V! ͦ]aHnfGl]kH&H!"k!!x_DM{H`iDM`i~#ʜH!9^#V`i^#V͔WʜHsH! ^#V!9^#V!D]#!9s#r!9^#V!D]Hnu}H!"k!!9^#V!D]Inu}I!"C!! ^!D]qC! ^#V`i^#V]! ^#V! ^͟Nl]qC!`inT]s!`is#r! s#r!!9^#V!l]ʨC!`inD]s!`is#r! s#r!`i~#¹C͕D! ^#V!l]C!!9! ^͟Nl]JC!9^#V! ^#V`is#r! ~+ng対X#XxXwX# Xw|!9^#V#n~AXw#¸Y!Ya~ \#Y[=ɯ<\a!daO~Y\a!daY/]#!9s#r*gd|"T!cd"ed"gdnfDM;T`i! ^#VBK! ^#V`i{]ʗT! ^#V`i^#V))PYl]ʗT! ^#V^#V`i~#fos#r! ^#V##^#V! s#r;T`i^#V!9~#fo]3U`i^#V!9~#fol]T! ^#VsrU!9^#V))PY"gd*gdut! ^#V*gd##s#r`i^#V!9oW$~TOn$&!]DM!9~#fo ^9O!9^#VBK!9^#V!PTO͈W!!9^#V`i]/]! 9s#rzO! 9^#V!9^#V`iR!9s#rzO͈W! 9^#V!9~#fo]]PYDM|O!`i! 9^#V!]PYDM`i!9~#fo^P!9^#V`i]!9^#VbDMJ`i'DM`i[c^(J`i%~2JJ!"k!!9^#VBV!9s#r!l][J!"k!!9^#V!l]vJ`W!9s#r!9^#VoW!9^#V!D]ʜJ!.V!.Vl]J!9^#V!D]J!.Vl]J!"k͈W!K!9^#V!D]l]K!"k͈9^#V! s#r!T`,s# yE*"*^"pBE^1EX!!a!yX!:o&D]as!G"ea!aDM!"!b*!bͦ]G`i^! l]ªE`i^! l]ʲE`i#DMÎE`i~G`i^!>l]E!E`i^!<l]ʹF!`i#DM^! l]F`i^! l]Y+YYa!aa#ZYa!aa#)ZYa!aa#=ZYa!aa#QZYa!aa#eZ!Ya~/w#uZ:aa?*Ya*[a))ғZ,=‹Z"[a"YaæZ:\a:aa?ZW!\a~w+·Z°Z!NyõYYaZaaZy1[YYaZyaaZ1[~#fo]*gds#r!9^#V`is#r"gd!! s#r`i`i*gdl]zU!&WDMl]VU!!`is#r!! s#r`i~U*gdDM-TX! 9^#V!##~#ʡU!*gdDMòU! ^#VBK`i ^U! ^#V ^V! ^#V`i]VPY ^V! ^#V^`i!PP͈W`i͈W!9^#VX! 9N#FRͦ]AP!!9^#V!$ ^!!9^#VyX!".V"k|yP!!$ ^!9~#foD]!$ s{«P`i!~#fo#s#r!X!9N#F!9^#V+#|Q`i^! l]P! !.V`i#DM+^!.VW!!!! s#r!# s!$ s!9^#V!& s`i!9^#V!s#r!9^#V!D]#!% s!{K!9^#V!s#r!9^#V!D]tKTQ͈W!X! 9N#F R!.V!!% s!X! 9^#V)))_DM!9^#V!9^#V! ^#V`i^)_^#VXX!DM!9^#Vn&&FE`i`i#DM~CF`i^! l]1F`i^! l]@F!`i#DM+sCF FqI|bF!GpF! Hl]ʶF!G!W!W!AG!W!! .V! CGG`i*!b#"!b+)eas#r`i#DM~G`i^! l]F`i^! l]G!`i#DM+s#     ]a!Yaw#[Y1[1[]a!Yaw#'[!]aw#7[> !Ya~w#F[O]a!aa#[[yt[!Ya4=?[=ʥ[!Ya~w#€[O]a!aa#“[yt[j[]a!aa#®[!Ya]a~6#[> !Ya~w#[[Ya!aa#[=[Y \!Control Area Directory named .X!DM!!9^#V!9s#r?`i#DM`iͦ]t!#9~#fo#s#r+^!9~#fo#s#r+s:!#9^#V!9s#r!9^#V^#V!#9^#V!Ws#r!!@!%9^#V!]X!DM!!9^#V!!9s#rל`i#DM`iͦ]!%9^#V~!%9~#fo#st's not a valid filename. You have modified the entry to read: %02x This is the operating system entry for %x Do you wish to modify it This is the operating system entry you have created: %x Updating Control Area Directory Updating Ops to hard disk Updating Control Area Directory Updating Operating System TablemX!M!!9l]q!9! 9͔!9` !9s#rzŸ!5:!9͡ !9s#r!{]!9s#r!9^#V*6^]`͎\!9s#r!9^#V*0^]͎\!9s#r!>5:d" "X! 9^8! 9^!K5:GsGNG]A,M2! *BUG* bad argument to syslib1! (0x%x)X!A!!9DMl]ʘ!9!9͔!9` !9s#r!!!!9͢K#!9^#V!9zʵ!9r Y[!))\, \}o|g=\=\DM!>))\ =#r+^!9~#fo#s#r+sҜ!ҝ5:! 5:!5:!M5:!DMF`i#DM`iͦ]ѝ!5:! !!9]X!! 9͠ʐ! 9^! l]ʠ!5:`i+DMA! 9^!l]ѝ`i)))!!9~#fo! 9͔A This is an OS file and may require other ferating System TableX!9^!Al]!9s!!9^#V!9^#V]X!9~i!5:!"5:!S5:q!a5:!5:!9^#V+!9^#V͠! 9s#rzʱ!9^#V^!l]ʵ!!9^#Vc! 9!9^#V͔!9~ʎ! 9` ! 9[! ! !9^#V!m5:!9^#Vͫ%!!9!9^#VyX!DM!t5:!9!5:!5:! !!9]X!! 9ͧ͠]ʘ!5:Y|T! 9^!l]ʱ!!9s! 9!9s#r!9^#V^ͧX! 9~#fo#s#r+s{Ɠ! 9ͼI!!9s#rz!9^#V! 9s#r!9͡ !#9s#rz|0 0͋]N!5:!5:õ0 `\*6^!#9s#r!9!9!)9Ȏ!!'9!9yX! 9^#V!|9s#r!@!>9!'9^#V!yX!9!'9ͽ!!9͢K#̓DYZ|\\}{_,]|7]|7g}o]{_,])']}{_,]|g}o7]|g}o|/g}/o|g}o|g}o|ʅ]v]}v]|ʅ]!}…]|v]!}|]}|?>o&zo&|]}|>o&|o&}/o|/g#}}o|gBK^#Vz]#y]###]#x]#~#fo}|>iles in order to work. Enter the names of any support files this OS requires. (Press ESCAPE when all file names have been entered) Support File #%d --> Enter file name or ESCAPE only! X!!"9^#V!!&9^#VyX!DM`i#DM`iͦ]I! T! 9͡ 9!ؚ5:! 5:!>5:!p 6!T!9^#V!5:T!!!9^#V H! 9s#r!l]ʋ!9^#V!5:!ԙ! 9` ə!5:! 5:! 9!5:!! 9s#rԙ!! 9s#r! 9^#V!l]+! 9^#V What is the nam! 9` -!!9!9Ͱ-! 9[F!!9!9yX!DMQ!5:Y!DMxo&'-6K_hpid 0ipi222???????????!! 9]X!J5:!q5:!5:!5:`i)))! 9~#fo^!9s{x!9^!{]x`i)))! 9~#foͿÀ!ܠ5:!5:!! 9͠|! 9^!l]Il](! ! 9s{(!PY])))`i)))!"9~#fo`i#)))!$9~#foe of the file to add to the Control Area Directory? (Use the full CP/M name in form filename.ext) Enter the name of the file entry to modify. (Press RETURN to go back to main menu) --> Do you want to overwrite it That file is not in the Control Are!w E!9!#9ͽ!5:9 !9^#V!ʗ5:!!9 DMJ!DMxf!`!!9^#V!%9yXâ!З5:!!9^#V!9yX!9^#V!!9XYjY!9^#V!9^#V!s#r!,^͇ !9~#!5:0 !9s#r!9^#V!!W!`*6^͵! 9!!5:!9!9Ч!9ʵ! 5:!!9s!9s!!9s!9s!9s!!9^#V!9yX!,^͇ !!9~#ʵ!-5:!`!%9^#V!)9yX0 !!W!`*6^͵! 9!2^͇ qI There is no room in the OS Table for the entry that this new OS GGGGGGGGGGGGGGGIG`_G`_Gf_Gf_Gf_Gf_Gf_Gf_Gl_Gl_r_GKMIN GN Q Q 00000 @@@@@@@@@@@@@@@ yX!!!$9^#V!O]X`i+DM`i)))! 9~#fo! 9͔ Press RETURN to keep current setting. Press SPACE then RETURN to erase entry. Press ESC to stop entering names. Current support file #%d is not used. Enter new name for supa but it does have an OS Table entry. This is an unusual condition. If you proceed, the new entry will replace the old one. Do you wish to proceed You have asked to read in file %s. Can't find the file (%s) to be added. There is no file in the 2^͇ *SERIOUS BUG* in modify, can't find file in sd any more This is the entry you have chosen to modify: %02x What is the new file name? (Press RETURN to keep current name of %s) (Press ESC to go back to Main Menu) --> 8 characters max! Thawould require. The new file will fit exactly on top of the old one. Erasing the old version of the file. WARNING!!! DO NOT TOUCH THE COMPUTER UNTIL THE ERASE IS COMPLETED. DO NOT INTERRUPT THIS ERASE!!! Erasing..... Erase is complete. Copying file % @@@@@@@ @@@@@ @@@@ $     port file #%d --> X!9^#V!9^#V!9^#VLX!"k!9!QY|Y!9^#VͰ!9jYDY[{-!9XYX!"k! 9!QY|Y!9^#VͰ!9jYDY["!9!QY|Y!9^#VͰ!9jYDY["!!DM|c!5:!#PYͦ]c)!9^#V!`\*6^!9s#r!9^#VͿ! 5:!9! 9֗DM|ώ!5:!Ñ#PYͦ]ώ)!9^#V)^^#V)! 9^#V!F5:Ê!c5:!e !5:! 9Ϳ!5:!9^#V! ^!9~#fo+D]#! 9s*ì\+!9s#r! 9^#V!9~#foͧ]!5:! 9^! 9^#V!5:!9^#V!5:!! There is no room in the Control Area for this file. If written, the file would end at track %x, sector %x. (The Contros %s Entry Point Offset (0-FFFF)? (Press RETURN to keep current value of %x) (Press ESC to go back to main menu) --> Invalid entryX!9!9^#V!>jY**^|ȧ!9XYYȧ!"*^!9XY!9XYX!9^#V! ^#V! 9s#r!9^#V! ^! 9s!9XY|Y!9^#VͰ!9DY[%-!9XYX!w5:*kl]R!5:v*kl]i!5:v*k!5: *BUG* bad fd to lseekinvalid param to lseekerrno = %d from lseekX!DMޢ`i#DM! 9~#fo#s#r`iͦ]! 9^#V^! {]ϑ5:! 5:!C5:!9^#Vg!9^#VД!9^#V!,^͇ !2^͇ !S5: This is the ERASE option. WARNING!!! ERASING IS A DANGEROUS PROCESS. IF INTERRUPTED IT COULD CORRUPT YOUR ENTIRE CONTROL AREA DIRECTORY. Do you want to continue Havel Area ends at track %x, sector 80.)`i"n!j s# y/"p"r"l!9"j*n"l]d:mwÄl]ʋ}:mw *l!9s#r*nDM*p*r!9^#V*jÄX! 9^#V))) _~ح!"kQY! 9^#V))) _^#VBK!9^#VÉ!& ^T5:!!9s#r!!9~#fo#s#r!9^#V! ^#V! 9^#Vͦ]P!!9^#V!9^+!9^#V!>%! 9! 9n#s!ͧ]ʽ*ì\! 9~#fo#s#rͧ]ʴ! 9^#V!f5:!!! 9s!9^#V#! !5:!9^#V! ^#V! 9^#V#ͦ]M!9^#V! 9^#V^!_%X!ʢ4`i#DM! 9~#fo#s#r`iͦ][! 9^#V^! {]X! !.: X!DM! 9^#VÖ`i#DM! 9~#fo#s#r#! 9^#V^ͧXu}ѣ! 9^#V^!.{]ѣ`iͦ]ѣ{! 9~#fo#s#r! 9^#V~! 9^#V^!. you made a backup of your Control Area (Partition 0) Enter the name of the file to be erased (or press ESC to go back to main menu) --> Invalid input!That file is not in System Directory. You have asked to ERASE this file: This file is NEEDED by toW!`inT]s!.V!`inD]sTQ͈W!9!! ^#Vc\DY~Z|Y!$ ^m\͊Y Z͕YXY ZjYÜ!"kQY]x;{!!# s!9XYDY\׮!!! s#r!$ s!"kQY!9XY|\D]!$ s!9XYDY͢!9^#V!!9^#V!9^#V͢K{]>*k!5:!!9~#fo#s#r! Sectors copied: *YIKES* attempt to increment to track 0x%x in add%c%02x *BUG* read != 128, errno = %dX!9~#ة!9^#V !9s#r!͋]!5:!K5:!{]ԣ! 9~#fo#s#r+^#+s{s!DML`i#DM! 9~#fo#s#r#! 9^#V^ͧXu}s`iͦ]s1!uX!9~#ʘ!U!9s#rã!]!9s#r!"(^!9^#V!a5:!9~#ߤ!9^#V!XY|Y!5:!5:!9~#!9^#V!hese OS's: This file is NEEDED to boot these products: PRODUCT #%d (%s) ARE YOU SURE YOU WANT TO ERASE IT Removing file from System Directory. The ERASE procedure will take a few seconds. WARNING!!! DO NOT TOUCH THE COMZ|\!! s#r!9XYX! 9^#V))) _~5!"k!! 9^#V))) _^#VBK!9^#V!! s#r!!# s!$ s!!9^#V!\*0^ There is no room in the Control Area Directory for the new entry that this file would require.X!9^#V!{]! 9s#r!9^#V!9^#V! s#r!9~#!9^#V! ^#V!9^#V! s#r!9^#V! ^!9^#V! s !9s#r!9^#V!!9^#V!XY|YͅjYV!9^#V!!!>jYYV**^|V!"*^!"(^**^|b!*(^|r!5:*(^|£!9^#V!5:!9~#ʭ!9^#V!^#V!5:!K5:!9~#!!9^#V!^#Vm\|Yͅ|\!9^#V!s#r-!!PUTER UNTIL THE ERASE IS COMPLETED. DO NOT INTERRUPT THIS ERASE!!! Erasing...... Erase is complete.X +!9s#r!9^#V!\*0^!"9~#fol]ʛ!"9^#V! ^#V! 9s#r!"9^#V! ^!9s#r!"9^#V!"^#V!9s#r!"9^#V!$^! 9s#r +!9s#r!F X!Q5:!5:!5:! ;! |\!9^#V!s#rz-**^|-!"*^!"(^**^|9!*(^|I!u5:*(^|z!the newits What is %s Memory Load Address (0-FFFFFFFF)? (Press RETURN to keep current value of %lx) (Press ESC to go back to main menu) --> Invalid entry What i%     9^#V!\*0^!9s#r!9^#V! ^#V!9~#fo]!9s#r!9^#V! ^#V!9^#V! ^! 9~#fo]!9s#r!9^#V!]!9~#fo!9s#r!9^#V!ͧ]Δ!9^#V!͋]ʶ!!9s#rē!9^#V!9s#r!9^#V! 9!9^#V+!9^#V!>%! 9!9^#V! 9ke this:Loader ProgramLogin ProgramOS Menu Program Would you like to see the list of possible product types Enter Product Type Number you want to add or modify. (Press RETURN to go back to the Product Menu) --> The Product Type Table is full -- youMenu ------- ----------- ------------- -------X!9^#V^!5:!! 9s#r!9^#V#!9s#r! 9~#fo#s#r! 9^#V!ͦ]!5:!! 9s#rô! 9~#fo#s#r! 9^#V!ͦ]!9~#fo#s#r+^!5:åp %x %c A - ADD/MODIFY Add or modify a Product Table entry. E - ERASE Erase an entry from the Product Table. L - LIST List the Product Table. T - TYPES Display Product Types for DMS equipment. Enter your choice (Press RETURN#s#r!9^#V! 9~#foͦ]ʵ!!9s#r5!9~#fo#s#r!9^#V!ͦ]ʲ!!9^#V)))!9^#V!`\!9~#fo!9^#V͟W¯!9^#V! 9~#fo#s#r+)!9~#fos#rò&!9^#V`i"P!L s# y˙"R"T"N!9"L*nl]:mw! 9^#V+!9^#V!>%! 9!9^#V! 9~#fos#r!9^#V!9~#fos#r! 9^#V!ͧ]}!! 9~#fo]s#r!9~#fo#s#r!9^#V!ͧ]ʲ!!9~#fo]s#r! 9~#fo#s#r!9^#V!9~#fo]s#rÈX!9^#V*0^]͎\! 9s#r +! 9s# cannot make any more entries. This is an unusual condition and may indiindicate a corrupted Control Area or a program bug. You have asked to add an entry for product type %d (%s). Is this correct Program names entered here should be eight characterX!a!9s#r!!9s#r!ԗ!9s#r!! 9s#r!! 9s#r!#! 9s#r!3 P!m5:!5:!!>|\!39s#r**^|ʁ!39^#V!ͧ]ʡ!39^#V!ͦ]§!ê!!9s{¸!9~P!39^#VX!9s#r!9^#V!l]!29s!29~`!9s#r! to go back to Main Menu) --> X!5:!Ə5:!5:! 5: !G5:!5:!5:!א5: !5:!5:!5: !*5:!=5:͑ Product Type codes for various DMS computers (Press any key to stop or restart listing) Prod. Typ l]':mw *N!9s#r*PDM*R*T!9^#V*L r! 9^#V!ͦ]#! 9^#V! 9~#foͧ]5! 9^#V!˕5:! 9^#V!9s#rg!9~#fo#s#r!9~#fos#r!9^#V! 9~#foͦ]ʩ!!9^#V!9^#V!yX!9^#VF!!!9^#V!\*0^]X **BUG** bad SD entry # %d in sd_delete()X!s or less. Press ESC to return to the Product Menu. Press RETURN to keep current choice.X! 9^#V!5:ͷ!9^#V6! %s Is this correctX!9^#V!9^#V!9^#V5!9~#!!9^#V!9^#VyX!!5:ä!9^(͋],!ט5:!5:!G5:͑ !!9s]!39^#V)^^#V!59^#V!}5:! !9s{!9^#V!9^#VX!9s!9~†!39^#V!9s!ș5:!5:!29~[!39^#V!9!!9^#V͞!9/!39^#V!$9!!9^#V͞!9/!39^#Ve Models ---------- ---------------------------------------------- 1 DMS-3, 3/101, 3/102, 3/103, 3/4004, 3/4008, 3/501, 3/A25, 3/B, 3/F (Fox), 15, 5080 2 DMS-4 3 1280 4 3/C 9~#! 9^#V*6^]`͎\DM0 +`iͦ]<`iͧ]G!5:`in#+! 9~#fo`s#rͦ]ʜ!`!9^#V!9^#V!`yXO!!``\*6^]X **BUG** bad OS entry # %d in os_delete()X!! 9s#r!!#V^!l]!!Enter a file name (or ESC) --> X!! 9s#r!! 9s#r!9^#V!9^#V!5:! !!9]X!!9͠!9s#rz!! 9^!l]ʿ!!9^#Vs!!9^#V!9͔!9^#V` l!! 9s#r!5:!!9s#!,9!!9^#V͞!9/!9!9^#VX5!8!!9s!9^#V!\*<^!9s#r !25:!39^#V!9!9^#V#!9^#V͞!9!39^#V!$9!9^#V! !9^#V͞!9!39^#V!,9!9^#V!!9^#V͞!9!9!9^#VX 5 86, 5086 6 5016 7 816 8 PC Adapter X*<^! 9s#r!9s#r!! 9s#rê! 9~#fo#s#r+! 9~#fos#r! 9^#V!9~#foͦ]ۑ! 9^#V^!9~#fo{]ۑÂ! 9^#V!9~#foͦ]! 9^#V!9s#r!9^#V*0^{]ʩ!9~#fos#r!9^#V! ^#V! 9s#r!9^#V! ^#V!9^#V! ^!9s#r!9^#V!ͧ]ʗ!!9~#fo]s#r! 9~#fo#s#r_!9~#fos#r! 9^#V!9^#V! s#r!9^#V!9^#V! sX!!9s#r*<^! 9s#r!DMr!9~#fo#s#r!9^#V!ͦ]\!9^#V!9~#fo^! {]\!9^#V!9~#fo^!Ĝ5:!ǜ5:!5:! 9~#F!9^#V Enter name of the %s for product %x --> There is no file named %c in the Control Area Directory. I cannot accept it in!!!9s!9~`!!9^#V!9yX!29~X!9^#V#!!!*<^͵! 9!8^͇ The Product Table entry which you have created looks like this:You have asked to modify this Product Table entry:The modified Product Table entry looks liX!5:ͷ!9s#r*<^! 9s#r!! 9s#rZ! 9~#fo#s#r+! 9~#fos#r! 9^#V~ʎ! 9^#V!9~#foͦ]ʎ! 9^#V6 2!5:͑ PRODUCT TYPE TABLE X!Β5:!5: Product Boot Loader Login Program OS . Xi!9s#r**^|)!g5:!9^#VLcccc]A4E:L@TFc X!"*^!5:!5:!75:!r5:!5:!ݎ5:!! 9͠!9s#r!ͧ]u!9~#ԍ!׍!"*^! 9^ͧX PRODUCT TABLE MENU`i#DM! 9~#fos#r`iͦ]ʶ! 9^#V#! 9s#r!W#!! 9~#fos#rͦ]ʳ!! 9^#V!9^#V͟W°! 9^#V^! 9~#fo#s#r+)!9~#fos#ró=!9^#VX!!9s#r*6^!9s#r0 ! 9s#r!!9s#r!9~#fo&     to the Product Table.X!<5:!l5:!!>|\! 9s**^|H! 9^X! 9s#rzj!5:!ٞ5:ͷ! 9^#V6! 9^!5:! 9^)^^#V!>5:! 9^ܟɝ!e!9s#rԝ!i!9s#r!9^#V!p5:! ! 9s#r! X!U5:!5:!5:!! 9͠!9^ͧXOl]NtQ͑ To list the OPERATING SYSTEM TABLE type 'O'. Any other key starts list of Control Area Directory. (Any key stops or restarts listing) --> X!P5: *0^DM!tries in the OS table refer to non-existent files: OS Filename Missing Files ----------- -------------X!9^#V!͕\l]ʑ!5:!9^#V!l]ʹ! 9^#V!Ϳ!5:!9^#V!l]ѐ!5:!9^#VͿ!5: X!!9^#V]X! 9^#V!!!*<^͵! 9!8^͇ Enter Product Type Number you want to delete. (Press RETURN to go back to the Product Menu) --> There is no entry for that product type in the table. You have asked to delete this produ#+`iDM`i~O`i^!{]Oͦ]O!o5:ͫ  CONTROL AREA DIRECTORY %x X!؎5:9 !*6^DMÛ`i`DM! ^!9s{׎!9^!{]׎#+!5: Ó OPERATING SYSTEM TABLE %x !!9s#r*<^!9s#r!9s#r!! 9s#rM! 9~#fo#s#r!9~#fos#r! 9^#V!9~#foͦ]Y!!9s#r!9^#V#! 9s#r!!9s#rî!9~#fo#s#r!! 9~#fos#r!9^#V!ͦ]V! 9^#V` S!9~#fo#s#r!9^!pl]S!9^#V!l]!ct type: If you delete this entry, machines of Product Type %d (i.e. %s) will not be able to log in.AREare no Currently there %s machines of that type in the Machine Table. ARE YOU SURE YOU WANT TO DELETE THIS ENTRYX! 9"2!. ! 9! 9s#r`i"! s# y """!9"*nl]@:mw`l]gY:mw *!9s#r*DM**!9^#V*`b5:!5:!5:!5: ! 9^#V!9~#fo#s#r! 9^#V!9^#V!9 Ì,!9^#V These Product Table entries refer to non-existent files: Product Missing File Needed For ------- ------------ - X!! 9s#r!!9s#r!f|! 9~#fos#r!f! 9~#fos#r! 9~#ʟ! 9^#V!ٍ5:!5:͑ !p|!!5: !p!#5:ç!%5:!9s#r!9~#͍!9^#V!O5:͑ !y5: FOUND (%d) ERRORS IN THE TABLES. A!!9s#r3! 9~#fo s#r!9~#fo#s#r+!9^#V!ͦ]ʜ!9^! 9^#V!^! 9sl]i!! 9^!ͦ]œ! 9^!l]œ! 9^!ͧ]œ !`i"8!4 s# y­":"<"6!9"4*nl]:mwl] :mw( `i"2!.s# y"4"6"0!9".*nl]I:mw͕il]pb:mw͘*0!9s#r*2DM*4*6!9^#V*.iX1f«!"**i^!0ͦ]͍!#5:!"*:Po&{]!Y5:!!9^#V!͋]!9^---------X!9^#V!l]K! 9^#V^)^^#V!9^#V^!5:S!5:!9^#VͿ!9^#VÖ!Ó5:é!ۓ5:é!5:é!5:é]uj %-2d - %-22.19s No good reason (*BUG*) Boot Loader Login Program OS Meny key stops/restarts ERROR REPORT. THERE ARE NO ENTRY ERRORS IN THE TABLES. Found (%d) files that may not be needed. X!!9s#r*6^!9s#r0 !9s#r!! 9s#rҎ! 9~#fo#s#r!9~#fo`s#r! 9^#V!9~#foͦ]!!9s#r!9^#V! *6!9s#r*8DM*:*%! 9!",!X1!!8!͟Wˆ!!SB0000X!9^#V^!D]! 9s!9^#V^!D]!9s!!9^#VnD]s!!9^#VnD]s!9^!T* * ;********************************************* jmp INIT ;Enter from BOOT ROM or LOADER jmp WBOOT ;Arrive here from BDOS call 0 jmp CONST ;return console keyboard status jmp CONIN ;return console keelected USARTS on BLC8538 ;********************************************* ;* * ;* Intel iSBC 204 Disk Controller Ports * ;* * ;********************************]L]!9^#VnT]s! 9^!T]L]!9^#VnT]sX!!ȑ!9^#V͟Wn!!ϑ!9^#V͟Wo! 9^#V!!9^#V͓! 9^#V!!9^#V#͓! 9^#V###!9^#V##͓! 9^#V //////X!9^#V!ͧ]!9^#V!͌]!yboard char jmp CONOUT ;write char to console device jmp LISTOUT ;write character to list device jmp PUNCH ;write character to punch device jmp READER ;return char from reader device jmp HOME ;move to trk 00 on cur sel drive jmp SELDSK ;************* base204 equ 0a0h ;SBC204 assigned address fdc_com equ base204+0 ;8271 FDC out command fdc_stat equ base204+0 ;8271 in status fdc_parm equ base204+1 ;8271 out parameter fdc_rslt equ base204+1 ;8271 in result fdc_rst equ base204+2 !9~#fo+s#r!9^#V!͕\)!9^#V!̀\!9^#V! \D^]D]X!! 9!9^#VyX!!9s!9!96!!9s#râ!9~#fo#s#r!9^#V! ͦ]!! 9!9^#V! \>͟Wߒ!9^#VÓ!X! 9^#V~M! 9select disk for next rd/write jmp SETTRK ;set track for next rd/write jmp SETSEC ;set sector for next rd/write jmp SETDMA ;set offset for user buff (DMA) jmp READ ;read a 128 byte sector jmp WRITE ;write a 128 byte sector jmp LISTST ;re;8271 out reset dmac_adr equ base204+4 ;8257 DMA base address out dmac_cont equ base204+5 ;8257 out control dmac_scan equ base204+6 ;8257 out scan control dmac_sadr equ base204+7 ;8257 out scan address dmac_mode equ base204+8 ;8257 out mode dmac_stat title 'Track Buffered BIOS - SBC204' ; 5 Jan 82 -jrp ; Copyright (C) 1980,1981 ; Digital Research, Inc. ; Box 579, Pacific Grove ; California, 93950 ; ; (Permission is hereby granted to use ; or abstract the following program in ; the imp^#V^!a͋];! 9^#V^!z͌];! 9^#V^!!9^#Vs! 9~#fo#s#rX!Δ! !9^#V!9^#V]X!9^#V! 9s#r!9^#V! 9s#r! 9~#m!!.VD]! 9s{½Ü! 9^K!!\!!! 9^#V!9~#fo{]! !turn list status jmp SECTRAN ;xlate logical->physical sector jmp SETDMAB ;set seg base for buff (DMA) jmp GETSEGT ;return offset of Mem Desc Table jmp GETIOBF ;return I/O map byte (IOBYTE) jmp SETIOBF ;set I/O map byte (IOBYTE) ;pr equ base204+8 ;8257 in status fdc_sel equ base204+9 ;FDC select port (not used) fdc_segment equ base204+10 ;segment address register reset_204 equ base204+15 ;reset entire interface max_retries equ 10 ;max retries on disk i/o ;before perm elementation of CP/M, MP/M or ; CP/NET for the 8086 or 8088 Micro- ; processor) true equ -1 false equ not true ; Track buffering equates... host_sectsiz equ 128 host_spt equ 26 host_fsn equ 1 bdos_int equ 224 bios_code equ 2500h ccp_o9~#fo+s#rs! 9~#fo#s#rj! 9^!9~#fo#s#r+s! 9~#fo+s#rj]ד ȓ ȓԓ Ò!!.VD]!9s{Žm!9^! l]®!9^! l]ʺ!!!9^!l]\mEnter Password: $ $^C$ $X! 9^#V! (     int signon message and initialize hardware INIT: mov ax,cs ;we entered with a JMPF so use mov ds,ax ; CS: as the initial value of DS:, mov es,ax ; and ES: mov ss,ax ; use local stack during initialization mov sp,offset stkbase cld ;set forwarmov bx,ds ! mov es,bx ; destination is our data segment mov di,offset track_buffer ; destination is in track buffer add di,ax ; plus appropriate offset lds si,dma_longword ; source is users DMA address rep movsw ; move that sector pop es  the track buffer home1: mov cx,0 ; home is a settrk zero settrk: mov cpm_track,cx ; save track number for next operation ret setsec: mov cpm_sec,cx ; save sector number for next operation ret setdma: mov dma_offset,cx ; save DM case uconecho: call CONIN ;get a console character push ax mov cl,al ;save and call CONOUT pop ax ;echo to console cmp al,'a' jb uret ;less than 'a' is ok cmp al,'z' ja uret ;greater than 'z' is ok sub al,'a'-'A' ;else shift to c;* at ports D8/DA * ;* * ;********************************************* CONST: ;console status in al,csts and al,2 jz const_ret or al,255 ;return non-zero if RDA const_ret:d direction push ds ;save the DS register mov ax,0 mov ds,ax mov es,ax ;set ES and DS to zero ;setup interrupt 0 to address trap routine mov int0_offset,offset int_trap mov int0_segment,CS mov di,4 mov si,0 ;then propagate mov cx,510 ; restore the extra segment pop ds ; and the data segment registers pop ax ; recover buffer offset mov cx,host_sectsiz ; setup to divide by host sector size sub dx,dx ; extend ax to 32 bits div cx ; find out which host sector we changed A offset address ret setdmab: mov dma_segment,cx ; save DMA segment address ret sectran: mov bx,cx ; Put logical sector into dest. reg. test dx,dx ; see if table address is zero jz sectran_exit ; yeah, logical = physical add bx,dx ; eaps uret: ret ; utility subroutine to print messages pmsg: mov al,[BX] ;get next char from message test al,al jz return ;if zero return mov CL,AL call CONOUT ;print it inc BX jmps pmsg ;next character and loop ;************ ret ;Receiver Data Available CONIN: ;console input call const jz CONIN ;wait for RDA in al,cdata and al,7fh ;read data and remove parity bit ret CONOUT: ;console output in al,csts and al,1 ;get console status jz CONOUT ;wait ;trap vector to rep movs ax,ax ;all 256 interrupts ;BDOS offset to proper interrupt mov bdos_offset,bdos_ofst pop ds ;restore the DS register ; Initialize the BLC 8538 printer port mov al,0FFh out blc_reset,al ;reset all usarts on 8538 mo mov bx,ax ; put into index [BX] mov sec_flags[BX],1 ; set the update flag for that sector mov wr_flag,1 ; also set the dirty buffer flag pop cx ; recover BDOS write code cmp cl,1 ; is this a directory update ? jne write_return ; no, welse, we need to fetch the mov bl,[BX] ; actual sector number from the table mov bh,0 ; zero high byte for good luck sectran_exit: ret GETSEGT: ;return address of physical memory table mov bx,offset seg_table ret read: call trac********************************* ;* * ;* Disk Input/Output Routines * ;* * ;********************************************* SELDSK: ;select disk givenfor TBE mov al,cl out cdata,al ;Transmitter Buffer Empty ret ;then return data LISTOUT: ;list device output call LISTST jz LISTOUT ;wait for printer not busy mov al,cl out ldata,al ;send char to TI 810 ret LISTST: ;poll list stav al,4Eh out ldata+2,al ;set usart 0 in async 8 bit mode mov al,3Eh out ldata+2,al ;set usart 0 to 9600 baud mov al,37h out ldata+3,al ;enable Tx/Rx, and set up RTS,DTR mov bx,offset signon call pmsg ;print signon message call clear_flags may leave dirty records ; in the buffer call flush_buffer ; we have a directory write, need to ; flush the buffer to insure the ; disks integrity write_return: sub ax,ax ; never return BAD SECTOR code ret track_setup: ; k_setup push es ; save the extra segment register mov si,offset track_buffer ; source segment is systems DS: add si,ax ; gives the offset into the buffer les di,dma_longword ; point ES:DI at the users sector rep movsw ; doit pop es ; r by register CL mov cpm_disk,cl ; save the selected drive mov bx,0000h cmp cl,2 ;this BIOS only supports 2 disks jnb return ;return w/ 0000 in BX if bad drive ;now, we need disk parameter address mov ch,0 mov bx,cx ;BX = word(CL) mov cltus in al,lsts and al,81h ;look at both TxRDY and DTR cmp al,81h jnz zero_ret ;either false, printer is busy or al,255 ;both true, LPT is ready ret PUNCH: ;not implemented in this configuration READER: mov al,1ah ret ;return EOF for  ; initialize track buffering mov cl,0 ;default to dr A: on coldstart jmp ccp ;jump to cold start entry of CCP WBOOT: jmp ccp+6 ;direct entry to CCP at command level int_trap: cli ;block interrupts mov ax,cs mov ds,ax ;get our data secommon code for setting up reads and writes mov al,cpm_disk ; see if selected disk is cmp al,cur_disk ; the same as last time jne wrong_track ; no, we have wrong track mov ax,cpm_track ; see if desired track is same as cmp ax,cur_track ;estore the extra segment sub ax,ax ; make a zero return code ret write: push cx ; save the write mode from the BDOS call track_setup push ax ; save buffer offset push ds ; save the data segment push es ; save the extra segment ,4 shl bx,cl ;multiply drive code * 16 add bx,offset dp_base ;create offset from Disk Parameter Base return: ret home: test wr_flag,1 ! jnz home1 ; if the buffer is clean, mov cur_disk,-1 ; insure we read the directory by invalidating ; now GETIOBF: mov al,0 ;TTY: for consistency ret ;IOBYTE not implemented SETIOBF: ret ;iobyte not implemented zero_ret: and al,0 ret ;return zero in AL and flags ; Routine to get and echo a console character ; and shift it to uppergment mov bx,offset int_trp call pmsg hlt ;hardstop ;********************************************* ;* * ;* CP/M Character I/O Interface Routines * ;* Console is Usart (i8251a) on iSBC 86/12 * )      the track in the buffer je correct_track ; same drive and track, we don't need to read ; Desired operation is on a different track then is in our buffer, ; So it will be nessecary to read in the desired track. First, we ; must check to see if any ;* * ;* The i8271 requires a read status command * ;* to reset a drive-not-ready after the * ;* drive becomes ready * ;* * ;**************or and al,1eh jz exec_exit ;no error, then exit ;some type of error occurred . . . cmp al,10h je dr_nrdy ;was it a not ready drive ? ;no, dr_rdy: ; then we just retry read or write push ax ; save error code call restore ; after physicB test b_first_flag,-1 ! jz not_first_b ; and first reference to B call restore ; then restore drive B mov b_first_flag,0 ; and clear flag not_first_b: mov bx,offset io_com ;point to command string mov ax,cur_sec ; put sector in mov sect,ost_fsn endif mul bx ; make track buffer offset add ax,offset track_buffer ; make direct pointer mov cur_dma_adr,ax ; save for write routine call sector_write pop cx pop bx not_updated: inc bx loop next_sect no_flush: mov wr_flag, sectors of the current buffer are dirty. wrong_track: call flush_buffer ; write any old records, if nessecary mov ax,cpm_track ; get desired track number mov cur_track,ax ; make in new track mov al,cpm_disk ; get desired disk number mov******************************* test_ready: mov dh, 40h ;proper mask if dr 1 test sel_mask,80h jnz nrdy2 mov dh, 04h ;mask for dr 0 status bit nrdy2: mov bx,offset rds_com call send_com dr_poll: in al,fdc_stat ;get status word testally homing this disk pop ax ; recover error code dec rtry_cnt jnz retry ; up to 10 times ; retries do not recover from the ; hard error mov ah,0 mov bx,ax ;make error code 16 bits mov bx,errtbl[BX] call pmsg ;print appropriate messagal ; iopb as 8 bits mov ax,cur_track ; same with mov trk,al ; track . . ; fall into execute and return execute: ;execute command string. ;[BX] points to length, ; followed by Command byte, ; followed by length-1 parameter bytes mov0 ; clear the dirty buffer flag ret clear_flags: ; Clear all variables associated with the track buffer, ; so next operation will have to read a track. ; This is involves clearing all write flags and setting ; the old drive code to the inv cur_disk,al ; make it current drive mov cur_dma_adr,offset track_buffer ; point dma offset at track buffer mov cur_sec,host_fsn ; starting from first sector call track_read ; load the track correct_track: mov ax,cpm_sec ; get the cp/m  al,80h jnz dr_poll ;wait for not command busy in al,fdc_rslt ;get "special result" test al,dh ;look at bit for this drive ret ;return status of ready restore: ;move selected disk to home position (Track 0) mov bx,offset hom_com call exee in al,cdata ;flush usart receiver buffer call uconecho ;read upper case console character cmp al,'C' je wboot_l ;cancel cmp al,'R' je outer_retry ;retry 10 more times cmp al,'I' je z_ret ;ignore error or al,255 ;set code for permanent e last_com,BX ;save command address for retries outer_retry: ;allow some retrying mov rtry_cnt,max_retries retry: mov BX,last_com call send_com ;transmit command to i8271 ; check status poll mov BX,last_com mov al,1[bx] ;get command op codealid -1. push es ; save extra segment mov cur_disk,-1 ; insure initial pre-read sub ax,ax ; make a zero mov wr_flag,al ; clear the dirty buffer flag mov di,offset sec_flags ; point to the update flag list mov bx,ds ! mov es,bx ; ESsector number if (host_fsn ne 0) sub ax,host_fsn ; correct if we start with sector one endif mov cl,7 ; log2(128) shl ax,cl ; sector times 128 gives offset mov cx,64 ! cld ; move 64 words forward ret flush_buffer: test wr_flcute jz restore_exit ;home drive and return if OK mov bx,offset bad_hom ;else print call pmsg ;"Home Error" jmps restore ;and retry restore_exit: ret ;********************************************* ;* rror exec_exit: ret dr_nrdy: ;here to wait for drive ready call test_ready jnz retry ;if it's ready now we are done call test_ready jnz retry ;if not ready twice in row, mov bx,offset nrdymsg call pmsg ;"Drive Not Ready" nrdy01: call  mov cx,0800h ;mask if it will be "int req" cmp al,2ch jb exec_poll ;ok if it is an interrupt type mov cx,8080h ;else we use "not command busy" and al,0fh cmp al,0ch ;unless there isn't mov al,0 ja exec_exit ; any result ;poll for bits <- DS mov cx,host_spt ! cld ; set length and direction rep stosb ; zero the sector update flags mov cur_dma_seg,ds ; get our segment address pop es ; recover extra segment ret track_READ: mov io_com,4 ; read track takes 4 byte cag,1 ; see if we have anything to write jz no_flush ; no, skip scanning for dirty sectors mov bx,host_fsn ; start at first host sector mov cx,host_spt ; for host_spt sectors... next_sect: test sec_flags-host_fsn[BX],1 ; see if this sector has  * ;* Send_com sends a command and parameters * ;* to the i8271: BX addresses parameters. * ;* The DMA controller is also initialized * ;* if this is a read or write * ;* * ;**********test_ready jz nrdy01 ;now loop until drive ready jmps retry ;then go retry without decrement zret: and al,0 ret ;return with no error code wboot_l: ;can't make it w/ a short leap jmp WBOOT ;*********************************************  in CH, exec_poll: ; toggled with bits in CL in al,fdc_stat ;read status and al,ch xor al,cl ; isolate what we want to poll jz exec_poll ;and loop until it is done ;Operation complete, in al,fdc_rslt ; see if result code indicates errommand mov io_com+1,13h ; special read track command jmps r_w_common sector_WRITE: mov io_com,3 ; write sector takes 3 byte command mov io_com+1,0ah ; basic write sector command r_w_common: cmp cur_disk,1 ! jne not_first_b ; see if drive been changed jz not_updated ; no, leave it alone mov sec_flags-host_fsn[BX],0 ; zero the flag for next time push bx ; save the registers push cx mov cur_sec,bx ; save host sector number mov ax,host_sectsiz if (host_fsn ne 0) sub bx,h*     *********************************** send_com: in al,fdc_stat test al,80h ;insure command not busy jnz send_com ;loop until ready ;see if we have to initialize for a DMA operation mov al,1[bx] ;get command byte cmp al,13h jne write_maybs1 ;Check Vector sec_flags rb host_spt track_buffer rb host_spt*host_sectsiz loc_stk rw 32 ;local stack for initialization stkbase equ offset $ lastoff equ offset $ tpa_seg equ ((lastoff+07FFh)/0400h)*40h ; round off to 1K boundarypb1 ;Dir Buff, Parm Block dw csv1,alv1 ;Check, Alloc Vectors ; DISKDEF 0,1,26,6,1024,243,64,64,2 ; ; 1944: 128 Byte Record Capacity ; 243: Kilobyte Drive Capacity ; 64: 32 Byte Directory Entries ; 64: Checked Directory Entries ; ;disk error retry counter last_com dw 0 ;address of last command string cur_dma_adr dw 0 ;dma offset stored here cur_dma_seg dw 0 ;dma segment stored here sel_mask db 40h ;select mask, 40h or 80h ; Various command strings for i8271 io_com dbameter jmps parm_loop ;go see if there are more parameters parm_exit: ret ;********************************************* ;* * ;* Data Areas * ;* e ;if not a read it could be write mov cl,40h jmps init_dma ;is a read command, go set DMA write_maybe: cmp al,0ah jne dma_exit ;leave DMA alone if not read or write mov cl,80h ;we have write, not read init_dma: ;we have a read or write oper tpa_len equ 0800h - tpa_seg db 0 ;fill last address for GENCMD ;********************************************* ;* * ;* Dummy Data Section for Interrupt Vectors * ;*  128: Records / Extent ; 8: Records / Block ; 26: Sectors / Track ; 2: Reserved Tracks ; 6: Sector Skew Factor ; dpb0 equ offset $ ;Disk Parameter Block dw 26 ;Sectors Per Track db 3 ;Block Shift db 7 ;Block Mask db 0 ;Ex 3 ;length (changed to 4 to read a track) rd_wr db 0 ;read/write function code trk db 0 ;track # sect db 0 ;sector # sec_len db 26 ;transfer 26 sectors on a track read hom_com db 2,29h,0 ;home drive command rds_com db 1,2ch ;read status command  * ;********************************************* data_offset equ offset $ dseg org data_offset ;contiguous with code segment signon db cr,lf,cr,lf db ' CP/M-86, 1 Feb 82 ',cr,lf,0 bad_hom db cr,lf,'Home Error',cr,lf,0 intation, setup DMA controller ; (CL contains proper direction bit) mov al,04h out dmac_mode,al ;enable dmac mov al,00 out dmac_cont,al ;send first byte to control port mov al,cl out dmac_cont,al ;load direction register mov ax,cur_dma_ * ;********************************************* dseg 0 ;absolute low memory org 0 ;(interrupt vectors) int0_offset rw 1 int0_segment rw 1 ; pad to system call vector org bdos_int * 4 bdos_offset rw 1 bdos_segment rw 1 END tnt Mask dw 242 ;Disk Size - 1 dw 63 ;Directory Max db 192 ;Alloc0 db 0 ;Alloc1 dw 16 ;Check Size dw 2 ;Offset xlt0 equ offset $ ;Translate Table db 1,7,13,19 db 25,5,11,17 db 23,3,9,15 db 21,2,8,14 db 20,26,6,12 db 18,24,4,1; Track buffering variables cpm_disk rb 1 cpm_track rw 1 cpm_sec rw 1 cur_disk rb 1 cur_track rw 1 cur_sec rw 1 dma_offset rw 1 dma_segment rw 1 dma_longword equ dword ptr dma_offset bdos_wr_code rb 1 wr_flag rb 1 ; System Memory S_trp db cr,lf,'Interrupt Trap Halt',cr,lf,0 errtbl dw er0,er1,er2,er3 dw er4,er5,er6,er7 dw er8,er9,erA,erB dw erC,erD,erE,erF er0 db cr,lf,'Error Code 0 :',0 er1 db cr,lf,'Error Code 1 :',0 er2 db cr,lf,'Error Code 2 :',0 er3 db cradr out dmac_adr,al ;send low byte of DMA mov al,ah out dmac_adr,al ;send high byte mov ax,cur_dma_seg out fdc_segment,al ;send low byte of segment address mov al,ah out fdc_segment,al ;then high segment address dma_exit: mov cl,[BX]; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * CP/M-86 Accelerator -- Track Buffering Routines * ; * * ; * This module, when installed in a CBIOS, causes * ; * CP/M-86 to perform disk input output on a * ; * tra0 db 16,22 als0 equ (243+7)/8 ;Allocation Vector Size css0 equ 16 ;Check Vector Size ; DISKDEF 1,0 ; ; Disk 1 is the same as Disk 0 ; dpb1 equ dpb0 ;Equivalent Parameters als1 equ als0 ;Same Allocation Vector Size css1 equ css0 ;Sameegment Table segtable db 2 ;2 segments dw tpa_seg ;1st seg starts after BIOS dw tpa_len ;and extends to 08000 dw 1000h ;second is 10000 - dw 1000h ;1FFFF (64k) ; include singles.lib ;read in disk definitions ; DISKS 2 dpbase equ $ ,lf,'Error Code 3 :',0 er4 db cr,lf,'Clock Error :',0 er5 db cr,lf,'Late DMA :',0 er6 db cr,lf,'ID CRC Error :',0 er7 db cr,lf,'Data CRC Error :',0 er8 db cr,lf,'Drive Not Ready :',0 er9 db cr,lf,'Write Protect :',0 erA db cr,lf,'Track ;get count inc BX mov al, 80h cmp cur_disk,0 jne sel1 ;drive 1 if not zero mov al, 40h ;else drive is 0 sel1: mov sel_mask,al ; save select mask or al,[BX] ;merge command and drive code out fdc_com,al ;send command byte parm_loop: dec ck by track basis, rather than sector by * ; * sector. * ; * * ; * This speeds diskette access up, often by a * ; * factor of four or more times. * ; * * ; * The actual disk sectors must be a integral * ; * multiple of 128 bytes,  Checksum Vector Size xlt1 equ xlt0 ;Same Translate Table ; ENDEF ; ; Uninitialized Scratch Memory Follows: ; dirbuf rs 128 ;Directory Buffer alv0 rs als0 ;Alloc Vector csv0 rs css0 ;Check Vector alv1 rs als1 ;Alloc Vector csv1 rs cs;Base of Disk Parameter Blocks dpe0 dw xlt0,0000h ;Translate Table dw 0000h,0000h ;Scratch Area dw dirbuf,dpb0 ;Dir Buff, Parm Block dw csv0,alv0 ;Check, Alloc Vectors dpe1 dw xlt1,0000h ;Translate Table dw 0000h,0000h ;Scratch Area dw dirbuf,d 00 Not Found :',0 erB db cr,lf,'Write Fault :',0 erC db cr,lf,'Sector Not Found :',0 erD db cr,lf,'Error Code D :',0 erE db cr,lf,'Error Code E :',0 erF db cr,lf,'Error Code F :',0 nrdymsg equ er8 b_first_flag db -1 rtry_cnt db 0 cl jz parm_exit ;no (more) parameters, return inc BX ;point to (next) parameter parm_poll: in al,fdc_stat test al,20h ;test "parameter register full" bit jnz parm_poll ;idle until parm reg not full mov al,[BX] out fdc_parm,al ;send next par+     but do not need to be * ; * a power of two multiple unlike the deblocking * ; * algorithms supplied with CP/M-86. * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The following three equates must be set to correspond taring all write flags and setting ; the old drive code to the invalid -1. mov cur_disk,-1 ; insure initial pre-read sub ax,ax ; make a zero mov wr_flag,al ; clear the dirty buffer flag mov di,offset sec_flags ; point to the update flagack buffer mov cur_sec,host_fsn ; starting from first sector call track_read ; load the track correct_track: mov ax,cpm_sec ; get the cp/m sector number if (host_fsn ne 0) sub ax,host_fsn ; correct if we start with sector one endif ag for that sector mov wr_flag,1 ; also set the dirty buffer flag pop cx ; recover BDOS write code cmp cl,1 ; is this a directory update ? jne return ; no, we may leave dirty records ; in the buffer call flush_buffer ; we have a dir physical add bx,dx ; else, we need to fetch the mov bl,[BX] ; actual sector number from the table mov bh,0 ; zero high byte for good luck sectran_exit: ret read: call setup push es ; save the extra segment register mov si,offset tro the ; actual disk utilized. host_sectsiz equ 1024 ; bytes per actual (physical) disk sector host_spt equ 8 ; actual sectors per track host_fsn equ 1 ; starting sector number (only 0 or 1 allowed) init: call clear_flags ; Initialize track bu list mov bx,ds ! mov es,bx ; ES <- DS mov cx,host_spt ! cld ; set length and direction rep stosb ; zero the sector update flags ret track_read: ; read an entire track from the drive "cur_disk", ; the track "cur_track" into "track_buffmov dl,7 ; log2(128) shl ax,dl ; sector times 128 gives offset mov cx,64 ! cld ; move 64 words forward ret flush_buffer: test wr_flag,1 ; see if we have anything to write jz no_flush ; no, skip scanning for dirty sectors mov bx,0 ectory write, need to ; flush the buffer to insure the ; disks integrity return: mov ax,0 ; never return BAD SECTOR code ret setup: ; common code for setting up reads and writes mov al,cpm_disk ; see if selected disk is cmpack_buffer ; source segment is systems DS: add si,ax ; gives the offset into the buffer les di,dma_longword ; point ES:DI at the users sector rep movsw ; doit pop es ; restore the extra segment sub ax,ax ; make a zero return code ret ffering . . . jmp CCP_entry seldsk: mov cpm_disk,cl ; save the selected drive test dl,1 ; check logged-in bit jnz old_disk ; not first time selected if nz ; here if CP/M is about to login to the drive being ; selected. er". ret sector_write: ; write a physical sector to disk "cur_disk", ; track "cur_track", sector "cur_sec" from ; the buffer at DS:"cur_dma". ret dseg cpm_disk rb 1 cpm_track rw 1 cpm_sec rw 1 dma_longword rd 1 org dma_ ; start at host sector 0 mov cx,host_spt ; for host_spt sectors... next_sect: test sec_flags[BX],1 ; see if this sector has been changed jz not_updated ; no, leave it alone mov sec_flags[BX],0 ; zero the flag for next time push bx ; save  al,cur_disk ; the same as last time jne wrong_track ; no, we have wrong track mov ax,cpm_track ; see if desired track is same as cmp ax,cur_track ; the track in the buffer je correct_track ; same drive and track, we don't need to read ;  write: push cx ; save the write mode from the BDOS call setup push ax ; save buffer offset push ds ; save the data segment push es ; save the extra segment mov bx,ds ! mov es,bx ; destination is our data segment mov di,offset track old_disk: mov bl,cpm_disk ! mov bh,0 mov dl,4 ! shl bx,dl ; times 16 add bx,offset dpbase ; gives offset from DPBASE ret ; back to BDOS setdma: mov dma_offset,cx ; save DMA offset address ret setdma_seg: mov dma_segment,cx ; savelongword dma_offset rw 1 dma_segment rw 1 cur_disk rb 1 cur_sec rw 1 cur_track rw 1 cur_dma rw 1 bdos_wr_code rb 1 ; 1 indicates a directory write wr_flag rb 1 ; bit 0 on indicates we have a dirty buffer sec_flags rb host_spt ; bit 0 of ethe registers push cx mov cur_sec,bx ; save host sector number mov ax,host_sectsiz mul bx ; make track buffer offset add ax,offset track_buffer ; make direct pointer mov cur_dma,ax ; save for write routine call sector_write pop cx popDesired operation is on a different track then is in our buffer, ; So it will be nessecary to read in the desired track. First, we ; must check to see if any sectors of the current buffer are dirty. wrong_track: call flush_buffer ; write any old r_buffer ; destination is in track buffer add di,ax ; plus appropriate offset lds si,dma_longword ; source is users DMA address rep movsw ; move that sector pop es ; restore the extra segment pop ds ; and the data segment registers pop  DMA segment address ret home: test wr_flag,1 ! jnz home1 ; if the buffer is clean, mov cur_disk,-1 ; insure we read the directory by invalidating ; the track buffer home1: mov cx,0 ; home is a settrk zero settrk: mov cpm_track,cx ; sach byte on indicates ; corresponding host sector has been ; updated and needs writing. track_buffer rb host_sectsiz * host_spt  bx not_updated: inc bx loop next_sect no_flush: mov wr_flag,0 ; clear the dirty buffer flag ret clear_flags: ; Clear all variables associated with the track buffer, ; so next operation will have to read a track. ; This is involves cleecords, if nessecary mov ax,cpm_track ; get desired track number mov cur_track,ax ; make in new track mov al,cpm_disk ; get desired disk number mov cur_disk,al ; make it current drive mov cur_dma,offset track_buffer ; point dma offset at trax ; recover buffer offset mov cx,host_sectsiz ; setup to divide by host sector size sub dx,dx ; extend ax to 32 bits div cx ; find out which host sector we changed mov bx,ax ; put into index [BX] mov sec_flags[BX],1 ; set the update flave track number for next operation ret setsec: mov cpm_sec,cx ; save sector number for next operation ret sectran: mov bx,cx ; Put logical sector into dest. reg. test dx,dx ; see if table address is zero jz sectran_exit ; yeah, logical =,     -     .     /     0     1     2     3     4     5     6     7     8     9     :     ;     <     =     >     ?     @     A     B     C     D     E     F     G     H     I     J     K     L     1Э Xĝ44=N{v)0.g;:.eg ~SI~!;_X vAMP]Z0H%=ˡmjmnB | )LU^sPh̅m