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 r…�ÔS¥P©hÆÀ€³hP8ͱ  àHF’€³lh8µ` Ûþ„nx*Ñlû6Ç€3l¨†À„l8 ~ Ä`Ö4fÙPp$#`?Ù¶4u`€Lã«Í®`«·eUð8êÁ€³k˜†®ÿŸŸÂFoŸŸÄ&e©ØPJÜ®æwXÿºÚ®Vm�fÙP DJ¯@ �pi›c@Y à FÕ€3lh Ü#~€àK6Æ€¼ÎÏöH†P&ŒÄ€¦Y)€AD2�4˜D) §#‘¼ä: ÆI°Êd âyÀÊnÊј¸¦Y)ƒAB@h(†P&“…!”är7œ‡B˜Âi6L‚¡¼@r2˜L‚@š3Ë%0h(H �@ P( �@ P( �@ P( !”äÑXf. †ó �Êr‚ˆfó�ääi3š‚A R ŽG!`€ˆi3šN†`€¤e9™L'#   CˆàdØ l ¶[ -‡Ö"»á³ËøÚ´ #+į[p�ÕÞ[àƒØÊÝ@êñ?�ì�²’å[À…»*þƒ@`ÉÝ^2·�K6ó‰àÆmãeRqð}BwÙ´è›j™·ü^2¸! ;Ê4fß@Rzù¥K�Ƭ;Òͽ€ÌÛ~ âàìÛþ:¸!~¾mU0wò…z@™·üuB@Öì+Ò͵ÀŒ«Ò͸ƒ«j·a] †m›fÝ 6m³aÑ`QÕÞ2¨XôCp‚̃¹\Ubµ4¾ÕfÕ07 J…�‹Y«M"3iÐ(ŠÄ2GVè ew‚*ñ•ÈaÝ qòŽ='Š®ø@Du†OÊò„î#?(W ü¡;³k+6÷” «¤~PœVð B®P@ùþ2¼!«¾~sÇ£+tþ²¯°9øer‚¶l›[ÁÇÀUß;²D ŠÄ+ÆWx z2¸AEwvl›fÁØu¼›h�Ù¶ˆ›IÂ,ÛV Èfß`Cðñ…MÂa°ÑÝ 2Y¶¤‡MÁÇWx!‡y@�b+¸ó`£«Äþ¶«ð@êß ®ð@êð„-ÙUø UwÂÀÕÊ[²«€AÜF:¹ c»6÷­àBØî*¨O‘U >‘ ¶0"[-�–ÉKe%²ÁÙ€‰lÐrive 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 ; ^�ÈŠ  l�†§9O/á“Jå’Ä7p‡sÀ[ÆFÕ›/…€�ÉxFV]ð‡[¦ô^€+vz¯@è½W  ô]ð+Ðz¯@¢át"ô^€+Ðz©ØEè½W  ôTŠŽz¯@è½W  ô^€+Ðz¯@è½W  ô^€+Ðz¯@è½W  ô^€)jŽÇc±Øìv;ŽÇc±Øìv;ŽÇc±Øìv;ŽÇc±Øìv;ŽÇc±Øìv;ŽÇc±Øìv;ŽÇc±Øìv;ŽÇc±Øìv;ŽÇc±Øìv;ŽÇc±Øìv8ê÷-ØVx ŠÍ¡�LȆí?�ì�£ø@П–ìƒËø¶ CVKøÀ'—ð%…d€�Âm’] ‡0…p@™"¶ _2lR{6Ý�0Xw< ÖM"0îxÊ„�²GÀåAD"!<¦ "”ŠC¡�¦e6LgA!@Êr6‹„’а0 ïfÜð üaÒ0 ïfÜð fÜð'™Øö•/ž“…v€’{B—ÏH»@ÉY”{œ†—ÌLÈaÓð0`5�;„Äl:”JfѰ£âÕ�^•„b1ŠÈÄb+$D¶p"[<- –ÑKi%´¡Úp‰m@D¶¤"[T-¬–×Kl%¶AÛ@‰m¨D¶Ø"[n-¸–ÝKnÂ%·�ÛЉmðD¶ü"[€-Á–á?帡Ü`‰n@D·$"[”-Ë–æKs‚%ºÝ �ð›{‚tX$@Užaß�U z³j Hêá„Ô+–{PŒ®@Šæ3k�(ŠÅ3jØKÅêþ4¨àK6Ÿ�²©`J½›YGÀ&ml fÕ°–mIW, x@(ødz¦Á.±UŠ ¼_À6J XÀ†K¬Uw(¥…­¨A^OdŠ®`@Fဌ�ˆ*¹�–KÕ›v€Þ#×¥³fÖ@‘Œ#s‚ÀFI–ÿ„€'ž…MÂa°ÑÝ 2Y¶¤‡MÁÇWx!‡y@�b+¸ó`£«Äþ¶«ð@êß ®ð@êð„-ÙUø UwÂÀÕÊ[²«€AÜF:¹ c»6÷­àBØî*¨O‘U >‘ ¶0"[-�–ÉKe%²ÁÙ€‰lÐcsv ; 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#ˆÄb1¬En6`  fÔ�1U˜uˆm(@8"Í© b«T|ÛÐ�³ýnʲ c`Ý’Í£JñU�;ˆÎâ«$w�ÄgvH†á„„ea’͵@lÚN·dßÀ6ÕXt\ UxÂÀ&m&b†sœ„gHªÈ„df(ªÉ„eaUpÂW ž}IŸG”Õ¥AÁV”!›I@Ü.1[�‡|ÅV”!›K€Ü'Ô™ñ4yL6¨ð#ŒFãr°è8#�Ê*´¡ ÚJáj±\®±U² ‘ ¢+œÍ£ÁMU�9ˆÎLˆªÉÄg!Á‚yI›Ï £;6µ‚ ¢«pëfÓ¢iEt´„(Ub‚ ¤F$ [@‚{“ˆm8A8upBáðk ¼‚ÇÀ„±= ?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 :»Á Rx„fÓ0V åjo<- ì‘ÕÞ'³i0)õÌdЬ`@êä„!Mí#%›y�Î`ùÝ’{J›ÏIÃ;%ª%áYÖÑd³n0êÚ„-ÙV<|fÞ€†›fÚQŒfÝ 6m³]À†§Yà†mrX †H†ñ„„kæñ’!¿ÄWŒ!’*µ�±U㈯C6µ‚¶­ (êñ„9€``* º`£+’·`1Yµô‚Éb½GV¤ ^G<¨ ïEÌ`²Y·Ø ƒ¬j¼V_0¨H05…ÁO#+v:·¡ sà ‹Ø®Sx˜:´áqð$OfÒ`R(êÔ„.-«ø ͼÀ„á{˜>¡X0Y"«¾"¼¡‘•çfÛ@Vm—¶ì›jÁYVlUyBlÚ° :¼áð0üþr²ªP1ånʲ€Ç‡ð5•cAŸÀÆU‚ %œÇöJaØÐ`Ӝͼ`¬» ¥Ä`@k´+ÆT$ Žd�Ÿäp#ò��ìÚt ÈfÞ`CóÕ›V]b«¾3jH6ú“Þ'p0Ö!€!¤‹*ìWH|€#Ï+xÉ[ÀƒòÝ€:·a v@ÃG ÌÍXÃG ûÍXÃG +ÍXÃG aÍXÃG ŒÍXÃG Î × à é ò û    ( ÍÊ ÍÉ!8q!06:8!0¾Ú{ *3NÍH*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>!C¾Úp*B&)))ƒ å*C&Á NÍH!C4ÂHÉ!Dq*D&)))ƒ  ~2FO>¹Ò•!F6!E6>!E¾ÚÅ*F&Ͳ� å*E&Á NÍH!E4šÉ!Gq!I6*G&)))ƒ  ~2H·2HŸþÿÂ÷IÍH!I4:H·2HŸI=2ƒ*ƒëÍÈÃS͘2e͘2fÍÊ ¯ÍX:e!…¾Òg:…Ö"O!C ^#VëéÍXÃUÃU$ÍXÃUÃU/ÍXÃUÃU:ÍXÃUÃUEÍXÃU "+.7:*…MͰ"†*†DMÍàÍÊ ÍÉ:2ˆ:�ÖÖŸõ:�ÖÖŸÁH±Ò›*MÍSÃî:�þÂá:ÖÖŸõ:ÖÖŸÁH±õ:ÖÖŸÁH±õ:Ö ÖŸÁH±ÒÙÍIÃÞÍ Ãî:�þÊîÍ !�6!6ýÅ~#r!¢8Í86ë+s#r#4¸>ÿÉ!§8s+p+q:§8þÂ5*¥8>ÍX6ë+s#rÃL*¥8å*§8M!Íh6ÑÍ\6ë+s#rÉ!©8p+q!ª86:ª8ÖŸ!¨8õÍ6>Í~6µÖŸÁH¡ÒŠ!¨8Ín6ë+s#r#4ÃX:ª8É!¬8p+q*«8N#FÍM2­8O>¹Òª>ÿÉ!"®8>!­8¾ÒÈ*­8M!®8Íd6ë+s#r*«8®8å͸6ëás#r:­8Éÿÿ²8Í—6µÆÿŸõ:¶8æÖÆÿŸÁH¡Ò9 :¹8þÊ**´8#~þAÂ!’86ÿÃ!*´8#~ÖDÖŸ*´8##õ~ÖIÖŸÁH¡Ò9!ø76ÿÃ!*´8#~ÖDÖŸ*´8##õ~ÖAÖŸÁH¡Òc!Œ86!‘86ÿÃ!*´8#~þEÂu!ÿ76ÿÃ!*´8#~þF«*´8##~þFÂ’!�86ÿè*´8##~þUÂ¥!Œ86èÃ? Ã!*´8#~þGÂ:·8þÒË*´8##~Ö02»8Ãî*´8##~Ö0o&Í<6å*´8 ~Ö0_áë!»8s:»8ÖŸ/õ>!»8–Ÿ/ÁHþÿÂOÍH!I4:Hæþ2HŸþÿÂ'SÍH!I4:H·2HŸþÿÂ>XÍH!I4:IþÊR ÍH!I4Ã>ÉÍÊ ÃÍXØÍX:e2Jþ(Òr!J6(*J&ë!͈!Ls+6!J6*K&)))ƒ ~þ ÍÊ É*KMÍ? ÍH*KMÍq ÍH*KMÍÆÿÍX!K4+~!L¾ÚØÍÊ Ã…!J4ÊÉ!Qp+q:e2cþ(Òö!c6(:cÖ _!͈!es!c6>!c¾Ú/*P)"PŸ*c&S w!c4 !c6*c&)))ƒ ~þÊX:cþÂQÃX!c4Ã4:c2f!R6!d6+6>!c¾ÚÎ*c&S ~þÿÂÇ:f!c¾Ò�ÍX%ÍXÍÊ É!R6*cMÍ? ÍH!d4:e¾ÒÇ!d6ÍÊ DÍX!c4Âk:bþÿÂá!R6OÍX:RþÂïTÍXÍÊ ÉÍÊ `ÍX"ͰUÍZ :ˆÖO!Ý ~2‰:þÂJ:‰þÒ- Í ÃG:‰þ"Â= Í ÃG*‰MÍêÃ!Š6#6>!‹¾Úp*‹&m 6:‹<2‹ÂR:Š/Ò:€}Íç+DMÍn2Œ:Œþÿ—Í *Œ&m 6:�þ±*ŒMÍ#:�ÖÖŸõ:�ÖÖŸÁH±õ:�ÖÖŸ*}õ~ÖÖŸÁH¡ÁH±Òç!Š6:�ÖÖŸ*}õ~Ö,ÖŸÁH¡Ò