DFLTDR: mvi c,25 ;func 25 for current disk call BDOS ;get curdsk adi 'A' sta GDISK call CRLF lxi d,VERGET call OUTMSG jmp VERCR ; GETVER: ; Getsys set r/w to read and get the system call CRLF lxi d,VERGET ;verify source disk call OUTMSG VERCR: call GETCHAR cpi CR jnz REBOOT ;jmp only if not verified call CRLF ret ; DESTIN: lxi d,PUTPRM ;address of message call CRMSG ;print it call GETCHAR ;get answer cpi CR jz REBOOT ;all done sui 'A' cpi NDISKS ;v ;to set BC for SEC call call DMA ;dma address set from BC xra a sta RETRY ;to set zero retries ; TRYSEC: ; Try to read or write current sector lda RETRY cpi MAXTRY jc TRYOK ; ; Past MAXTRY, message and ignore lxi d,ERRMSG call OUTMSG call GETCHAR cpi CR jnz REBOOT ; ; Typed a CR, ok to ignore call CRLF jmp RWSEC ; TRYOK: ; Ok to tyr read write inr a sta RETRY lda RW ora a jz TRYREAD ; ; Must be write call WRITE jmp CHKRW TRYREAD: call READ CHKRW: read func call OUTMSG ;print it out ; ; Put the system PUTSYS: call DESTIN ;get dest drive ; lxi h,RW ;load address mvi m,1 call GETPUT ;to put system back on disk lxi d,DONE call OUTMSG ;print out end prompt ; ; FILE COPY FOR CPM.SYS ; CPYCPM: ; Prompt the user for the source of CP/M3.SYS ; lxi d,CPYMSG ;print copys prompt call CRMSG ;print it call GETCHAR ;obtain reply cpi Y ;is it yes? jnz REBOOT ;if not exit ;else ; ; mvi c,13 ;func # for reset calli h,0 ;sector in hl rept LOG2SEC dad h endm ret ;with HL - sector*sectorsize ; GETCHAR: ; Read console character to rA mvi c,CONI call BDOS ; Convert to upper case cpi 'A' or 20h rc cpi ('Z' or 20h)+1 rnc ani 05Fh ret ; PUTCHAR: ; Write character from rA to console mov e,a mvi c,CONO call BDOS ret ; CRLF: ; Send Carriage Return, Line Feed mvi a,CR call PUTCHAR mvi a,LF call PUTCHAR ret ; CRMSG: ; Print message addressed by the HL until zero with lealid disk jc PUTC ; ; Invalid drive call BADDISK ;tell user bad drive jmp PUTSYS ;to try again ; PUTC: ; Set disk fron rA adi 'A' sta PDISK ;message sent sui 'A' mov e,a ;disk # in E call SEL ;select destination drive ; Put system, set r/w to write lxi d,VERPUT ;verify dest prmpt call CRMSG ;print it out call GETCHAR ;retrieve answer cpi CR jnz REBOOT ;exit to system if error call CRLF ret ; ; GETPUT: ; Get or put CP/M (rw = 0 for read, 1 for write) ; disk i ora a jz RWSEC ;zero flag if read/write ok ; ;Error, retry operation jmp TRYSEC ; ; End of track ENDTRK: lda SPT ;sectors per track call MULTSEC ;*secsize xchg ; to DE lhld DMADDR ;base dma for this track dad d ;+spt*secsize shld DMADDR ;ready for next track jmp RWTRK ;for another track ; ENDRW: ; End of read or write ret ; ;******************* ;* ;* MAIN ROUTINE ;* ;* ;******************* ; START: lxi sp,STACK lxi d,SIGNON call OUTMSG ; ;get version ; Macro Definitions for CP/M3 BIOS Data Structures. ; dtbl - drive table ; dph translate$table, - disk parameter header ; disk$parameter$block, ; checksum$size, (optional) ; alloc$size (optional) ; skew sectors, - skew table ; skew$factor, ; first$sector$number ; dpb physical$sector$size, - disk parameter block ; physical$sectors$per$track, ; number$tracks, ; block$size, ; number$dir$entries, ; track$offset, ; checksum$vec$size (optional) ; Df)*?spt ?dsm set ?size/(?bls/128)-1 ?exm set ?bls/1024 if ?dsm > 255 if ?bls = 1024 .'Error, can''t have this size disk with 1k block size' exitm endif ?exm set ?exm/2 endif ?exm set ?exm-1 ?all set 0 ?n set (?ndirs*32+?bls-1)/?bls rept ?n ?all set (?all shr 1) or 8000h endm ?al0 set high ?all ?al1 set low ?all ?drm set ?ndirs-1 if not nul ?ncks ?cks set ?ncks else ?cks set ?ndirs/4 endif dw ?spt ; 128 byte rSPhhP8ͱ HFlh8` nx*l6ǀ3ll8 ~ `4fPp$#`?ٶ4u`Lͮ`eU8kFo&ePJܮwXڮVmfP DJ¯@ pic@Y FՀ3lh #~K6ƀHP&Y)AD24D) #: Id ynјY)AB@h(P&!r7Bi6L@r2L@3%0h(H @P( @P( @P( !Xf. rfi3A R G!`i3N`e9L'#  Cd l [ -"ڴ#+[p[@?쁲[*@`^2K6meRq}Bwٴj^2! ;4f@RzKƬ;ͽ~ â:!~mU0wz@uB@+͵͸ja] mfݠ6ma`Q2XCp̃\Ub4f07 JYM"3i(2GV ew*a q='@DuO#?(W ;k+6 ~PV BP@2!~sǣ+t9erl[U;D +Wx z2AEwvlfuhٶI,V f`CMa 2YMWx!y@b+ó`@ @-U Uw[AF: c6B*OU > 0"[-Ke%ـlrive Table. Contains 16 one word entries. dtbl macro ?list local ?n ?n set 0 irp ?drv, ?n set ?n+1 dw ?drv endm if ?n > 16 .' Too many drives. Max 16 allowed' exitm endif if ?n < 16 rept (16-?n) dw 0 endm endif endm dph macro ?trans,?dpb,?csize,?asize local ?csv,?alv dw ?trans ; translate table address db 0,0,0,0,0,0,0,0,0 ; BDOS Scratch area db 0 ; media flag dw ?dpb ; disk parameter block if not nul ?csize dw ?ecords per track db ?bsh,?blm ; block shift and mask db ?exm ; extent mask dw ?dsm ; maximum block number dw ?drm ; maximum directory entry number db ?al0,?al1 ; alloc vector for directory dw ?cks ; checksum size dw ?off ; offset for system tracks db ?psh,?psm ; physical sector size shift ; and mask endm ; gcd macro ?m,?n ;; greatest common divisor of m,n ;; produces value gcdn as result ;; (used in sector translate table generation) ?gcdm set ?m ; ^Ȋ l9O/J7ps[F՛/xFV][^+vz@W ]+z@t"^+zEW Tz@W ^+z@W ^+z@W ^)jcv;cv;cv;cv;cv;cv;cv;cv;cv;cv8-Vx ͡LȆ?쁣@¶CVK'%dm]0p@" _2lR{6݁0Xw< M"0xʄGAD"!< "Ce6LgA!@r6а0 f a0 f f'/v{BH»@Y{La0`5;l:JfѰՐ^b1b+$Dp"[<-Ki%pm@D"[T-Kl%A@mD"[n-Kn%ЉmD"[-?帡`n@D$"[-Ks% {tX$@UaUzjH+{P@3k(3jK4K6`JYG&ml fհmIW, x@(dz¦.U _6J XKUw(A^Od`@F*K՛v#ץf@#sFI'Ma 2YMWx!y@b+ó`@ @-U Uw[AF: c6B*OU > 0"[-Ke%ـlcsv ; checksum vector else dw 0FFFEh ; checksum vector allocated by endif ; GENCPM if not nul ?asize dw ?alv ; allocation vector else dw 0FFFEh ; alloc vector allocated by GENCPM endif dw 0fffeh,0fffeh,0fffeh ; dirbcb, dtabcb, hash alloc'd ; by GENCPM db 0 ; hash bank if not nul ?csize ?csv ds ?csize ; checksum vector endif if not nul ?asize ?alv ds ?asize ; allocation vector endif endm dpb macro ?psize,?pspt,?trks,?bls,?n;variable for m ?gcdn set ?n ;;variable for n ?gcdr set 0 ;;variable for r rept 65535 ?gcdx set ?gcdm/?gcdn ?gcdr set ?gcdm - ?gcdx*?gcdn if ?gcdr = 0 exitm endif ?gcdm set ?gcdn ?gcdn set ?gcdr endm endm skew macro ?secs,?skf,?fsc ;; generate the translate table ?nxtsec set 0 ;;next sector to fill ?nxtbas set 0 ;;moves by one on overflow gcd %?secs,?skf ;; ?gcdn = gcd(?secs,skew) ?neltst set ?secs/?gcdn ;; neltst is number of el#b1En6`  fԐ1Uum(@8"ͩ bT|Ёnʲc`ݒͣJU;$wgvHea͵@lNd6Xt\ Ux&m&bsgHdf(eaUpW }IGÕAV!I@.1[|V!K'ԙ4yL6#Fr8#* Jj\U +ͣMU9Lg!yI ;6 pfiEt(Ub F$ [@{m8A8upBk = ?secs ?nxtsec set ?nxtsec-?secs endif ?nelts set ?nelts-1 if ?nelts = 0 ?nxtbas set ?nxtbas+1 ?nxtsec set ?nxtbas ?nelts set ?neltst endif endm endm d>g>:N ,:h : Rxf0V jo<- 'i0)d`@!M#%y`ݒ{JI;%%Ydn0ڄ-V<|fހfQfݠ6m]YmrXHk!W!*UC6(9``* º`+`1YbGV ^G< E`Y jV_0H05O#+v: s خSx:q$Of`R(Ԅ.- ͼ{>X0Y""f@VmjYVlUyBlڰ :0rP1nʲLJ5cAU %Ja`ͼ` `@k+T$ dp#t f`C՛V]b3jH6'p0!!*WH|#+x[݀:a v@G XG XG +XG aXG XG    ( !8q!06:8!0{ *3NH*3#"3!04\ !06:8!0ں *5}§ !76^Hì  H*5#"5!04ƒ !;s+p+q!"<!;>w *;M!<+s#r*<9+s#r!>q!"@}2?>!?3*?&m ~,*@DM*?; "@!?4*>M*@!Bq!C6>!Cp*B&))) *C& NH!C4H!Dq*D&)))  ~2FO>ҕ!F6!E6>!E*F&Ͳ *E& NH!E4š!Gq!I6*G&)))  ~2H2HIH!I4:H2HI=2*S͘2e͘2f X:e!g:"O!C ^#VXUU$XUU/XUU:XUUEXU "+.7:*MͰ"*DM :2::Hқ*MS:::H:H: HI : !6!6~#r!886+s#r#4¸>!8s+p+q:85*8>X6+s#rL*8*8M!h6\6+s#r!8p+q!86:8!86>~6HҊ!8n6+s#r#4X:8!8p+q*8N#FM28O>Ҫ>!"8>!8*8M!8d6+s#r*88͸6s#r:88͗6:8H9 :8**8#~A!86!*8#~D*8##~IH9!76!*8#~D*8##~AHc!86!86!*8#~Eu!76!*8#~F«*8##~F’!86è*8##~U¥!86è? !*8#~G:8*8##~028*8##~0o&<6*8 ~0_!8s:8/>!8/HOH!I4:H2H'SH!I4:H2H>XH!I4:IR H!I4> XX:e2J(r!J6(*J&!͈!Ls+6!J6*K&))) ~  *KM? H*KMq H*KMX!K4+~!L Å!J4Ê!Qp+q:e2c(!c6(:c _!͈!es!c6>!c/*P)"P*c&S w!c4 !c6*c&))) ~X:cQX!c44:c2f!R6!d6+6>!c*c&S ~:f!cҝX%X !R6*cM? H!d4:e!d6 DX!c4k:b!R6OX:RTX `X"ͰUZ :O! ~2:J:- G:"= G*M!6#6>!p*&m 6:<2R:/:}+DMn2:— *&m 6:±*M#::H:*}~HH!6:*}~,H