IMD 1.12: 12/12/2009 20:20:02 Morrow M16 2of2    ABOOT& ASM CDEFABOOT& ASMCGHIJKLMNOLOAD COMCBIOS& ASM* loader during the load. * * * * track sector sysgen load order Name * * * * 0 1 900 ff00 0 BoCBIOS& ASMCBIOS& ASMCBIOS& ASMCBIOS& ASMv. B 8 inch disk controller (DJ2D/B), * * Disk Jockey DMA 8 + 5 1/4 inch controller (DJDMA), * * Hard Disk Controller revisioCBIOS& ASM !"#$%&'()*]^_`aCBIOS& ASMbcdefghijklmnMBASIC COM+,-./0123456789:MBASIC COM>;<=>?@ABot loader * * 0 2 980 Unused * * 0 3 a00 * * 0 4 a80 * * 0 5 b00 9100 1 CCP * * 0 6 b80 9180 12 * CBIOS& ASM n 3 (HDC3), * * or the Hard Disk DMA (HDDMA) disk controllers. * * * * Provisions have been made for a Micronix booNOTESHD DOCyCDEFGHIJKLMNOPQRPIP COM:STUVWXYZPRL DOC [\CBIOS& ASM * 0 7 c00 9200 2 * * 0 8 c80 9280 13 * * 0 9 d00 9300 3 * * 0 10 d80 9380 14 * * 0 11 e00 9400 4 * * t loader. * * This loader always gets loaded to 0100h. * * * * 8 inch floppy disk boot loader for the * * CBIOS& ASMSINGLE ASMZopqrstuvwxyzSINGLE COM{STAT COM)|}~***************************************************************** * * * Morrow Designs CP/M vers 2.2 Cold Boot Loader.0 12 e80 9480 15 * * 0 13 f00 9500 5 * * 0 14 f80 9580 16 * * 0 15 1000 9600 6 * * 0 16 1080 9680 17 * * 0 1 Morrow Designs Disk Jockey 2D/B (DJ2DB) * * * * The 'order' column is the interleave sequence used by the * SUBMIT COM SYSGEN COM VITALS BADXSUB COM * * Cbios revision E.2, 3/4/82. * * * * The following routines will boot CP/M from the * * Disk Jockey 2D Re 7 1100 9700 7 * * 0 18 1180 9780 18 * * 0 19 1200 9800 8 * * 0 20 1280 9880 19 * * 0 21 1300 9900 9 BDOS * * 0 tart loading from track 0, * * sector 1 and stops at track 1, sector 9. The load * * sequence is as follows: * *  * * The loading is identical to that of of the DJ2DB except * * that the loader itself is loaded at 80h and the 'order' * * * for the loader. This cold boot loader will start loading * * the CCP from track 0, sector 2 and will finish up with * * theo 4) have been * * provided for a more advanced boot loader at a later date. * * * * The warm boot loader starts on tr1 7 2b00 b500 17 * * 1 8 2d00 b700 18 * * 1 9 2f00 b900 19 * * * * The warm boot starts from track 0 sector 22 1380 9980 20 * * 0 23 1400 9a00 10 * * 0 24 1480 9a80 21 * * 0 25 1500 9b00 11 * * 0 26 1580 9b80 22 * *  * * track sector sysgen load order Name * * 0 0 900 80 0 Cold boot * * 0 1 b00 9500 1 CCP * * 0 2 d00 97column does not apply. The DJDMA is capable of loading a * * complete track at a time and thus it merely zaps the * * tracks last part of the Cbios on track 0, sector 20. * * * * track sector sysgen load order Name * * 0 1 900 fc00ack 0, sector 5 and * * continues through to track 1 sector 3. Only the first * * 3/4 K bytes of track 1, sector 3 is loaded1 and continues * * through to track 1 sector 1. * * * * * * Shugart SA4000 disk interface boot loader for * * Track 1 is recorded in double density format. There are * * 1024 bytes per sector. * * * * 1 1 1600 9c00 00 2 * * 0 3 f00 9900 3 * * 0 4 1100 9b00 4 * * 0 5 1300 9d00 5 BDOS * * 0 6 1500 9f00 6 * * 0 7 1700 a in all at once. * * * * * * 5 1/4 inch floppy disk boot loader for the * * Morrow Designs Disk J 1 Cold boot * * 0 2 b00 9500 2 CCP * * 0 3 d00 9700 3 * * 0 4 f00 9900 4 * * 0 5 1100 9b00 5 * * 0 6 1 since CP/M * * requires that the warm boot loader load up to the start * * of (but not past) the Cbios jump table. * *  the * * Morrow Designs Hard Disk Controller rev. 3 (HDC3) * * * * The cold boot loader (track 0, sector 1) is loaded  4 * * 1 2 1a00 a000 1 * * 1 3 1e00 a400 5 CBIOS (@ a700h) * * 1 4 2200 a800 2 * * 1 5 2600 ac00 6 * * 1 6100 7 * * 0 8 1900 a300 8 * * 0 9 1b00 a500 9 * * * * 1 0 1d00 a700 10 * * 1 1 1f00 a900 11 * * 1 ockey DMA (DJDMA) * * * * The cold boot loader (track 0, sector 0) is loaded into * * RAM at 80h. This loader will s300 9d00 6 BDOS * * 0 7 1500 9f00 7 * * 0 8 1700 a100 8 * * 0 9 1900 a300 9 * * 0 10 1b00 a500 10 * * 0 11  * * * * 8 inch floppy disk boot loader for the * * Morrow Designs Disk Jockey DMA (DJDMA) * * into * * RAM in the very last part of the Cbios. This area is * * used for uninitialized tables and thus is a safe place *  2a00 b000 3 * * 1 7 2e00 b400 7 * * 1 8 3200 b800 Unused * * * * Three spare sectors (track 0, sectors 2 t 2 2100 ab00 12 CBIOS * * 1 3 2300 ad00 13 * * 1 4 2500 af00 14 * * 1 5 2700 b100 15 * * 1 6 2900 b300 16 * *  1d00 a700 11 * * 0 12 1f00 a900 12 * * 0 13 2100 ab00 13 CBIOS * * 0 14 2300 ad00 14 * * 0 15 2500 af00 15 * * 0 1ee in the future is * * the increasing the space for the uninitialized tables * * following the Cbios. The amount of code anth the cold boot loader and * * part of the CCP. The cold boot loader relocates this * * peice of the CCP to it proper resti * b00 9500 b500 c500 cd00 d500 CCP * * 1300 9d00 bd00 cd00 d500 dd00 BDOS * * 2100 ab00 cb00 db00 e300 ed00 Cbios * * 3100  * Morrow Designs Hard Disk DMA controller (HDDMA) * * * * track sector sysgen load order Name * * 0 1 900 system. Out * * of this 5.5k bytes are used by the (CCP + BDOS) leaving * * us with a total of 4k bytes of loaded code and da6 2700 b100 16 * * 0 17 2900 b300 17 * * 0 18 2b00 b500 18 * * 0 19 2d00 b700 19 * * 0 20 2f00 b900 20 * * 0 21 3d table space * * that can actually be loaded from the disk is fixed by the * * amount of space available on the system tracksng place as part of * * the boot process. * * * *****************************************************************bb00 db00 eb00 f300 fb00 Tables * * 35ff bfff dfff efff f7ff ffff The End * * * * ~~~~ 8d00 ad00 bd00 c500 cd00 DDT *  100 0 Cold boot + CCP * * 0 2 d00 9300 1 * * 0 3 1100 9700 2 * * 0 4 1500 9b00 3 Bdos (@ 9d00) * * 0 5 1900 9fta space * * to play with. Right now we are using all of this space * * so any major additions will have to result in a littl100 Unused * * * * The warm boot load sequence starts at track 0, sector 2 * * and goes straight through to sector . * * * * Our most restrictive (smallest) drive is the 5 1/4 inch * * 'minnie floppy'. This drive has 20 512 byte se ***************************************************************** * * * The following table gives a general idea as * * ***************************************************************** micron equ 0 ;Set to 1 for Micronix boot loa00 4 * * 0 6 1d00 a300 5 * * 0 7 2100 a700 6 Cbios * * 0 8 2500 ab00 7 * * 0 9 2900 af00 8 * * * e * * (lot?) of code shuffeling or in the creation of a Cbios * * that simply will not fit on a small disk drive. * * 12. There is still * * plenty of room left in this loader for more advanced * * things like sector interleaving although thictors for * * a total of 10k bytes on the system tracks. The 8 inch * * floppy disk drive is also very close to being filled  to where the * * various parts of of the operating system are in memory. * * * * The only changes to the map that I sder if micron eq 0 msize equ 48 ;Memory size of target CP/M biosln equ 10h ;BIOS length codlen equ 11h ;Code le* 1 10 2d00 b300 9 * * * * Since 1k byte sectors were implemented on this disk; * * track 0, sector 1 contains bo * * sysgen 48k 56k 60k 62k 64k * * image CP/M CP/M CP/M CP/M CP/M * * * * 900 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ Loader * s is hardly * * necessary on a hard disk. * * * * * * Shugart SA1000 disk interface boot loader for the * up. * * * * Since 512 bytes are reserved for the cold boot loader we * * have a total of 9.5k bytes for the operating  ngth ccpln equ 800h bdosln equ 0e00h size equ (msize*1024) ccp equ size-(biosln*100h+ccpln+bdosln) bdos equ ccp+ccplnontroller hdstat equ hdorg ;Hard Disk Status hdcntl equ hdorg ;Hard Disk Control hddata equ hdorg+3 ;Hard Disk Data hdfun****************************************** * * * DJ2D/B prom base address. * * * ***************************************** * * * The following equates are for the Hard Disk DMA. * * * ********************************y one of the following equates should be set. The * * others sould be 0. These equates define the boot loader * * that is ton hdrlen equ 4 ;Sector header length secln equ 512 ;Sector data length wenabl equ 0fh ;Write enable wreset equ 0bh ;Wri bios equ ccp+ccpln+bdosln cboot equ bios ;Cold boot address for CP/M loaddr equ ccp ;Load address for floppy else c equ hdorg+2 ;Hard Disk Function hdcmnd equ hdorg+1 ;Hard Disk Command hdreslt equ hdorg+1 ;Hard Disk Result retry equ 2 *************************************** if maxfd ne 0 origin equ 0f800h ;Orgin of DJ 2D Mod B PROM endif ******************************************* if maxmw ne 0 cyl equ 153 ;Specifications for a Seagate Technology 506 heads equ 4 ;No be used. * * * ***************************************************************** maxhd equ 0 ;Set to boot ante reset of function scenbl equ 5 ;Controller control dskclk equ 7 ;Disk clock for control mdir equ 0f7h ;Direction mask f;Micronix boot loader cboot equ 0100h ;Cold boot address for the loader loaddr equ 0100h ;If the load address is mo ;Retry bit of result tkz equ 1 ;Track zero bit of status opdone equ 2 ;Operaction done bit of status complt equ 4 ;Comple******************************************************* * * * The following equates are for the Hard Disk Controller 3.umber of heads per cylinder spt equ 9 ;Sectors per track precomp equ 64 ;Cylinder to start write precomensation lowcurr equ HDC3 controller maxmw equ 0 ;Set to boot a HDDMA controller maxfd equ 1 ;Set to boot a DJ2D/B controller maxdm equ 0 ;Setor function null equ 0fch ;Null command idbuff equ 0 ;Initialize data command isbuff equ 8 ;Initialize header command rseved forward from ;0100 then the starting extended address for ;the djdma boot loader should be adjusted. endif rete bit of status tmout equ 8 ;Time out bit of status wfault equ 10h ;Write fault bit of status drvrdy equ 20h ;Drive ready * * * ***************************************************************** if maxhd ne 0 hdorg equ 50h ;Hard Disk C 128 ;Cylinder to start low current stepdly equ 30 ;Step delay (0-12.7 milliseconds) headdly equ 20 ;Settle delay (0-255 mi to boot a DJDMA controller with 8 inch maxmf equ 0 ;Set to boot a DJDMA controller with 5 1/4 inch ***********************ct equ 1 ;Read sector command wsect equ 5 ;Write sector command endif **************************************************tries equ 10 ;Maximum # of disk retries ***************************************************************** * * * Onl bit of status indx equ 40h ;Index bit of status pstep equ 4 ;Step bit of function nstep equ 0fbh ;Step bit mask of functi lliseconds) sectsiz equ 7 ;Sector size code (must be 3 for this Cbios) ; 0 = 128 byte sectors ; 1 = 256 byte secto DM+;! p+q* i2 ! p+q* i2 ! p+q* i2 i2 !" p+q*! f!$ p+q*# i!& p+q*% i! ADDRESS $BYTES READ:$INVALID HEX DIGIT$CHECK SUM ERROR $FIRST ADDRESS $LAST ADDRESS $BYTES READ $RECORDS WRITTEN $HEXCANNOannel address stepout equ 10h ;Step direction out stepin equ 0 ;Step direction in band1 equ 40h ;No precomp, high current q=  ͝Kd*= ! ͸p!@ 6>!@ X*= }O!< *@ & w*= #"= !@ 4)!< 4\mad* }O!< :? wrs ; 3 = 512 byte sectors ; 7 = 1024 byte sectors (default for CP/M) ; f = 2048 byte sectors ;Define cont( p+q*' i2 !* p+q*) f!/ s+p+q+p+q:/ =2/ X*+ *- w*+ #"+ *- #"- 1* #" ͖r*   ~!" ! ͸T OPEN SOURCE$COMNO MORE DIRECTORY SPACE$CANNOT CLOSE FILE$*!9"!e !" !" \!""͊: ƒ band2 equ 0c0h ;Precomp, high current band3 equ 80h ;precomp, low current track0 equ 1 ;Track zero status wfault equ 2 ;lR*4 DM+{R* DM+R 4 ͝*4 }¿= 4 ͝< N*4 #"4  å;*4 DM+: Y2roller commands dmaread equ 0 ;Read sector dmawrit equ 1 ;Write sector dmarhed equ 2 ;Find a sector dmawhed equ 3 ;Write×* " x20 º*   DM":0 Ad*   6!" Ç!" : !"6 "8 ": }2< !"4 "= ! de"\\\͊: ²d\͝: )d;! q* &f  ! q> ! : A O************************************************************************* * * * Morrow Designs CBIOS for CP/M Version Write fault from drive dready equ 4 ;Drive ready endif ***************************************************************** A 0O> :A 0:A AO>&R̀:A A H.2B !2 w:B !D s+q*C &͍:D _og_ headers (format a track) dmalcon equ 4 ;Load disk parameters dmassta equ 5 ;Sense disk drive status dmanoop equ 6 ;Null c6Y: !2 6=21 á:1 : r+s#r==_HL"4 " >6 ͪS* "6 =23 :1 =21 v=O* #" Y8  ͝: 0O! q: O: O! p+q* |O* }O! p+q*  f! p+q* DMB! p+q)R* DMB1B*2.2. * * * * This CBIOS can be configured to run with the following devices. * * The disks may be configured to r@ COPYRIGHT (C) 1978, DIGITAL RESEARCH ERROR: $, LOAD ADDRESS $DISK READ$INVERTED LOAD ADDRESS$DISK WRITE$LOAD ADDRESS $ERROR{ozg^#V) _{ozgi`N#Fogo&og_{_z#Wontroller operation reset equ 54h ;Reset controller attn equ 55h ;Send a controller attention chan equ 50h ;Default ch* +"8 .!2 ʞR̀* "4 4 = ͝* #" çR*6 DM+R*8 DM+R*: DM+R*< M!?  un with any or all of the disk * * systems. The logical order of the disks can be set to any order. * * * * Disk sys * * 11 9 82 Marc Reduced bad map size to 1 for non MW systems * * 11 8 82 Marc Deleted baud rate test from Multio driveriskette in the B: * * drive and then PIP it over to a 1024 byte sector * * system diskette. * * * * Written bBGEN * * 9 9 82 Marc Fixed system length checks for 64K systems * * 9 9 82 Marc SETHIGH was botching 2 sided DPB pointer for the Hytype II. * * * * Note: Floppy systems diskette (drive A:) has to have 1024 byte * * sectors in order forhave 1024 directory entries * * 9 28 82 Marc Deleted the Centronics drivers * * 9 27 82 Marc Changed login message to ltems: * * HDCA 10, 20 and 26 megabyte hard disks. * * HDDMA 5, 10, 16, megabyte hard disk systems. * * DJDMA flops * * 11 4 82 Marc Added initial IOBYTE to IOCONF * * 11 3 82 Marc Added the North Star character I/O system * * 11 2 y Les Kent and Marc Kupper 3/4/82 * * * * Date Programmer Description * * * * 12 30 82 Marc Firs * * 8 31 82 Marc Changed TRACKS in HD driver to HDTRAK * * 8 27 82 Marc Added code/system length checker * * 8 27 8 the cold and warm boot loaders to * * work. Be sure to format all new system diskettes with * * 1024 byte sectors. The syook like a label * * 9 27 82 Marc Changed the login messages to say M5, M10, ... * * 9 27 82 Marc Redefined the dparam tabpy disk controller with 8 and 5 1/4 inch disks. * * DJ 2D/B floppy disk controller with 8 inch disks. * * * * Consol82 Marc Added character redirection code for the IOBYTE * * 11 1 82 Marc Changed serial i/o entry names to IOBYTE names * *xed bad map error return in GETBAD * **11 20 82 Marc Public release of revision E.31 * * 11 19 82 Marc Changed HDC3 equat2 Marc mwreset save/restores the track number * * 8 26 82 Marc mwreset now sets *step and *dir for CMI * * 8 20 82 Marc stem diskette can be either * * single or double sided. The sector size on normal (non * * A: drive) diskettes is not restrle structure * * 9 22 82 Marc Added a serial console for the Switchboard * * 9 22 82 Marc Added initialization code for se I/O: * * Disk Jockey 2D/B serial. * * Disk Jockey DMA serial. * * Multi I/O serial. * * Decision I se 10 18 82 Marc Fixed SETHIGH for 2 sided DJDMA 8 inch disks * * 10 18 82 Marc Deleted the HyType drivers * **10 1 82 Marce to HDCA * * 11 19 82 Marc Changed blank IO routines from RET to JMP $ * * 11 19 82 Marc Converted BIOSLN to a byte value Added 'equ'ed handshaking to the serial LST: * * 8 19 82 Marc Removed clock switching code from HDCA driver * * 8 18 82 Maicted. Thus if you have * * a diskette with software that is supposed to run on the * * A: drive then you should mount the derial group 2 * * 9 22 82 Marc Added sector size byte to the HDCA DPB's * * 9 22 82 Marc Added sector size parameter to DPrial. * * * * Printer I/O: * * Multi I/O serial with handshaking. * * Multi I/O Diablo 1620 simulato Public release of revision E.3 * * 9 29 82 Marc 40H now points to the HDDMA command channel * * 9 28 82 Marc MW's now  rc Added handshake configuration code * * 8 18 82 Marc Added handshake configuration bytes * * 8 18 82 Marc Removed 'eqioning (again) * * 5 13 82 Marc Fixed illegal MAC labels * * 5 11 82 Marc Fixed North Star drive configurations * * HD a bit * * 6 30 82 Marc Fixed MF multi density problems * * 6 29 82 Marc Added Olivetti HD561/1 HD561/2 drives * * nd 1012 drives * * *3 1 82 Marc Public release of revision E.2 * * 2 -- 82 Marc Pre-release testing and debugging * *rity on conout to clear up glitches * * 8 6 82 Marc Fixed the 8 inch dpb256ss DPB's EXM * * 8 6 82 Marc Increased the Hgate ST412 drive * * 4 6 82 Marc Moved serial LST: device to port 2 * * 4 1 82 Marc Added common group select routineu'ed handshaking from LST: * * 8 12 82 Marc Added configuration entries for a0 & d0 * * 8 11 82 Marc Added the autostart 4 30 82 Marc Fixed Quantum Q2040 tracks to 512 * * 4 29 82 Marc Fixed ST412 step constant to 0 * * 4 26 82 Marc Added 6 28 82 Marc Added a MW error reporter * * 6 18 82 Marc Added nonstandard system mode flag * * 6 17 82 Marc Added a b 2 1 82 Les + Marc Initial coding of revision E * * * ************************************************************D capacities slightly * * 8 6 82 Marc Deleted all non-supported MW drives * * 8 6 82 Marc Deleted call to flush in cons * * 4 1 82 Marc Fixed Diablo HyType II initialization * * 4 1 82 Marc Fixed LISTST for PROM driver * * 3 16 82 M command structure * * 8 11 82 Marc Redefined the configuration table * * 8 11 82 Marc Added DJDMA drive parameter table unallocated writing * * 4 22 82 Marc Fixed HD partition overlap * * 4 20 82 Marc Started testing and debugging of E.3uffer error flag * * 6 17 82 Marc Added save/restore of 50-52 to MW driver * * 6 17 82 Marc Fixed Centronics drivers ************** title 'CBIOS Revision E for CP/M Version 2.2 - March 4, 1982' revnum equ 53 ;CBIOS revision number 5.x = Eout * * 8 6 82 Marc Moved printer back to port 3 * * 7 28 82 Marc Moved conin flush call to conout * * 7 27 82 Mararc Added Tandon TM602 and TM603 drives * * 3 16 82 Marc Use 'part number' equates for MW drives * * 3 15 82 Marc Dropp * * 8 9 82 Marc Added clock switching to HDCA code * * 8 9 82 Marc Added seek complete clearing in HDCA * * 8 6 8 * * 4 19 82 Marc Added 1 sector to HD warm boot loader * * 4 19 82 Marc Added mod. number to CBIOS rev. number * * 4 * 6 7 82 Marc Fixed allocation map sizes * * 6 7 82 Marc Fixed MW partitioning * * 6 7 82 Marc Fixed HD partit cpmrev equ 22 ;CP/M revision number 2.2 ************************************************************************* * c Fixed double sided head settle time * * 7 14 82 Marc Optimized MWissue * * 7 14 82 Marc Clean up login message for ed hdrev and mwrev equates * * 3 15 82 Marc Seagate ST506 head settle is 0 ms. * * 3 15 82 Marc Added MiniScribe 1006 a2 Marc Added buffer disable on home * * 8 6 82 Marc Fixed 8250 UART initialization sequence * * 8 6 82 Marc Strip pa 19 82 Marc Clean up login message 'if's * * 4 15 82 Marc Fixed MCR Initialization for LST: * * 4 15 82 Marc Added Sea   * * The following flags set a 'non-standard' system mode and an * * assembly time debugger. * * * * If this number of HDDMA hard disks maxfd equ 4 ;Set to number of 2D/B floppies maxdm equ 0 ;Set to number of DJ DMA floppies 8 inch***** msize equ 48 ;Memory size of target CP/M biosln equ 10h ;BIOS length. Also in ABOOT&.ASM ********************* * * * * One is the so called 'standard partitioning' where we try to * * create as many 8 megabyte partitionould not * * affect the resulting code in any way. * * * *******************************************************12 cm5619 equ 0 ;CMI CM-5619 wmdrive equ 0 ;Device to warm boot from. This is the ; CP/M logical drive number. i CBIOS is used with the CP/M 2.2 system that is shipped on * * a Morrow Designs diskette then NOSTAND can be set to 1. This * maxmf equ 0 ;Set to number of DJ DMA floppies 5 1/4 inch hdorder equ 0 ;Set the order of logical drives ELSE 0 if mworde**************************************************** * * * The following equates set up the disk systems to be includes as possible plus a small * * partition to take up the slack on the end of the drive. * * * * Another way the driv****************** nostand equ 1 ;Set to 1 for non-standard mode debug equ 0 ;Set to 1 for debugging mode *************f maxmw ne 0 ;Only HDDMA drives use the bad map badsiz equ 32 ;Number of badmap entries else badsiz equ 1 ;Leave one entry * will allow the CBIOS to use various data areas found inside of * * the CP/M 2.2 BDOS. If the CBIOS is used with a differenr equ 0 ; not included. fdorder equ 1 dmorder equ 0 mforder equ 0 ;HDCA controller disk drives. Set only one m10f equ d * * along with the types of drives and the logical order of the * * drives. * * * ***********************es are partitioned is the so called 'even * * partition' formula. This means that the drive is split into * * equale sized ************************************************************ * * * The following is set to the memory size of the CP/M as filler endif ************************************************************************* * * * Since most hard t * * operating system then NOSTAND should be set to 0. * * * * The DEBUG flag merely causes various internal valu0 ;Fujitsu M2301B m20 equ 0 ;Fujitsu M2302B m26 equ 0 ;Shugart SA4000 m10m equ 0 ;Memorex ;HDDMA controller disk d************************************************** maxhd equ 0 ;Set to number of HDCA hard disk drives maxmw equ 0 ;Set topartitions with the only restriction being that no * * partition be over 8 megabytes in length. * * * * All hard d the CBIOS is * * being created for. * * * ********************************************************************disk drives hold more than 8 megabytes we * * partition the drive. We partition our drives using two different * * formulas.es and * * addresses to be printed during the assembly process. This * * printing is forced via assembly errors and thus shrives. Set only one mwquiet equ 0 ;Set for no names printed on login st506 equ 0 ;Seagate ST-506 st412 equ 0 ;Seagate ST-4  isk drives shipped from Morrow Designs are partitioned * * using the standard partition formula. If the user wishes to * * il, no protocol. * * 3 Multio serial, Clear To Send protocol. * * 4 Multio serial, Data Set Ready protocol. * * 5 Multiet CBAUD to the divisor latch value for the console. For an * * explanation of the values look at the DEFCON table. * * *** multr3 equ 0 ;0 = Decision, 1 = Multi I/O rev. 3 or 4 congrp equ 1 ;Cosole port (1 = p1, 2 = p2, 3 = p3) lstgrp e****************************************************** ********************************************************************** lsttyp equ 3 lbaud equ 12 ************************************************************************* * * * The nexmplement even partitioning then he/she must set HDPART or MWPART * * to the number of partitions desired. * * * *o serial, Xon/Xoff protocol. * * * * Note: The Decision board is functionally identical to the Multi * * I/O board f * ************************************************************************* contyp equ 2 cbaud equ 6 *************qu 3 ;Printer port (1 = p1, 2 = p2, 3 = p3) ************************************************************************* * *** * * * Define the console driver to be used. * * * * CONTYP is: 0 Nothing, used for patching to PROM't equate determines if you have a Multi I/O Rev 3 or a * * Decision I mother board for parallel i/o. If are not using * * e************************************************************************ hdpart equ 0 ;Set to number of non standard partitior serial printer I/O. Selections 2 to 5 will * * work on the Wunderbuss i/o board. To use drivers 6 or 7 * * the MULTR3 equ************************************************************ * * * Define the printer driver to be used. * *  * * The following equates are internal to the CBIOS. * * * ***************************************************s. * * 1 Provide for 128 bytes of patch space. * * 2 Multi I/O or Decision I driver. * * 3 2D/B driver. * * 4 DJither of these boards then you need not worry about this equate. * * If you are using a Multi I/O rev. other than 3.x or 4.x tons mwpart equ 0 ;Set to number of non standard partitions ****************************************************************ate will have to be set. * * * * Set pbaud to the divisor latch value for the printer. For an * * explanation of * * LSTTYP is: 0 Nothing, used for patching to PROM's. * * 1 Provide for 128 bytes of patch space. * * 2 Multio seria********************** m10 equ m10f or m10m if hdpart ne 0 ;Use non standard partitions hdlog equ hdpart else hdlogDMA serial port * * 5 Switchboard serial port * * 6 North Star motherboard (2 serial + 1 parallel) * * * * Shen you * * should set MULTR3 to 0. * * * ******************************************************************************* * * * The following equates define the console and printer environments. * * * ******************* the values see the deflst table. * * * *************************************************************************   equ m10*2+m20*3+m26*3 ;Logical disks per drive for HDCA endif if mwpart ne 0 ;Use non standard partitions mwlog equ mwp ;Origin of Disk Jockey PROM endif ************************************************************************* * * ult buffer address tpa equ 100h ;Transient memory iobyte equ 3 ;IOBYTE location wbot equ 0 ;Warm boot jump address entry ********** dpbgen macro nam,log,dspt,dbsh,dblm,dexm,ddsm,ddrm,dal0,dal1,dcks,doff,ssiz dpb&nam&log equ $ dw dspt db dbsh*************************************************************** ccpln equ 800h bdosln equ 0e00h size equ (msize*1024) cc;Form Feed acr equ 'M'-64 ;Carriage return xon equ 'Q'-64 ;Xon character xoff equ 'S'-64 ;Xoff character aesc equ 1bh ;Eart else mwlog set st506+st412*2++cm5619*2 ;Logical disks per drive for HDDMA endif hdca equ m26 or m20 or m10 ;HDCA co * The following are internal Cbios equates. Most are misc. constants. * * * *****************************************equ 5 ;BDOS entry jump address if nostand ne 0 cblock equ bios-19h ;Current actual block# * blkmsk ;Used for unalloca db dblm db dexm dw ddsm dw ddrm db dal0 db dal1 dw dcks dw doff db ssiz endm dphgen macro nam,log,dpb1,dp equ size-(biosln*100h+ccpln+bdosln) bdos equ ccp+ccpln bios equ ccp+ccpln+bdosln offsetc equ 2100h-bios ;Offset for sysgescape character ars equ 1eh ;RS character aus equ 1fh ;US character asp equ ' ' ;Space adel equ 7fh ;Delete *********ntroller fujitsu equ m20 or m10f hdspt equ 32*m26+21*m20+21*m10 ;Sectors per track hdma set st506 or st412 or cm5619 ;HD ******************************** retries equ 10 ;Max retries on disk i/o before error clear equ 'Z'-64 ;Clear screen on anted writting endif ***************************************************************** * * * DJ2D/B prom code base apb2 dph&nam&log equ $ dw 0 dw 0,0,0 dw dirbuf dw &dpb1&dpb2 dw csv&nam&log dw alv&nam&log endm alloc macro namn if debug dbgtmp set offsetc ;DDT offset ! dbgtmp set ccp ;CCP address ! dbgtmp set bdos ;BDOS addres**************************************************************** * * * The following are the macros used in generatingDMA controller mwspt equ 9 ;Sectors per track maxlog equ (maxhd*hdlog)+(maxmw*mwlog)+maxfd+maxdm+maxmf *************** ADM 3 anul equ 0 ;Null aetx equ 'C'-64 ;ETX character aack equ 'F'-64 ;ACK character abel equ 'G'-64 ;Bell abs equ 'ddress. * * * ***************************************************************** if maxfd ne 0 fdorig equ 0f800h,log,al,cs csv&nam&log: ds cs alv&nam&log: ds al endm *******************************************************************s ! dbgtmp set bios ;CBIOS address ! endif cdisk equ 4 ;Address of last logged disk buff equ 80h ;Defa the DPH, DPB and * * allocation tables. * * * ************************************************************************************************************************* * * * CP/M system equates. * * * **********H'-64 ;Back Space aht equ 'I'-64 ;Horizontal tab alf equ 'J'-64 ;Line feed avt equ 'K'-64 ;Vertical tab aff equ 'L'-64  ****** * * * The following marco is used in generating the logical order of the * * CP/M drives. * * nter cin: jmp $ ;Console input PROM pointer cout: jmp $ ;Console output PROM pointer endif if (lsttyp ne 0) or (contyple below must remain in the same order, the routines * * may be changed, but the function executed must be the same. * * on table. * * * ************************************************************************* drconf: db 0 ;Revis**************************************** d$wboot equ 0 ;Warm boot d$stran equ 1 ;Sector translation d$sel1 equ 2 ;Drive seless jmp read ;Read the disk jmp write ;Write the disk if lsttyp ne 0 jmp lstost ;List device status else jmp do* ************************************************************************* order macro num if num eq hdorder dw hddst  eq 6) pout: jmp lstout ;List device output else pout: jmp cout ;List device output endif if contyp eq 6 ;North Star * ************************************************************************* org bios ;Cbios starting address jmp cion 0 structure db 32 ;32 bytes long now ************************************************************************* * ect, Return DPH d$sel2 equ 3 ;Drive select d$home equ 4 ;Home drive d$strk equ 5 ;Set track d$ssec equ 6 ;Set sector d$sdmanop ;List device status endif jmp sectran ;Sector translation ; ; The following jumps are extended BIOS calls define endif if num eq mworder dw mwdst endif if num eq fdorder dw fddst endif if num eq dmorder dw dmdst endi drivers have punch entry points jmp punout ;Punch device output else jmp cout ;Use console I/O endif if contyp eqboot ;Cold boot entry point wboote: jmp wboot ;Warm boot entry point if contyp ne 0 const: jmp conist ;Console status r * * The following is the table of pointers to the Device * * Specification Tables. The order of this table defines the  equ 7 ;Set DMA address d$read equ 8 ;Read a physical sector d$write equ 9 ;Write a physical sector d$bad equ 10 ;Return poind by Morrow Designs ; if maxfd ne 0 jmp fdsel ;Hookup for SINGLE.COM program else jmp donop endif jmp 0 ;End f if num eq mforder dw mfdst endif endm *************************************************************************  6 ;North Star drivers have reader entry points jmp rdrin ;Reader device input else jmp cin ;Use console I/O endif outine cin: jmp conin ;Console input cout: jmp costrp ;Console output else const: jmp $ ;Console status routine PROM poi * * logical order of the CP/M drives. * * * ********************************************************************ter to bad sector info ************************************************************************* * * * The jump tabof the jump table ************************************************************************* * * * Drive configurati* * * The folloing are offset numbers of Device Specification Tables. * * * ********************************* jmp home ;Home drive jmp setdrv ;Select disk jmp settrk ;Set track jmp setsec ;Set sector jmp setdma ;Set DMA addr  ***** dsttab: equ $ dn set 1 rept 16 order %dn dn set dn+1 endm ************************************************group ;Get group byte * * ori bank ;Set the bank bit * * sta group ;Save new group setting * * ori group2 ;Select  stays consistant throughout the Cbios. * * Only the group bits themselves (bits 0 and 1) should be changed * * as you outpung * * protocall used by the serial list drivers with the Multio or * * Wunderbuss I/O boards. The first of these two bytes  * * The first two bytes show the I/O configuration that the CBIOS was * * assembled with. These bytes are used by exnd the decimal * * value needed for the defcon or deflst words. * * * * Baud rate defcon/deflst Baud rate defcon/d************************* * * * I/O configuration table. * * * * At this CBIOS revision 11 bytes are desecond serial port * * out grpsel ;Select the desired group * * * * Note: You should not set the group bits themset to the group port. If you modify one of the other * * bits (such as driver-enable) then you should modify the same bit * * is a mask. * * This mask is ANDed with the 8250's MODEM Status Register to strip * * out the desired handshake lines. Next tternal software to * * determine the configuration options that are available. * * * * The next byte is the initialeflst * * 50 2304 2000 58 * * 75 1536 2400 48 * * 110 1047 3600 32 * * 134.5 857 4800 24 fined for this table. * * Several extensive changes are planned for the table. Future * * revision of the IOCONF table willlves in the * * group byte. * * * * * * The following two words define the default baud rates for thein this byte. For example: * * * * ;Select console group * * lda group ;Get group byte * * ori congrphe result of the ANDing * * is XORed with the second of the two bytes. This XORing allows * * the handshake lines to be inver IOBYTE value. This value is written * * to location 3 on cold boots. See the CP/M 2 alternation guide * * for a description * * 150 768 7200 16 * * 300 384 9600 12 * * 600 192 19200 6 * * 1200 96 38400 3 * have independant entries for * * three serial ports and will be used by several character drivers. * * Also the IOBYTE will b * * console and the list devices. These words are provided so that * * the user can easily modify them and that they will a ;Select the console port * * out grpsel ;Select the group * * * * ;Modify a bit in the group byte * * lda ted. Common byte values are * * shown below. * * * * cts equ 10h ;Clear To Send status mask * * * of the IOBYTE. * * * * The next byte is to make sure that the group select byte on the * * Mult I/O or Decsion I * 1800 64 56000 2 * * * * * * The next two bytes are ued to configure the hardware handshakie implemented for all the character * * drivers. I might even write an external program to edit this * * table. * *lso be used * * in the future by Morrow Designs software. * * * * The following is a list of possible baud rates a  * db cts ;Morrow Designs 'Clear To Send' * * db 0 * * * * db cts ;Inverted Clear To Send * * db cts o * * the DJDMA floppy disk controller. There is one entry for each of * * the the eight drive that the controller can addreson flag endif if lsttyp eq 3 ;Clear To Send protocol lstand: db cts ;Serial list handshake mask lstxor: db 0 ;Serial lcomended stepping delay times * * 34.1. Example. Shugart SA 850's step at 3 * * milliseond inte ioconf: db 2 ;Revision 2 structure db 11 ;11 bytes long now db contyp ;Console device driver number db lsttyp ;Liscks and * * most 5 1/4 inch drives have 35 or 40 tracks. * * * * config This a a flag byte that indic * * * * db 0 ;No handshaking * * db 0ffh * * * * * * The last byte in the revision ons. The first * * four entries are for the 8 inch drives and the last four are for * * the 5 1/4 inch drives. Users with fastist inversion flag endif if lsttyp eq 4 ;Data Set Ready protocol lstand: db dsr ;Serial list handshake mask lstxor: db rvals. The step constant would be * * 3 * 43.1 or 102. * * * * rfu The next two words are reservedt device drive number iobyt equ $ ;The initial IOBYTE is kept here db 00$00$00$00b ;All devices go to CON: group: db 0 ates as to whether * * or not this drive has been configured. Set to * * 0 to force reconfigurae structure is the last character * * that was recieved from the printer. This byte is used to * * implement Xon/Xoff softwa stepping 8 inch drives * * (SA850/1) or slow 5 1/4 inch drives (SA400) should adjust this * * table for optimal device perfor0 ;Serial list inversion flag endif lastch: db xon ;Last character recieved from the printer ************************* for future use. * * They must be zero. * * * * settle This word is similar to the previously defined * *  ;Group byte defcon: dw cbaud ;Console baud rate divisor value deflst: dw lbaud ;Printer baud rate divisor value if (lsttion. * * * * step This word contains the stepping rate constant. * * The DJDMA's delay routines tre handshaking. This handshaking * * protocol should not bother printers that have not implemented * * Xon/Xoff protocol somace. * * * * Each table entry contains four fixed length fields. The fields * * are defined as follows: * ************************************************ * * * The following table are drive parameters for drives connected t step word. This specifies the head settle timing * * after the heads have been stepped. Example, * typ ne 3) and (lsttyp ne 4) ;Xon/Xoff protocol lstand: db 0 ;Serial list handshake mask lstxor: db 0ffh ;Serial list inversiick 34.1 times per * * millisecond. Thus the step constant would be the * * drive manufactors re this driver is enabled all the time. * * * ************************************************************************* * * * tracks This byte contains the number of tracks on the * * drive. Most 8 inch drives have 77 tra  * Shugart's SA 850 head settle time is 15 * * milliseconds. The settle constant would be 15 * *y||PF<2(z{ *z);*)&,,d-D.s)%%'i')1+%+Q+3)NEXT without FORSyntax errorRETURN without GOSUBOut of DATAIllegal functHAIιELETŪATI͆EFSTҭEFINԮEFSNǯEFDB̰EƘLSŢNāRASŦDIԧRROҨRRX O/QO҂IELILERIOTωO TωOSUEEX, Note: Caution should be used when defining the drive parameters. * * Incorrect definations may damage the floppy disk drive. ready exists??Disk fullInput past endBad record numberBad file name?Direct statement in fileToo many files * 34.1 or 512. * * * * An assembler macro (dconf) has been provided to assist in * * generatingion callOverflowOut of memoryUndefined line numberSubscript out of rangeDuplicate DefinitionDivision by zeroIllegal direcNPUԅƋNSTNNMNKEYILPRINԞLISԟPOEԈINűOASEISԓO O0EEFTO1ERGOKI2KS3KD4IDEXԃUL̖AMEהÌ]z))DEc9@gQC}DE CsD +"]D  $ |D}DDD<|""XL{LL{PtM=$$pP8`@`  the dparam table. This macros parameters are the * * number of tracks, the step rate in milliseconds, and the head * * settType mismatchOut of string spaceString too longString formula too complexCan't continueUndefined user functionNo RESUMEOPEοUԝΕCTPTIOκRINԑUOKřOEEETURΎEAćUΊESTORŌE͏ESUMũSEIGHTNENUͬESEANDOMIZŻTOАWAХAVPCTEYXTZZSR\SZeXY{TzTSYHIyII|(*g(678&+7y8919JHFIHH"+IFFz)) *m*zQ}QQU@VX:tle time in milliseconds. For example: * * * * ;Shugart SA 850 * * dconf 77, 3, 15 ;77 tracks, 3 ms step, 1RESUME without errorUnprintable errorMissing operandLine buffer overflow??FOR Without NEXT??WHILE without WENDWEND witGQI TRTRINGPACEYSTEͽHEROΣROFƤABA SINSAARPTIDTȡAIԗHILŴENĵRITŷO۾yVaQdQgQ;LM$Xq"9BLdhiUTϫNBTSLOSONԚLEAҒINSNDBV+V,V-O HRAL̶OMMO5 ms settle * * * * ;Shugart SA 400 * * dconf 35, 40, 10 ;35 tracks, 40 ms step, 10 ms settle * * * *hout WHILEFIELD overflowInternal errorBad file numberFile not foundBad file modeFile already open?Disk I/O errorFile al 0o.o%~ Ҡ ʠ ʠ> :i <ʩ=m+~ ʬ ʬ ʬ#>d2 ͋9C" :g ͬ! (" !9T  +V+^##m?>HjZEڗ;;>ʸ;>HOZ#þGO TOUBZ!AO ^#V#ZOd#<~ #####u   =>C,* =( |" 2 " â ~,dC+͆(~ʕ *n <1>DA2MSB!E :* > @(K 2 Ç 2 *  C " :b ʢ >(Kڢ s#=~,V  ~.* +3 *n 2l +!Cdbk))0_C7Ct šR;CÔ* C" B* *Cd Nz)~S ͒(q)ʹ(QZ~>r)ʹ(E(OdG+y(!!!Z.!>dG>Y2i Y%=+ZOiMk֢ύ>2i W„€€l>2á Q+!B>ee,%;d)1F6 * 4TF* ::G<:?<=ʢ (ͬ~ ̾(" ҊSe]" ;5$ܢ"ʇ: \*v " * ͶB" t##s#r## w#B(*>3Ø(:l  *j #*C > 2 ,$`i P "  "!>:yHG+ȸ#" in Ok Break!9~#b  T N#F#`izv C T  $* "* 3àE3\B" !9" ~: #~#ʅ #^#V": >[@1>]@ցLO! Y>5W>Y{~.ʧ:"0":i ~O.O>Y(ͬ}Y|Y%~.ͬ:g * |>}e. =:G<:e ?=!B&Gá(* TF~\:I:G<:\V:G:e \!B\/V tz|TF y}ͯ!6"*" 7C*"* "â *bk~####~ ҷ ڷù#s#rïC *DM~#<֌W-͋9C" :g G:g x=ͬ:g  H * #^#V*Cs* C{! C{>HͣFH *|<ʗ :  D=96543>7@?2C: * "   *" 2 2 |< "  * N#F#~: ҆ ځ#:l `#2l f>R~#"j &o"n >2m !~##"j +fC͎*j <2m n G("j !Y! d! ~Y#=%iʎ%à&O[H> K> Yi>: y +=2i ZY#ZEo:ҋ›:::o<ʛ& ,C)+(* TF~:::e /<!B{= @è2go"C#ʧQH+##~#foC`i~#fo??2i 2h ;#~=!@}O|G!""y O:h ~ʂ#Y:aJg>2h 2i U%~|*O~#Y(µC(zʢPY" : {:_ u ~GC+K x),  <2~(z˜<* * "C{K2* " * |< " " * |! 4 4 5wY2B!{DP 2R U >(_#U * ~?o !P #GC!BʻY| 0?<=:l ҫ ګ*n ¨###^#V,:m 2g *n " *p " !n (E AOGEAGx-?Redo from start #~ "4N: !!#G* Q!a ;#YHL">2>2 F~>2 ͋9:g " " ͬB!9(:g * ~)C,* C,Á2N 2g !9(!9.,:g G:N Od}![Eҗ:0ÞG7))))o~ +8  )))0O í)#~ց(7>OyC,;*/#,#BK/#C,/#C,( z`iC[# !C^#Vzn#~#+K#͑#^#Vzʌ#KG* W " Ð)͙(6Çz)uÇxdd!BdX* \FÇy2h :g g+Wx! _!A!_.!!!/!: -!<-!> >2 { =! ! <~J!#~#X! k*l!~#>l!+!:G@ #T]~u!#,2 ÓC;&G: ʫ>?@> @0KDů2 6,+>2 ͉:~+[(# "4([])P O:* * C)>" : OBO/2  N#fi-++<(aZz)}/o|/g" :g q7xz)z #s#r u# 2 *+#~##^#Vʚ#O: y$#¦#¦#3z##£#3 > %$B!$#G11+(zOxdz o! N#F* *(" " ͩ( *!:h og~#fox(2g 6" ;)!A͙(*ʹ(" "y!~v!ʏ!y_¢!: >2 ÷![®!2 !: >2 !> XG{!~#_XG!!2 E0:?+͎ " o, ~,B>2 d: =Bd̨H+~,ʿ+N6,E* 2 QC,͋9~,c: 2 TF—Qd¢WG"ʌ:ͣFG* T]##N#F! * +" |2 !O ,w# x»*#| C>2 OÐ9~ #~#`J x 2b ,{ʨ+F•{o|P {o|<«{o|2¸{/o|/}//o|//}o|g,::e !#*j +p+q+w: Ò#CBCACSCE: * * C ~0  2 <2 ~̓$# i*͙(*g' .EJ ]<=ʓ<"FO&i:* ,C(#r PQ6 r6*n )1:l O " H*">&{:m ;"!;"#~ ̾(~#m":m A" ^".h"Dh"EA"A"{v"*j  Wʉ:,+FO: y!...+ʽ,G+M: C#~# #^#V" cCb + C,u W : u 2_H 2u 2_H 2H /<z)zu 2 2 C,u Y +:n O!t C"s#rs#r~(͋9~)C,D:g " ~#fo| ~(" * C(y$\Aʔ$z)ð$!$#G KD#~.~•$z)"j87Random number seed (-32768 to 32767)$*" +%%$͉:C)|)IoBI'UTC)}* k(͋9" d(~a{_&([OʭH¬#~5$Ҕ"T]C!E #G!* C¦"`i" "\]~"\]C,u "z)d: E()È% PXC(+B͓2 " * ~" ڎ_4:g {[H !xVzʬQںzʺ! :g  N#F#N#F! N#F#N#F{>2e]!"N#F#xʇ TFQBN#F#Cچ " 1~ > @ !b !BÑ ~ͥB# b 2 e] #~  %#~#Y #^#V" y~.%$$$$$%** "͋9+%c%C,+8%": 2 2 ! 6ͷ(+ʚ+*͙(*'x)*t(| ++DM!>+ +7>{_zW}o|g=+w+|G+|)Ooyg)* +| )(! 6(&,)Ü)y%: 2 : B*: ½)))|/g}/o)! : )B*" >2g )aj)d* ʹ)O |0" .y*750t$)20.(H0 0**Ͳ.(T(**&, 0͙(T(È%{ b00_X/! dw0: x0yÞ0'+~2'+~2'AOW_2'}o|gxG>?ұ'2'7y<=':'x'> $&{_zWyO)xG:'2'y”'! 5”'%>.! N#3.=-..! 5%! >5=.>! N#F#=(.>! p+q+=9.: ʔ0: %'44ʈ0͝.!7 qA>,?t.>,: <=,%ͷ(t(x: ʩ(Ң%/<͙(ͩ((gb&|! %B&#ʈ0.͉&#&G~_#~W#~ON&hcGy&JTeox%2 |&y%6*Y(ͨ+g{o)+! ~w! ~G+N (R,/<#Fwx+ B,F+N9(! G>w2 ! %-x,: 2 ,,4ʈ0(6*x(! F#&* 6*|UY(d *!" " >>)d GOW_ʹ((gf*>b&|5&N&z< dE(*t(̀*k(: Þ0: /Þ0y×0: !b"* |0! ~ʸ0=04*y$2e > ̓$> ̓$!  101(d0! 1(* |* "1CG.x'(}! Gx&(ƀwW'(w+E(/%g0ʹ(xڀ0G͈%! 4À0: : /<! Op#6%͆(d+ ! ~w͆(o! [-!0 Y-xb.! 5b.%y2 +6 ~q+¨.(+~ڈ0w&,4È0%3*j%>2 `h)~&i-.+.+/O&)zWyO%x\E#&! w%%x! 5&F#~怩Oé( 4Ç0~_#~W#~O! ~/woG}_}W}Oq&CZQd& oz…&y-OQ-,>,! -G: º,! Vwz# Ÿ,x’,%! Y-,x,! w%: ,! ~++w! 4#,4ʈ0+60 ! ->! dҦ* )! ~: ~B*6{y%! ~*O+~+¶*!*) *yʹ((+6+q*: O! >%-,2 Ñ,! ~5 !@ #G"G)Ͳ1F1Ͳ1416+͆(F16-k(#60: W:g 22һ1ͺ5! F : _ 1x*1{1Aqg)d E(* ||O(* * ͷ(" `i" ! ^#V#N#F# (:g Gw#(! ~7w?##wy7O! ((! ( d.ʆ/e /E5/l#/L#/q#/Q4/:g N/>N/~%ʓ/#ʤ/!ʥ/dN/De/ͮ/2S0e/_{_//i/k(d!W{&Ë&-yOzW{_xGÅ&$cCu͍M r5E(&1r'ʹ(>2 ͙(!&ͧ7͙(ͩ(!&ͧ7i'͙(T( 2 -# -~/w! Oyw#-q<-NsY+1-'- W~w+F-?-! C-~w# [-E(: %'͝.qʙ-#*!x"+>);)+ ;=+|G+y4+|Gz)*͙(,N0|)+DM!>)ډ+)q+ ډ+=c+|+xʟ1Eʟ1Dʟ101,1.¢1+60{ʫ1+6${+p2 ! 6 ͙(* * 2 f2E~2:101 #~1>DG1" `i xE(!N(E(y! y )#x+y+z+{z|O(@)}P(! ( E(!N(E(O! y#)+f)I)N(d* ')d e/ܮ/.!W'!z)e/ͮ/e/) *d.(.=d^'-.".&,!  " #~+N2-%20OxGN2#~ 2`xEC2y 1>2 S2|1;21" `i" ͩ(#W\4: 2Ë w: 82 t("~'͙(͍*ͅ%)8͈%͈%E(t(͈%t(: 82 !9͘7: 2 "~ʎ6))))Ÿ6y=ʟ6ʫ60:ڨ6 ʸ6ʊ6È6!t(͙(! 6ͦ(6)!r%>2 E(x+76ʗ0%yʹ(7: 7|<>!@1> @!b  ~#=GA"=[0A= A=_zW"=! =L=ʺ>O>>ʨ=1g= !>=#ʻ=>>=Ͳ4d4CO)Û45C)4;/Ã4/Ͳ4d4t#)46C)4=60#44560#=4{460̾("5+~0ʞ2.ľ(2d>"w#6+26-/</ 2:#p#w#6! #zQ334z4ͺ5{(=4b1Ie&X4#]I͙(8͙(ͩ(y8g'E(6t(: N9QYi'!%!X9͘7!8 J;xn{/|t1}=Z}~L~l+7͍*)|" " ܻ6t(ͽ&'8;': `7hr7͙(͍*Ɓc7ͅ%!{7ͧ7J'͙(: o7%~0é(|Yt >>(9>ʵ=6>>@!B<~ͥB#¨=!>7A_>~=ͥB܁>=#~== !B<~>\ͥB~>ͥB́> 6.#605#H56." #H 6,#dq5(! 6(&,*6> 5/>,K5>,p#=B5! ͦ(~5y%>B*ͩ(] " "f * >* C;^#~#¸;:g ¸;~;#^^#V#˜;:f DMW']< #:¹;#ʾ;+͸<þ;:g w#_ʖ8!i8ͦ(!H8Ȇw#O ͷ(=>\@~A +> +>+> +>>@ >wͥB# >6Hͨ=Aq>s> >s> ʑ>ʑ> ʑ> >>_‘>>_ʙ>ͥB+>>_6?5ʹ(/{_#zW#yO++Ғ5B&#ͩ(p#ڄ5>5e6>5N#F#* /}o|g5" p#=55w1_c<#OB##" q#:f y#<: O%<q#p#+=ROhFhiuh!8|%: ~7W'#~+w#Ã>yڡ>>@>> o&DM#͹BwͥB#Þ>x+>ͥB>x+~ͥB> !Bz\@@_W@W~#!ʎ@#ʡ?&ʉ@g@+>H?+~#.?_}@\&???$B**v {_zWME}_|W2 " ċ9" P ^#V#* C ~#~#Eͦ(: E! ͦ(|%(ͷ()/F####N#F" C* " " : T*++" ##!z "x r%DAgo" 2 "N " " 2 * |}~C##~:  *C(`i+" HW'ͫHG=O>x~#F#fh GN#^#VUJ LJ#7Jѯx<#4JIJC(͋9;*#^#V* CڍJ*C> @:e €A ڮA:G:e ʥA!BʮA<2e OTFAWMS: 0P:A!7C!E #G #* CGHů#^#V#DM* C`iC`i|+F+N+n& PY+DM* ͹Bq#p`i+jG* ͓;*~*  ͹FͬHͫHʚ?*??x#ڒ?~$> ž?#W?~#.?#ʡ?,?z@Wá?~#>.??# ?~##??T]^###xG#z+@x#^#Vi`: F* F1+:g  r+s^#V#3)ͷ(AF"i`Ü" * ~, ͨE*|ͥH~#N#FͬHW^#N#F{zد< < D T" !z "x !*}<-D" * " 2DAB!J b Æ >OD22>^@@@!B* | * "u <2>2ҍJͣF(C,u ~JͥHG!W'y~ @> @TF3B:?B2ɯ2e :=@FBAA2CDD͙BƒBʌB* ͓H͓H!F~#N#Fo,- ÜH;** HPYN* CHG " *x +F+N+C"x ͥHW~H#^#VͷFx * sF@~-@@>Wr@Cxz*1#G+7N@2 ;K@, ~#_~#foxE?m@@@?!BͫH@#rF?P(o6ÙFr6ÙF)1FͨHH~#2 ͋9D2 `i D * CD `i" ~,DgG* * >?@> @(KͿAzK68Kp22 ͿAoK!B!=:>\2UK'K@+iK~@K+@K@!B!b 2OAKAͷF_H!D " >2g :2@ > @+B> BC~ +üB*v  >ƕo>gB9*++"  BgGBBC(u C,C)d$Ix 'IH0Ix > {͹FGH* w#?IHIO>~XIx@r@;** AxxOI&G* 5@G> 5@@@z>+@TFfV:\A@:@27A >*x " >2g ( C"x ~ #FͨH͹( @ +B-G* * /O #CZG" # >G*v " !* !z *x C~A[?;C E, E+ EC, E*,4EyE+ʅEC,ʅEyE+ !NC҂E͗EڂE*  C҂E"v " E"z:ʐK>\@2yKCD7 ;L K ´K(KKCD(KK0K@> @>bKK>#iKK6!B!b K KxL* C:G!^#V#C T*}D2 2 2 w#w#" *+" : XC2 2 ! 6#QC7!i8(!F8w#w#w2 og" " *v : ƒCLI~IJPI=O~GCH_#~#foFr+.pC)Cd>Ix C,;*C,* C)ͥA> @:A 3A6A:<:-A!MA6A<2Oɯ2:> 7A> 7A2:XG{A:e ʍA=2e >îA AxGH!L " * " * * CʹG~###͚<²GH_ÕG* ^#Vz* G" ##^#V#" ÕG* C7H~###͚L!b ("_yq#@ K2e > @ͿA,L KzK: Bw!a >2 ;2 " $L33oL " ** áL ..ɷw#eRX͔R:2+ʾRC,CR 22!6"!C:2*""*#|,@ÇP>"@&G>"@íP*|Q~Q\}o|gQ> @+|ʻ !! {w:W}W!! ~!) ;WU;W~#>W*~ʖ\( ~hW+~#5O ~+~tWzWJW7>*T]::g W):zBK!N N 2 ~(nN ͖N+"N(NC)"NC,BN"* * C#ON##~w#͚< NO* "U>  U!Ux͹FFTC$C(u ~,KU*Qʠ "QC)}͹FʅU͙BlUA~Uw# ^UF*LL" *" ##^#V#~#fo"͆(ʵLA3à* "à!9~#L L~#foC L >2 ͋9d*  CVSHWw#S" : "]ͫ##" !~267C:2: 0P:ʇ àVC!CB͔R+mSMS 2Wڢ <ʠ <ʠ *P!B#*QѻQ  C,PY"+#x _:ڦ !N#F :Q!)^Q! >>>ͬ͹F* (H>>% N#F+q#p###6 ’WͱW: ͞Z>ªW>w+w!(HW7?*' 6#67ͥH~ʲ #^#fk_XN#~:X+ N* C Oy_xW `i" * CNO##~w#͚O #~(PY!' ůwͱW:!͞Zʻ =ʝ =UѯÚ <ʻ !% ^#(""  B!9 +" _MC(͋9s#r#~,=M #MC)" >!=_M=_M=_M!9DM!jM* * * à2 2 ~( 4â *|B ͖R+ʶSC,P\CAÉ ͒#e]>hV* *CMS~#hVSV:SS=S~,~#>ͥH<2g #~#fo(d ,»QZûQ Q͋9;*W_Wڬ Q¾Q"QG{,xQPXW1R!b Oz"yR QR RO{,+@bXy@bXbX #RX~.0X>X7X#X2 z bXbX> >X7X> WX7Xò W<ʣ !O~###͚yV!' ~UͱW)9V6Qʦ !&QV! ~+n6Qʦ ! ~*~Ee\DM'‡M2 #+͔R!" +NC,,ʸM"" +NC,MCACLCLNOC, 2 5$`i" NT]" Cu SůSѯ*Qʦ   ! ~#fo" !"o]| G~,r CACS͋9;*O*o] "o]* Cڸ q#s#r9T7͋9yĊRW1R R{ +R,> +R+R1R1R͊RWQ"2 : mS:2ùR2 2 * DM* " * #* " CNP `i" * *+zʠ `ià Q~U4N#V pʝVzw w+s#r#6#6DM:V!" s#r#6 W! {zVWw<W<NO**+#~#N#^#V"N:N2 ͉:ʢNxG͒;>2 hN~(nNþN~(͉:zNxGN;*ͥHF~O#^#VT*CT* CTY* * CUyYwwͱWoY<ʻ ÅY<…Y£y Microsoft Bytes freeBASIC-80 Rev. 5.21 [CP/M Version] Copyright 1977-1981 (C) by Microsoft Created: 28-Jul-81  ~šRÇ !?`2 "!"6:͗C2e " * ^#V"zB"UB"##^#V"A##^#V"A##^#V"=A 2!]!!"" !"22d 2 2 es are for the Disk Jockey DMA if wanted. * * * ***************************************************************** i}la)ҍ[#x"o]! "q]!) "s]!}o|gCڼ[bk:u]\C[ \DM*s]*q]X\"q]PY\*o]#"o]}o|g|Ÿ[d B PROM djram equ origin+400h ;Disk Jockey 2D Mod B routines tkzero equ origin+9h ;Track 0 seek trkset equ origin+0ch ; cY!%w#w#w#w~ʨYCzW* ) p# ®YC T T _W<Yʣ 2!"!" !z "x ! "L *"v >2!^" :^^<2^!~" ^F#~+w##D^+6" !^/x^+6"" #/x^i^^6Zf (maxdm ne 0) or (maxmf ne 0) djkick equ 0efh ;Kick port for DJDMA controller channl equ 50h if maxdm ne 0 ;8 inch bo \DM*q]*s]X\"q]PY[2*o]! ~#foCs#rG\:T\!T\!& äV~# xY\DM\ʓ\͹\! w!( Set track setsec equ origin+0fH ;Set sector setdma equ origin+12h ;Set DMA address dread equ origin+15h ;Read sector dmast eZ!6# ͖ZW2 !͒Z!͒Zʣ O!  ~#@ygZ~ dZ>.@ QZ:e W:ڀZ> @@S^Mʐ^F C:dʯ^z{2ô^"v +^C/}^C:d" ô^+*v +"v +:!]"2<s#r# * ot loader trkoff equ 22*128 ;Number of bytes loaded from track 0 else ;5 1/4 inch boot loader trkoff equ 9*512 ;Number oV6 ʎ\zwø \ʓ\͹\! ~!ô\! ^#V! s#rDMͱ\ͫ\C" ͒#\>;S"]C ** C!X9}o|gqu origin+24h ;Get DMA address status equ origin+27h ;Disk status dskerr equ origin+2ah ;Flash error light setden equ origin+!BAZ~*6?# –ZO!!4¶Z#4¶Z#4y"Zʻ ><+Z* C! s#r#wZ2 * * * The following equates are for the Disk Jockey 2D/B. * * * ******************************************** DM=^#"" {ozgB|g}o_|0_!{ozgB"v "" " *B}o|g++!_#G1!_#G!#G" !B! v] Owned bf bytes loaded from track 0 endif setdma equ 23h ;Set DMA address djhalt equ 25h ;Halt controller djbran equ 26h ;Bran!9}o|g ] \ \ ** C!9}o|g!X9}o|g S] )] )]*|<:  C*+6*2dh ;Set density endif ***************************************************************** * * * The following equatu]*Q  ! ^#V~,+ zʵ +s#r! w#w! ~#fo!CT[Ò[BK>!)g[)#h[))v[ u[#=][}_********************* if maxfd ne 0 ;note 'origin' equate moved to start of 'aboot' ;origin equ 0f800h ;Orgin of DJ 2D Mo ch controller command redtrk equ 29h ;Read track command endif ******************************************************** lxi b,10*100h+2 ;B = sector count, C = sector # call clodhd jmp cboot ;Go to CP/M endif clodhd push b ;Save sectort'ed data) ; 'cpsect' cannot be greater than 19 (system won't fit on a track if greater) ; cpsect set 11 + biosln / 2 - 1  dcr b ;Update error count jnz crhd ;Try again if not too many errors jmp $ ;Dynamic error halt hdread call hdprep ***************************************************************** * * * Cold Boot loader for a hard disk. * *  ;Continue reading ***************************************************************** * * * crdhd does the actual rea********* * * * Define the origin address for the various boot loaders. * * * ******************************** and count mov a,c ;Load sector sta hdsec lxi h,loaddr-200h ;Get DMA address (self modifying) cdmahd equ $-2 ;Storage fif cpsect gt 19 cpsect set 19 ;truncate cbios if needed endif lxi b,cpsect*100h+2 ;B = sector count, C = sector # call;Prepare the sector header image rc ;Error exit mvi a,rsect ;Read sector command out hdcmnd call process ;Process th * ***************************************************************** if (maxhd ne 0) or (maxmw ne 0) lxi sp,cstkhd ;Sed from the controller, the DMA * * address and sector # have already been set up. * * * ************************************************************** if maxhd ne 0 ;HDC3 boot equ bios+(biosln*100h)-512 ;Very last part of CP/M system endior previous DMA address if maxhd ne 0 lxi d,200h ;Offset to new DMA address else lxi d,400h endif dad d ;Add in of clodhd jmp cboot ;Go to CP/M else lxi h,boot+200h ;Copy part of CCP up lxi d,loaddr lxi b,200h movlop: mov a,m ;Gee read rc ;Error exit xra a ;Pointer to data buffer out hdcmnd mvi b,secln/4 ;Number of bytes to read lhld cdmahd t up stack at end of this sector if maxhd ne 0 ; ; note for 'cpsect': ; 11 = number of sectors (512 bytes) for ccp + bdo************************************ if maxhd ne 0 ;Low level HDC3 drivers crdhd lxi b,retries*100h+1 ;Maximum # of attemptf if maxmw ne 0 ;HDDMA boot equ 100h endif if maxfd ne 0 ;DJ2D/B boot equ djram+300h ;Upper 3/4 of on board floppy Rfset, HL = new DMA address shld cdmahd ;Save new DMA address call crdhd ;Attempt a read pop b ;Recover sector number ant a byte stax d ;Save it inx h ;Bump pointers inx d dcx b ;Bump counter mov a,b ;Test for end ora c jnz movlop;Get destination of data in hddata ;Two dummy data bytes in hddata rtloop in hddata ;Move four bytes mov m,a ;Byte ones ; biosln / 2 = number of sectors (512 bytes) for cbios ; -1 = make room so we don't overlay boot loader (we truncate uninis crhd push b ;Save error count call hdread ;Attempt the read pop b ;Restore the error count rnc ;Return if no errorAM endif if (maxdm ne 0) or (maxmf ne 0) ;DJDMA boot equ 80h endif offset equ 900h-boot ;DDT offset org boot d count ; B = count, C = number dcr b ;Update sector count rz ;All done ? inr c ;Bump sector number jmp clodhd   inx h in hddata ;Byte two mov m,a inx h in hddata ;Byte three mov m,a inx h in hddata ;Byte four mov m,a roller ani 7 ;3 bits of head select rlc ;Shove over to bits 2 - 4 rlc sta dmasel1 ;Save in command channel head seleAttempt the read pop b ;Restore the error count rnc ;Return if no error dcr b ;Update error count jnz crhd ;Try aga ;Get status ora a ;Set up CPU flags rm ;Return no error (carry reset) stc rnz ;Return error status xthl ;Wastea ;Form head byte out hddata ;Form track byte mvi a,0 ;Form sector byte hdsec equ $-1 out hddata mvi a,80h ;Form Kenot present mvi a,dmassta ;Sense status command sta dmaop rdychek call hdissue ani dready ;Check for drive ready jnz r inx h dcr b ;Update byte count jnz rtloop ret process in hdstat ;Wait for command to finish mov b,a ani opdone ct ret divspt mvi c,0 ;Clear head counter divsptx sui spt ;Subtract a tracks worth of sectors rc ;Return if all donein if not too many errors error jmp $ ;Dynamic error halt hdsetup shld dmadma ;Set up DMA address call hdreset ;Reset c some time xthl xthl xthl dcx d ;Bump timeout counter mov a,d ora e jnz hdiloop ;Loop if still busy stc ;Sety out hddata mvi a,dskclk ;Turn on Disk clock out hdcntl mvi a,wenabl ;Write enable on out hdcntl ret org boot+2dychek ;Loop if not ready lxi h,0ffffh shld dmastep ;Do recalibrate call hdissue lxi h,0 shld dmastep ;Clear step c jz process mvi a,dskclk ;Turn on Disk Clock out hdcntl in hdstat ani tmout ;Timed out ? stc rnz in hdreslt ani inr c ;Bump to next head jmp divsptx hdreset mvi a,(ret) ;One time code sta hdreset out reset ;Send reset pulse tontroller lda hdsec ;Set logical sector number dcr a ;Range is actaully 0-16 call divspt ;Figure out head number -> (c) error flag ret hdsec db 0 ;Currently selected sector dmachan equ $ ;Command channel area dmasel0 db 10h ;Drive sele00h-2 ;Last word on sector is load address cstkhd equ $ dw boot endif if maxmw ne 0 ;Low level HDDMA routines crdhd ounter shld dmarg0 ;Clear cylinder # shld dmarg3 ;Clear sector # + read disk command ret hdissue lxi h,dmastat ;Statu retry ;Any retries ? stc rnz xra a ;No error exit ret hdprep in hdstat ;Is Drive ready ? ani drvrdy stc rnzo controller lxi h,dmachan ;Address of command channel shld chan ;Default channel address xra a sta chan+2 ;Clear exte adi spt ;Make real sector number sta dmarg3 mov a,c sta dmarg2 ;Save head number cma ;Negative logic for the contct (step out, drive 0) dmastep dw 0 ;Relative step counter dmasel1 db 0 ;Head select dmadma dw 0 ;DMA address db 0 ;Extcall hdsetup ;Set up parameters lxi b,retries*100h+1 ;Maximum # of attempts crhd push b ;Save error count call hdissue ;s byte mvi m,0 out attn ;Start controller lxi d,0 ;Time out counter mov b,e ;Controller busy status hdiloop mov a,m  mvi a,isbuff ;Initialize pointer to header buffer out hdcmnd mvi a,null out hdfunc ;Select drive A xra a out hddatnded address byte xthl ;Wait for reset (around 10 uSEC's) xthl call hdissue ;Do load constants jc error ;Controller  ended address dmarg0 db 0 ;First argument dmarg1 db stepdly ;Second argument (stepping time) dmarg2 db headdly ;Third argu t1boot lxi h,cboot ;We jump to cboot next time shld exit mvi c,1 ;Select double density call setden xra a ;First 100h ;Memory address of sector - 100h newdma equ $-2 lxi d,100h ;Update DMA address secsiz equ $-2 dad d nowrp shld newdh,sectb0 ;Check for bad load lxi b,40ffh ;b = ok, c = loaded lxi d,endtbl-sectb0 ;Error count + # of sectors djloop: mov a********************* if maxfd ne 0 t0boot mvi a,5-2 ;First sector - 2 newsec equ $-1 inr a ;Update sector # inr a ******************** * * * Cold boot loader for the Disk Jockey DMA controller * * * ************************ment (Settle time) dmarg3 db sectsiz ;Fourth argument (Sector size) dmaop db dmalcon ;Operation code dmastat db 0 ;Controlsector - 2 sta newsec mvi a,8 ;Size of (logical) track + 1 sta trksiz dcr a ;Number of sectors to back up sta backupma ;Save the updated DMA address mov b,h mov c,l call setdma ;Set up the new DMA address lxi b,retries*100h+0;Maximum ,m ;Load sector code cmp c ;Check for 0ffh (already loaded) jz djcont ;Skip if load was 'ok' mov m,c ;Load 'loaded' fl cpi 27 ;Size of track in sectors + 1 trksiz equ $-1 jc nowrap ;Skip if not at end of track jnz t1boot ;Done with this t***************************************** if (maxdm ne 0) or (maxmf ne 0) ;Set up DJDMA loader mvi a,djbran ;Load branchler status byte dmalnk dw dmachan ;Link address to next command channel db 0 ;extended address org boot+200h cstkhd eq lxi h,loaddr+0700h ;DMA start address for first revolution - 2048 shld newdma lxi h,loaddr+0300h ;DMA start address for s# of errors, track # nxtrty equ $-2 fread push b call trkset ;Set up the proper track call dread ;Read the sector pop ag cmp b ;Check for 'ok' status jz djcont ;Skip if load ok inr m ;Make flag = 0 inr d ;Bump error counter djcont: drack exit equ $-2 sui 27-6 ;Back up to sector 6 backup equ $-1 lxi h,loaddr-80h ;Memory address of sector - 100h nxtdma  channel command sta channl lxi h,commnd ;Load new command channel address shld channl+1 xra a sta channl+3 djstrt:u $ ;Stack area at end of sector endif endif ***************************************************************** * econd revolution - 2048 shld nxtdma lxi h,2048 ;Difference between DMA addresses shld secsiz lxi h,retries*100h+1;Maximb jnc t0boot ;Continue if no error dcr b jnz fread ;Keep trying if error jmp dskerr ;Too many errors, flash the lightcr e ;Bump sector count inx h ;Bump table pointer jnz djloop mov a,d ;Check out error counter ora a jz cboot ;Starequ $-2 shld newdma nowrap sta newsec ;Save the updated sector # mov c,a call setsec ;Set up the sector lxi h,loaddr- out djkick ;Start controller djwait: lda djdone ;Get final status ora a ;0 = still busy jz djwait ;Loop if busy lxi  * * Cold boot loader for the Disk Jockey 2D Revision B controller * * * ********************************************um # of errors, track # shld nxtrty jmp t0boot ;Go load in track 1 endif ********************************************* t CP/M if no errors dcr m ;Drop retry counter jnz djstrt ;Retry load operation jmp $ ;Dynamic error halt commnd: db t Dis Jocke 2D/ firmware wil no functio properl i singl mode an MOVCPM.CO͠ becaus o memor relocnot load boot loader sectb1: dw 0, 0, 0, 0, 0 ;Load ten sectors db retries ;Retry counter endif endtbl equ $-1 ;e on tha th Dis Jocke 1Ġ boar ca read bu th Dis Jocke 2D/ canno (th DJ1Ġ doe no utiliz th 179 contrctb1 ;Sector table 1 db 0 ;Extended address db 0 ;Returned status db djhalt ;Halt controller djdone: db 0 ;Returneeratio o th 179 controlle chi (IMSA diskette i particula hav thi problem) Thi progra wil b o interessetdma ;Set DMA address dw loaddr-512 ;Start at CCP if micron eq 0 db 0 ;Extended address for CP/M else db 0ffh ;Wratio problems. T exi singl mode type: A>SINGLE E[RET] Thi wil retur th use t th standnd of table marker endif end olle chip) Essentially th REGE progra read complet trac o dat an forma informatio int memory filterd status org boot+5dh ;Boot + 5ch contains 'configuration byte' if maxdm ne 0 ;Booting from 8 inch drives sectb0: dw 0 t thos user wit th Morro Design Dis Jocke 2D/ Controlle only I i no intende fo us wit th Dis Jockap around from ffff00 to 000100 endif db redtrk ;Read track db 0 ;Track 0 db 0 ;Side 0 db 0 ;Drive 0 dw sectb0ar CP/ syste (Th "E argumen i fo End) Typin SINGL E whe no i singl mod wil repor a erro an retur  an o th amoun o dat t b transferred. I general an CP/ comman whic ca b use i regula mod ca b ou th formatting re- format th trac an the re-write th data Thi proces i repeate unti th whol disketffffh, 0ffffh ;Do not load boot loader dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;22 sectors to be loaded sectb1: dw 0, 0, 0, 0ff0e DM controller. Th REGEΠ progra i designe t b use wit diskette whic hav bee formatte incorrectl - no ;Sector table 0 db 0 ;Extended address db 0 ;Returned status db setdma ;Set DMA address dw loaddr+trkoff ;Load adwithou an chang bein made a wil typin SINGL S i alread i singl mode. REGEN Th REGEN.CO comman regen use whil i singl mode Ther ar tw exceptions however Th FORMT#.CO program becaus i make direc call t ha bee regenerated Th origina diskett i bot th sourc an destinatio diskette an mus therefor b wri0h ;First seven sectors db retries ;Retry counter else ;Booting from 5 1/5 inch drives sectb0: dw 0ffh, 0, 0, 0, 0;Do  wit diskette tha hav bee partiall destroyed A exampl o diskett tha coul b use wit th REGE progra idress for track 1 db 0 ;Extended address db redtrk ;Read track db 1 ;Track 1 db 0 ;Side 0 db 0 ;Drive 0 dw seerate CP/ singl densit diskette whic hav bee formatte i suc wa tha i i incompatibl wit th norma op t enabled. Th fina resul shoul b singl densit diskett tha i readabl bot o th machin tha origin221@:2!o6+6+6!6#6!6#6:G*o .!N6:^*M^!K6!6!6+6' :$ar dis controller. Th Morro Design MPZ8 CP car ha bot BOOTHĠ an BOOTM encode i it PROM Refe t thABORTED$BAD PARAMETER$INVALID USER NUMBER$RECORD TOO LONG$INVALID DIGIT$END OF FILE, CTL-Z?$CHECKSUM ERROR$CORRECT ERROR, TYPE Rall produce i a wel a o th Dis Jocke 2/B controller. Simpl typin REGEΠ wil invok thi program I ha (INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)::=2K  :ʤ\:ҷ\x'Ͳ:!\͢  :͈'!  MPZ8 manua fo th prope switc settings. ETURN OR CTL-Z$INVALID FORMAT$HEX$$$$NO DIRECTORY SPACE$NO FILE$COM$START NOT FOUND$QUIT NOT FOUND$CANNOT CLOSE DESTINATION FILEenoug prompt t explai it use. BOOTHD Th progra BOOTHD.CO contain boo stra loade fo th HDC har dis(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE):$: $͈Ͳ!N6' :!Cwͯ !6:^͢c!6{:/>!/H{ͯ :<2$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$$$$$$$NOT FOUND$COPYING -$REQUIRES CP/M 2.0 OR NEWER FOR OPERATION.$UNRECOGNI controller BOOTHD.CO coul b programme int PRO s tha yo coul boo directl ont th har disk withou  COPYRIGHT (C) 1979, DIGITAL RESEARCH, PIP VERS 1.8$$$ SUB =.:,<> _[]INPIRDPTRUR1UR2RDROUTLPTUL1PRNLSTPTPUP1UP2PUŠ ::=HҮͯ !6:Ҿ:2 !6::/H͈;!6:> !/>ZED DESTINATION$CANNOT WRITE$INVALID PIP FORMAT$CANNOT READ$INVALID SEPARATOR$1 :2L> ̈́M9 havin t bothe wit th floppies. BOOTMW Th progra BOOTMW.CO͠ contain boo stra loade fo th HDC/DM hNTTYCRTUC1CONNULEOFDISK READ ERROR$DISK WRITE ERROR$VERIFY ERROR$NOT A CHARACTER SINK$READER STOPPING $NOT A CHARACTER SOURCE$ HHͯ :^!w:<2:0}:@E}:!S!W6: z!]6:cm!c6:_z!_6l:!lwҙ  â :0O !q:O| :O| !6:]2l:o'2o:n'2n:m'2m*mMͣ *nMͣ *oMͣ :] :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*M> *N& N2 !p+q!6!6+6 !6: S: M!6g8:N2M*M8p!6!6!6>! !kp+q*j> >ڪ Þ !qp+q/ *pDM9: :M2r:N!r !:r *r& N!r4 !6:ͯ m!62m!62m!62m!62m'2:2:TҒ:2 ::,: HHҰͯ : 2ó:E:1:2v!q!*8!*6: >:   *}2D" * * *&"!q:UY: Y:ҩ: ʩ:_2ʘ:€!6<! ^#V͎ * :w*#" = = = = = ͯ  *M !6q  !6q  !6q  *& !ڕ*&P 6!4z!6!6#6#6!6*M8:ھ:*͇g2ê::¿::,͡A<2O>͔: :ͳ.!ws+p+q+p+q:w=2wN *s*u w*s#"s*u#"u' !"*M^7 !x6:!xھ **DM͆ !6*ME:2::Ҳ:<22ý: 2:} >ͯ :i:2:d*M:[ ͦ>ͦ!q:_  !p+q.*   !q*&!p+q*2:<2!ژ!6 >!]Ҥ; !6:Q::H: !6*M : !6!q:a/>z!6à  !6 à  !60à  *& !6  !6  !6  *& . 1 4 7 : = F P [ f q  *M8):[ͱ!N5!6ñ:5!6#6>!ڰ!6:<2O>/:!O!T *M͡H~K:2yʭ :yʗ ͯ *"*6:2x÷ *"!x4d !"/ !j}=2| !"*KM^'_ !z6:|!z1 **M:>!(:=2%> >>!F!5+N! ~2!4<2T>>!b}*bMͭz:b2!b6:<2é>!!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*/H:_2:!q:A/>Z!/H8: 2::=O>m:W!Q} Hmd>9>!6:2*M!E :2!q: " *M n :c4 *M n :2!c:Q !c:2: !:cw>!n !5 Y : { !6!q¡!6[–ͱ!N5:2:2!4=:[¼ͱ4:!6:.2O8: :* ͇g "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{&`ҥ*`MͭҞ!`6!6> :é:(!q:!wO! ~2*& :w>!:!4!6>:N<2N!!p+q* !q*& *M *M !p+q*!!p+q*"!p+q*$!6  ^#V͎ڗO **~2*#"m2m͖ 2m!6m!6m!6 m2m :[ ͱ!N5!6:%:<2*6 * 6å!q!6> !d*&I :]>!4A>:<2O* :w:?†:X!Wғä:ڤ*MEÓ:ұ@@:O2Mc;!6#6>!)*&P ~"::H:H :020:121'ͳ':²ͯ !G6!"!"7 *M^n/ :a/:H!6:ͯ !&69Ž>!6-e!6ͻ2=2ʺ-é:>>"ͻ2:!!5ͻ2ͬ!\DM!  ::=H-\:N2O_og_{ozg^#V))) _{ozg^#V) d^#V|g}o n_{o!6!q!6?!:ҠgÐ!q*&*~!6:22: :]Hں:A2O>: 2ͯ :H:H"!6!4:_jYO jM*"S*" 3@bl*M1͓!""2*">!b!ͯ >!`0ͯ !q:E:24J!46*}a!44EJ *KM^'́:‚-:>>!p+q:,!6*DM9:<!6:z 2W!6D*&L :w:<2Ov*:>=zgO{ozgi`N#Fogo&og H ©=¨÷:S:QHI:N<22: H@"2Í202O> c!6Í202O> ڍ*&O*7 *M^͆ \͔!":͎H*#"ͧÝ/ :>͛9ͯ .*#":_! !36'n::0:f9OY#9.3'ͳ.:020' 'ͳ'7 6'20O> ڒ:0:AO>Ҥ::A }}Hͬ!wͻO`idͻV[2O>2:!X!6:!& !sc*&P :w:·>!ұͯ :22:_!6=!6>'!E!4!p+q*0 !' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!j>A+!s!"@͓1!"<**"͓n "Dn"":!Q2҂:=O!L NE!4 E E:/.*&L 6$L9k9.Xͯ *KM^020r+s+p+q*~$7*>*>H&>*#"*#"> 2:R͎:!6!6=2:ʙ!6:“H!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈* NAME prl -- "page reelocatable" format DESCRIPTION Prl ("page relocatable") is a file format for relocatable objecte non-relocatable construct has been used. BUGS The load address must be on a page boundry (multiple of 256). arameters: 77 tracks, 8 ms step, 8 ms settle * * * ******************************************************************for each byte of code, beginning with the most significant bit of the map's first byte. A 1 bit indicates that the cor dconf macro tracks, step, settle db tracks ;Number of tracks db 0 ;Reset the calibrated flag dw step*341/10 ;Step t code defined in the Mpm users manual. It begins with a 256 byte header: header[0] Octal 375. Not document prl.doc 8/5/80 gf ruct has been used. BUGS The load address must be on a page boundry (multiple of 256). ******* dconf 77, 8, 8 ;Drive 0 dconf 77, 8, 8 ;Drive 1 dconf 77, 8, 8 ;Drive 2 dconf 77, 8, 8 ;Drive 3 *******responding byte of code should be relocated by adding to it the most significant byte of the load address. The usualime dw 0 ;Reserved for future use, must be zero dw 0 ;Reserved for future use, must be zero dw settle*341/10 ;Head seed by Mpm. header[1 to 2] Program size (low byte first). header[3] Not documented by Mpm. header[4****************************************************************** * * * Define 5 1/4 inch drive parameters * * U way to make a prl file is to assemble the source code twice, once at 0 and once at 100 hex. Then build the map by comparinttle time endm dmarap: db 0, 10*8 ;Revision 0, length 80 bytes dparam: equ $ ;Drive parameter table ************* to 5] Size of any required buffer space (low byte first). header[6 to 255] Currently unused, reserved by Mpm.  Morrow * * Designs takes no responsibility for damage that occures through * * the misuse of this macro. * * * se Tandon parameters: 40 tracks, 5 ms step, 15 ms settle * * * ******************************************************g the bytes one-for-one, setting the corresponding bit to the difference. If two bytes differ by more than 1, then som************************************************************ * * * Define 8 inch drive parameters * * Use SA800 p Next comes "program-size" bytes of binary object code assembled at address 0. Finally comes a "bit map", one bit  ************************************************************************* if (maxdm ne 0) or (maxmf ne 0) ;DJDMA present?  ******************* dconf 40, 5, 15 ;Drive 0 dconf 40, 5, 15 ;Drive 1 dconf 40, 5, 15 ;Drive 2 dconf 40, 5, 15 ;Drase ;Divisor (lsb) dlm equ mbase+1 ;Divisor (msb) ier equ mbase+1 ;Interupt enable register clk equ mbase+2 ;WB14 printerout endif ***************************************************************** * * * The folowing equates will defier equ 04h ;Cover open pfrdy equ 08h ;Paper feed ready crrdy equ 10h ;Carriage ready pwrdy equ 20h ;Print wheel ready chNorth Star motherboard (2 serial + 1 parallel) * * * *****************************************************************fine multi I/O ports addresses for group zero gzero equ 0 daisy0 equ mbase ;Daisy input ports daisy1 equ mbase+1 sensesw ive 3 endif ************************************************************************* * * * Console driver rout select port lcr equ mbase+3 ;Line control register mcr equ mbase+4 lsr equ mbase+5 ;Line status register msr equ mbase+6 ne the Decision I mother * * board I/O or the Multi I/O environments if needed. * * * *******************************eck equ 40h ;Printer check (error) ready equ 80h ;Printer ready ; Define daisy 0 status input bits for Diablo HyType II dr******** ************************************************************************* * * * This routine is an experimequ mbase+1 ;Sense switches if multr3 eq 0 ;Daisy output ports are different daisi0 equ mbase ; for Decision I and Multines. * * * * Routine used depends on the value of CONTYP. Possible CONTYP * * values are listed as follows:  rbr equ mbase ;Read data buffer thr equ mbase ;Tranmitter data buffer dlab equ 80h ;Divisor latch access bit thre equ 20h********************************** multio equ (contyp eq 2) or (lsttyp ge 2) ;Multi I/O board used? if multio ;Define Muiver crstrd equ 1020h ;Carriage ready pfstrd equ 810h ;Paper feed ready pwstrd equ 2040h ;Print wheel ready ; Define ent to reduce missed and garbled * * characters on console output. * * * **************************************i I/O. daisi1 equ mbase+1 ;These two are the Decision I ports else daisi0 equ mbase+1 ; and these are the Multi I/O's.  * * * * CONTYP is: 0 Nothing, used for patching to PROM's * * 1 Provide for 128 bytes of patch space * * 2 M ;Status line THRE bit cts equ 10h ;Clear to send dsr equ 20h ;Data set ready dr equ 1 ;Line status DR bit wls0 equ 1 ;lti I/O environment mbase equ 48h ;Base address of Multi I/O or Decision I grpsel equ mbase+7 ;Group select port dll equ mbdaisy 0 output bits d9 equ 01h ;Data bit 9 d10 equ 02h ;Data bit 10 d11 equ 04h ;Data bit 11 d12 equ 08h ;Data bit 12*********************************** if contyp ne 0 costrp: mov a,c ;Strip parity on conout ani 7fh mov c,a jmp condaisi1 equ mbase endif ; Define daisy 0 status input bits ribbon equ 01h ;End of ribbon paper equ 02h ;Paper out covulti I/O or Decision I driver * * 3 2D/B driver * * 4 DJDMA serial port * * 5 Switchboard serial port * * 6 Word length select bit 0 wls1 equ 2 ;Word length select bit 1 for 8 bit word stb equ 4 ;Stop bit count - 2 stop bits ; De   pfstb equ 10h ;Paper feed strobe crstb equ 20h ;Carriage strobe pwstb equ 40h ;Print wheel strobe rest equ 80h ;Print just below the regular Cbios jump table. The standard divisor * * table is given below. * * * * Sense switch:* CONTYP: 2 Multi I/O or Decision I console driver * * * *************************************************************ill character ready jz conin1 in rbr ;Read character ani 7fh ;Strip parity ret ************************************ cperi equ 10 ;Default to 10 characters per inch lperi equ 6 ;Default lines per inch hinc equ 120 ;Horizontal increments pe************ * * * Due to its length, the TTYSET routine driver is below the CBOOT * * CBOOT routine. * * er restore (Ribbon lift on Multi I/O) ; Define clock select bits rlift equ 40h ;Ribbon lift pselect equ 80h ;Select (No 123 (0 = off, 1 = on) * * 000 = 110 * * 001 = 300 * * 010 = 1200 * * 011 = 2400 * * 100 = 48**** if contyp eq 2 ************************************************************************* * * * This driver***************************** * * * Output a character to serial port. * * * ******************************r inch vinc equ 48 ;Vertical increments per inch numtabs equ 160 ;Number of horizontal tabs maxchrs equ 1024 ;Maximum numb * ************************************************************************* ********************************************t used by Diablo) ; Define Modem Control Register bits dtrenb equ 1 ;DTR enable rtsenb equ 2 ;RTS enable ; Define gr00 * * 101 = 9600 * * 110 = 19200 * * defcon = 9600 * * * * Note: If you are using a Mul on cold boot will inspect bits 1-3 of the sense * * switches. If the value found is in the range 0-6 then the * * console *********************************** conout: call selcon ;Select console conout1:in lsr ;Read status ani thre ;Wait tier of printer characters to queue maxrgt equ 1584 ;Maximum carriage position dfrmln equ 110 ;Forms length times 10 autolf e********************* * * * Read a character from the serial port. * * * ***********************************oup select bits s0 equ 01h ;Group number (0-3) s1 equ 02h smask equ 03h bank equ 04h enint equ 08h restor equ 10h ;Pritio then the switches will not be * * available so the baud rate will be taken from DEFCON. * * * **********baud rate will be taken from the rate table. Otherwise * * the baud rate will be set from the DEFCON word which is found * *ll transmitter buffer empty jz conout1 mov a,c ;Character is in (c) out thr ;Output to transmitter buffer ret *****qu 0 ;Default to noIAuto line feed endif ***************************************************************** * * ****************************** conin: call selcon ;Select console conin1: in lsr ;Read status register ani dr ;Wait tnter restore on Multi I/O denable equ 20h ;Driver enable on Multi I/O ; Define special constants for the HyTyp II driver *************************************************************** *************************************************************! ************************************************************ * * * Return serial port status. Returns zero if characte************************************************************************* if contyp eq 5 swbase equ 0 ;Base of the SWITconin: lxi h,serin+1 ;Serial input status xra a ci2: cmp m ;Wait till 40h deposited at 3fH jz ci2 mov m,a ;Clear statusl ret sellst: lda group ;Select printer group ori lstgrp out grpsel ret endif ******************************************* if contyp eq 3 conout: jmp fdcout ;Console output conin: jmp fdcin ;Console input conist: call fdtst************************************************************ * * * Multio/Wunderbuss group select routines * * r is not * * ready to be read. Else returns 255 if ready. * * * ***************************************************CHBOARD conist: in swbase+2 ;Get the first ports status ani 4 ;Mask the data ready bits rz ;Return console not read dcx h ;Point to input data mvi a,7fh ;For masking out parity ana m ret conist: lda serin+1 ;Pick up serial input ********************************** * * * The following byte determines if an initial command is to be * * given to CP/at ;Console status mvi a,0ffh rz inr a ret endif ;2DB ******************************************************** * ************************************************************************* if (contyp eq 2) or (lsttyp ge 2) ;Need gr************** conist: call selcon ;Select console in lsr ;Read status register ani dr rz ;No charactter ready y mvi a,0ffh ttyset: ret ;NULL terminal initialization conin: in swbase+2 ;Get switchboard status ani 4 ;Test for status ora a rz ;If zero then no character ready mvi a,0ffh ;Set character ready ret endif *********************M on warm or cold boots. The value of the byte is * * used to give the command to CP/M: * * * * 0 = never give comm********* * * * CONTYP: 4 DJDMA console driver * * * ******************************************************oup select routines? selg0: lda group ;Select group zero out grpsel ret selcon: lda group ;Select console group ormvi a,0ffh ;Character ready ret endif ;Multi I/O or Decision I *****************************************************data ready jz conin in swbase ;Get a character ani 7fh ;Strip off parity ret conout: in swbase+2 ;Check status **************************************************** * * * CONTYP: 5 Switchboard as serial console * * * and. * * 1 = give command on cold boots only. * * 2 = give the command on warm boots only. * * 3 = give the command *********** if contyp eq 4 conout: lxi h,dmchan mvi m,serout ;Command for serial output inx h mov m,c jmp docmd i congrp out grpsel ret selrdr: lda group ;Select reader/punch group ori 5-lstgrp ;Use 'other' serial port out grpse************ * * * CONTYP: 3 2DB console driver * * * ***************************************************** ani 8 ;Wait till output buffer empty jz conout mov a,c ;Write a character out swbase ret endif *************" on warm and cold boots. * * * ***************************************************************** autost: db 0 ;Reve length byte itself. * * * * Revision Description * * E.0 1 and 2 defined * * E.3 This table is moveequ $ ************************************************************************* * * * At the first page boundry fol if $ gt bios+256 ;Test for code overlap 'Fatal error, pointer table placement.' else ds bios+256-$ ;Start at a page bYPROG' * * coldend equ $ * * * * will execute Microsoft BASIC, and MBASIC will execute the * * "MYPROG" BASIC  * * * * 3) This points to the drive parameter table for DJDMA floppy * * disk drives. If no DJDMA is prision 0 structure db 100h - (low $) ;The rest of the page is used for this stuff autoflg:db 0 ;Auto command feature enabled to a page boundry * * E.3 0, 3 and 4 defined * * * * The pointers defined so far are as follows: * * lowing the CBIOS we have a series of * * pointers that point to various internal tables. At the start of * * each of these taboundry endif db high ($-1) ;CBIOS page number db revnum ;Cbios revision number dw drconf ;Drive configuration table program. Note: The command line must be in * * upper case for most commands. * * * ******************************esent then this pointer is * * null (0). * * * * 4) This points to the autostart command structures. Use flag coldmes:dw coldcm ;Pointer to the cold start command warmes: dw warmcm ;Pointer to the warm start command ******* * * 0) High byte is the page number of the CBIOS. Low byte is * * the CBIOS revision number. Used to determine pointer les we have a revision byte and a length byte. * * The revision byte is the current revision number for that * * particularpointer dw ioconf ;I/O configuration table pointer if (maxdm ne 0) or (maxmf ne 0) ;DJDMA present? dw dmarap ;Drive para*********************************** coldcm: db coldend-coldcm ;Length of cold boot command db '' ;Cold boot command goesd to * * automatically invoke a command on cold or warm boot * * * * 5) This will be a null (0) pointer. It marks t********************************************************** * * * If there is a command inserted here, it will be passed * * structure. * * * * 1) This points to the drive configuration table. * * * * 2) This points to  structure and the length byte is the length of that * * structure. This length does not include the revision byte nor * * thmeter table pointer else dw 0 endif dw autost ;Auto command structure pointer dw 0 ;End of table marker ********* here coldend equ $ warmcm: db warmend-warmcm ;Length of warm boot command db '' ;Warm boot command goes here warmend he end of the * * table. * * * ************************************************************************* to the * * CCP if the auto feature is enabled. For Example: * * * * coldcm: db coldend-coldcm * * db 'MBASIC Mthe I/O configuration bytes for the serial * * drivers. Eg, the console, printer, reader, and punch * * devices.# **************************************************************** * * * The following code performs the mapping of logiin the A * * register a 0 if the device is not ready accept a character and a * * 0ffh if the device is ready. The input and aracter input ready status * * devOST Return the device character output ready status * * * * The setup routine iniST, RDRIN, RDRIST, PUNOUT, LSTOUT, and * * LSTOST routines are the logical device driver entry points * * provided by this dn performed by that particular device routine. The device * * names are defined and described in the "An Introduction to CP/M  * LST: LSTOUT LSTOST * * * * TTY: TTYSET TTYIN TTYOUT TTYIST TTYOST * * CRT: CRTSET CRTIN CRTOUT CRTIST CRTOcal to physical * * serial I/O devices. The physical entry points are CONIN, CONOUT, * * CONIST, RDRIN, PUNOUT, LSTOUT, and Loutput routines * * should wait untill the device is ready for the desired operation * * before the doing the operation and rtializes the device and returns. The input * * routine returns one character in the A register (parity reset). * * The outputevice mapper. The other entry names must be * * provided by the physical device drivers. * * * ******************* * Features and Facilities" manual in the section on the STAT * * command and in the "CP/M Interface Guide" in the IOBYTE seST * * UC1: UC1SET UC1IN UC1OUT UC1IST * * * * PTR: PTRSET PTRIN PTRIST * * UR1: UR1SET UR1IN UR1IST * STOST. These entry points * * are mapped via the Intel standard I/O byte (IOBYTE) at location 3 * * in the base page to the leturning. * * * * Not all of these functions need to be implemented for all the * * devices. The following is a  routine write one character from the C register. The * * input status routine returns in the A register a 0 if the device * ******************************************************* if contyp eq 6 ;I/O byte implemented for North Star ; drivection. * * The device function postfixes are as follows. * * * * devSET Initial device setup and initialzation * * UR2: UR2SET UR2IN UR2IST * * * * PTP: PTPSET PTPOUT * * UP1: UP1SET UP1OUT * * UP2: UP2SET UP2OUT ow level device drivers. * * * * Note: A naming convention has been chosen to reduce label * * colisions. The fitable of the entry points needed for * * each device handler. * * * * device setup input output input output * does not have a character ready for input for 0ffh if a character * * is ready for input. The output status routine returns rs. Other drivers to follow conin: mvi e,1 ;Console input call redir ; IOBYTE: 76543210 dw ttyin ;CON: = TTY: xxxx * devIN Read one character from the device * * devOUT Write one character to the device * * devIST Return the device ch * * * * LPT: LPTSET LPTOUT LPTOST * * UL1: UL1SET UL1OUT UL1OST * * * * The CONIN, CONOUT, CONIrst three characters of a name indicate the * * device drivers name, the following three characters indicated the * * functio* * name status status * * * * CON: CONIN CONOUT CONIST * * RDR: RDRIN RDRIST * * PUN: PUNOUT *$ xx00 dw crtin ;CON: = CRT: xxxxxx01 dw rdrin ;CON: = BAT: xxxxxx10 dw uc1in ;CON: = UC1: xxxxxx11 conout: mvi e,1til the command: * * SINGLE E * * is given followed by a carriage return. A message should * * appear saying: *riage return. The messge: * * SINGLE INSTALLED * * should appear, followed by the CP/M prompt. At this time, * * if an **************************************************** * * * Main reconfiguration program. * * * ***********s pip (or any * * other program) to copy or move data between diskettes by * * prompting for a disk change operation on driveP/M prompt reappears, ececute SINGLE E. * * * ***************************************************************** tit ;Console output call redir ; IOBYTE: 76543210 dw ttyout ;CON: = TTY: xxxxxx00 dw crtout ;CON: = CRT: xxxxxx01 d * SINGLE REMOVED * * followed by the CP/M prompt. * * The program is intended to allow backing up diskettes * access to drive B is made, a prompt will appear * * requesting you to insert a diskette of the proper density * * into drive ****************************************************** org tpa start lda tbuff ;Check if any command given mov b,a ;P A. Will allow * * back ups to be made with only one drive. * * * * Written for Thinker Toys by Bobby Dale Gifford. le '*** Single Drive Utility For CP/M Ver 2.2 ***' acr equ 0ah ;Carriage return alf equ 0dh ;Line feed wboot equ 0 ;CP/Mw lstout ;CON: = BAT: xxxxxx10 dw uc1out ;CON: = UC1: xxxxxx11 conist: mvi e,1 ;Console input status call redir ; * for those users with only one drive. To back up a diskette * * follow these these procedures. * * * * 1) ExecuteA. Type a return. CP/M will now access drive A * * thinking it is actually drive B. When CP/M return to drive * * A, another put counter in B lxi h,tbuff+1 ;Beginning of command line loop dcr b ;Check for end of command line jm exit ;If minus then * * 12/17/79 * * * * The program SINGLE tricks CP/M into thinking there are * * two drives when in actuality o warm boot tpa equ 100h ;CP/M transient program area tbuff equ 80h ;Command line buffer ccpsize equ 800h ;Size of CP/M ccp IOBYTE: 76543210 dw ttyist ;CON: = TTY: xxxxxx00 dw crtist ;CON: = CRT: xxxxxx01 dw rdrist ;CON: = BAT: xxxxxx10  SINGLE S. * * 2) Use PIP to copy all or a selected group of files * * (actually any program should run). * * 3) Folrompt will be given to you requesting that you * * reinsert the original drive A diskette. This procedure will * * continue un error exit without change mov a,m ;Get charactor typed on command line inx h ;Bump scanning pointer cpi aspc ;Skip spanly one drive is present in the * * system. To execute the program give the command: * * SINGLE S * * followed by a car aspc equ ' ' ;Space entry equ 5 ;CP/M BDOS entry location seljmp equ 30h ;Offset to jump to select drive ************* ***************************************************************** * * * Single Drive copy program. This program allowlow the prompts for inserting diskettes ( Suggest * * you write protect the original diskette (Tab OFF)). * * 5) When the C% ces jz loop ;Continue if space cpi 'S' ;Check for "Start" command jz insert ;Insert the code if true cpi 'E' ;Check ump dad d ;Form pointer to drive select jump lxi d,badmsg ;Message pointer mov a,m ;Get the jump opcode cpi (jmp) ;Issh h ;Save pointer to relocated single lxi d,heart ;Pointer to code to relocate lxi b,map ;Pointer to relocation map relsel-heart dad b xchg mov m,e inx h mov m,d lxi d,insmsg jmp list **********************************************the CP/M console device. * * * ***************************************************************** list mvi c,9 ;Prrelocated code mov a,h sta entry+2 pop psw ;Restore controller page address lxi d,3 dad d mov m,a ;Form second jumfor "End" command jz remove ;Remove the code if true ***************************************************************** *  it a jump instruction ? jnz exit1 ;Exit if not a jump inx h mov a,m ;Get first byte of jump address cpi 1bh ;Is it ao ldax b ;Get a relocation byte ana a ;Test if byte needs relocated jm putjmp ;If minus then all done mov m,h ;Assume ******************* * * * Remove does the opposite of insert. It modifies the address * * to be in the original state.int buffer command jmp entry ;Enter CP/M ***************************************************************** * * * p (home) dad d mov m,a ;Form third jump (seek) dad d mov m,a ;Form fourth jump (status) lda wboot+2 ;Get page addre * * Exit by printing an error message. No change made. * * * ************************************************* jump with correct offset ? jnz exit1 inx h ;Get page address of controller mov a,m pop h ;Restore pointer to relocaterelocation jnz incre ;Move this byte directly ldax d mov m,a incre inx h ;Bump relocation address inx d ;Bump source * * * ***************************************************************** remove lhld wboot+1 ;Pointer to CBIOS Insert the code for the new selection routine into the ram * * below the ccp. * * * *****************************ss of CBIOS dad d mov m,a ;Form fifth jump (oldinp) dad d mov m,a ;Form sixth jump (oldout) lhld wboot+1 ;Get point**************** exit lxi d,what ;No change message exit1 call list ;Entry point for different message on exit jmp wbootd code push h push psw ;Save page address of controller inx h lda entry+1 mov m,a ;Insert first byte of new bdos loc inx b ;Bump relocation map jmp relo putjmp lhld wboot+1 ;Get pointer to CBIOS lxi d,seljmp ;Offset to drive select j lxi d,seljmp ;Offset to select drive dad d ;Form offset to select drive lxi d,badmsg ;Assume error mov a,m ;Get the fi************************************ insert lhld entry+1 ;Get pointer to base of BDOS lxi d,-(ccpsize+6+100h) dad d puer to CBIOS lxi d,seljmp+1 ;Offset to select drive jump dad d pop d ;Restore pointer to relocated code xchg lxi b,new ;Do a warm boot on exit ***************************************************************** * * * List a message on ation inx h lda entry+2 mov m,a ;Insert second byte of new bdos location xra a sta entry+1 ;Modify entry to jump to & rst byte of the jump cpi (jmp) ;Is it a jump opcode ? jnz exit1 ;Error if not inx h mov a,m ;Should point to newsel 0ff * * represents the end of the map. * * * ***************************************************************** m remmsg db acr,alf db 'Single removed.$' ***************************************************************** * * *  is relocated to execute with the * * current CP/M being executed under. * * * ****************************************** what db acr,alf db 'Unknown command - NO change made.$' *********************************************************da db 0 ;ana db 0,0 ;mvi db 0,0,1 ;jz db 0,0 ;mvi db 0,0,1 ;jmp db 0 ;mov db 0 ;mov db 0 ;ana db 0 ;r cpi newsel-heart jnz exit1 ;Error if not inx h ;Point to high byte of address mov d,m mvi e,5 ;Form address to contrap db 0,0,0 ;jmp db 0,0,0 ;jmp db 0,0,0 ;jmp db 0,0,0 ;jmp db 0,0,0 ;jmp db 0,0,0 ;jmp db 0,0,1 ;lxi db 0,0Bad Cbios format message. * * * ***************************************************************** badmsg db acr,***************************** heart equ $ ;Beginning of code to relocate diff set tpa-$ oldbdos jmp 0 ;New jump to bd******** * * * Successful insertion message. * * * *******************************************************z db 0 ;inx db 0 ;push db 0,0,1 ;call db 0 ;pop db 0,0,1 ;jmp db 0,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 db 0oller page ldax d ;Get the byte of controller address mov m,a ;Reconstruct controller address dcx h mvi m,1bh ;Offset,0 ;shld db 0,0 ;mvi db 0 ;mov db 0,0,1 ;sta db 0 ;cmp db 0 ;rz db 0,0,1 ;lxi db 0 ;ana db 0,0,1 ;jz alf db 'Bad Cbios format found - NO change made.$' ***************************************************************** * os home jmp 09h ;Controller track 0 seek seek jmp 0ch ;Controller seek routine status jmp 27h ;Controller status routine ********** insmsg db acr,alf db 'Single installed.$' ***************************************************************** ,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 db 0,0,0,0,0 db 0ffh  into controller rom to drive select lxi d,remmsg jmp exit1 *************************************************************db 0,0,1 ;lxi db 0,0,1 ;call db 0,0,1 ;call db 0,0,1 ;lxi db 0,0,1 ;call db 0,0,1 ;call db 0 ;push db 0,0,1 * * Byte for byte map of code to relocate. A zero represents no * * relocation, a 1 represents a relocateable byte, and a oldinp jmp 09h ;Jump installed oldout jmp 0ch ;Jump installed newsel lxi h,oldbdos+diff ;Insert new bdos jump in case of w* * * Seccessful removal message. * * * ***************************************************************** ds 100h-($ mod 100h) ***************************************************************** * * * The rest of the program**** * * * Unknown command error message. * * * *********************************************************** ;call db 0 ;pop db 0,0,1 ;lda db 0 ;ana db 0,0,1 ;lxi db 0,0,1 ;jz db 0,0,1 ;lxi db 0 ;mov db 0,0,1 ;l' arm boot shld entry+1 mvi b,0 ;Get last selected drive olddrv equ $-1 mov a,c ;Put new drive into A sta olddrv+diff ;******************************************** * * * Messages output by the program. * * * ****************** proper track ***************************************************************** * * * Mesg prints a message on the c:G!~# S*Eʟ% *: ItCw#8*0~#~#~#:w#:w2|2ww olddrv+diff ;Get drive to select ana a ;Test for drive A lxi h,trkb+diff ;Point to place to save track for B jz next0+diUpdate last selected drive cmp b ;Check if same drive rz ;Done if same lxi h,insamsg+diff ;Insert A message ana a ;T*********************************************** insamsg db acr,alf,acr,alf db 'Insert "A" (return) : ' db 0 insbmsg db aonsole. * * * ***************************************************************** mesg mov c,m ;Get char to print w:ww*1 s#r%*0~#~#Vw+6 Unknown command - NO change made.$ Single installed.$ Sff ;Take jump if selecting drive A lxi h,trka+diff ;Place to save track for A next0 mov m,c ;Save track number lda olddrv+est for drive A jz next+diff ;Take jump if selecting A lxi h,insbmsg+diff ;Else get insert B message next call mesg+diff ;Pcr,alf db 'Insert "B" (return) : ' db 0 crlf db acr,alf,0 end  mov a,c ;Put copy into A ana a ;Test for end rz ;Return if done inx h ;Bump pointer to message push h ;Save poiningle removed.$ Bad Cbios format found - NO change made.$diff ;Get drive to select ana a ;Test for drive A trka equ $+1 ;Storage for track on drive A mvi c,0 ;Pick up track for rint message call oldinp+diff ;Get response lxi h,crlf+diff ;Echo carriage return and line feed call mesg+diff call statter call oldout+diff ;Print the char pop h ;Restore the pointer jmp mesg+diff ;Continue printing *********************NO change made.$ Single installed.$ SA jz seek+diff ;If selecting A then take the jump trkb equ $+1 ;Pick up track for drive B mvi c,0 jmp seek+diff ;Seek tous+diff ;Get status of currently selected drive push b ;Save track call home+diff ;Home drive pop b ;Restore track lda(  ' !"y2!g*!Z !Z :!VK!Qq:Ny#Z Insert "A" (return) :R" O!/q*/& L!1p+q*0#L~*##N!ͽ͞"T!Vq*VMͳ!Xp+q!W* >Wr#MͲ!_R/, Space: Invalid File Indicator** Too Many Files **File Not Found Size Recs Bytes Ext Acc65536 set to R/O Invalid!+s#r#4 !s+p+q!6!66:!ڄ !6!6>!r *&**&Y i !6!4+4A :} :!:UP1:UP2:TTY:CRT:LPT:UL1:R/OR/WSYSDIRR/O R/W SYS DIR ** Aborted **Active User :Active Files: Drive Characteristics6*s"s*o͊O !v6>!vQ*v&w 6`i+46)A*:'ʓ:'O!) ~2vʍ: Insert "B" (return) : p+q!`6>!`6*`&*^*`&Y />!`4 >*]& ~ O!]49!a6:a*]& ~2bO>z*bM > Disk AssignmentWrong CP/M Version (Requires 2.0)!9"2!T OË!]6:\:] Hr3 Ë:\ʀË4- >!699 2¨ :!4: :2!6+6>! :O!9 DMi ͱ:!O!Y DMi :25536: 128 Byte Record CapacityKilobyte Drive Capacity32 Byte Directory EntriesChecked Directory EntriesRecords/ ExtentRvO!w 6,]!v6>!v*v&w ~һ*vM !v4˜8AO͐:͐ͱ*##N!ͽ"* N#F*͠"!b/~,H~:H~*H~.H~>H~<H~=H*]& 6!]4T!]4!cq*a&Y :cw!a4͇ /ҋͺ *2!"q*"&L ͐ ͐ ͐!$p+q*#~*#N͐*##"#÷!&p+q͠*%DMͱ O O!(q*(&:2͠!4 F :® )!6>!ګ ͠:O!9 DMi 8ͱ!6> !ڤ Å :2ecords/ BlockSectors/ TrackReserved Tracks is Temp R/O Disk: d:=R/OSet Indicator: d:filename.typ $R/O $R/W $SYS $DIRDisk S>!H% - *DM ͱͷDM  ͱ* N#F 9ͱ * ^#V))DM Tͱ* ~fr*d*f!is*d́"dPY! "f>!h#~Haͫo!h6:i0O͐!mr+s+p+q*lL!*p+q*)O2'!,p+q*+O2'O2'O!.p+q*-LRRLR\Lk ä  ͐:!O!Y DMi w !4C F :¿ >F : F :=229:Y= ;>9*&Y DMtatus : DSK: d:DSK:User Status : USR:Iobyte Assign: =Bad DelimiterInvalid AssignmentBad Delimiter: Bytes Remaining On DM oͱ*DM ͱ*N#F ͱ * N#F ͱ͠!p+q͠*DM':͐ͫZ"!6> *} *M3 Copyright (c) 1979, Digital Research????????????CON:RDR:PUN:LST:DEV:VAL:USR:DSK:TTY:CRT:BAT:UC1:TTY:PTR:UR1:UR2:TTY:PTPTZs#r*lڶ*l+s#r*jN#F+q#pÌ!nq!"o"q}2uo&"s* s:n*sDM2u:uqos)  =2 I>!6:=28 :2:2 :!!29:Y T >:Y,e \>Ì !p+q*~:ʉ *N͐*͐*)#")Ã& \!"))\Ұ*)")]͠*)M! ^#V *) >*) w *) >*) w *) >*))!")*++!)a*)) ^#V")]*)")*)) ^#V")]!)6> !)T*)&*)~2)*)&*)~2)O;*)) ^#V"2):)<2)M*)#")/:)ҩ*)+")`*")#"]!*)!/H!")!"]*)) *)s#r!#"o :͐!p+q!'"!6> **{2*́"PY! ">!+~H !6:0O͐à k͐ w *) >*) w.*)DM\ -+!\6uͱ:)O! DMͱ*)#")Ù*))))))"):m w>.Yn )*)) *)) N#Fq#p*)) *)s#r*)#")!)6 J:)!)J!)6 :)<2)*)")҈q:tw͠ͱ!)6> !).*)&*)*)&*) w:)<2)*)) >w#6*)) w#6*)!) w#6*)%) w#6*)) N#F*)) q#p*)%)͠Q" 8AO͐jͱͷDM͏ m  Z"l"!6>ʥ *}҆ *M ͱ*}x O͐} W͐-:YS:Z Hҧ!6> 2)½>!)6> !)*)&*)>2) :) .͐*)M͐:)<2)"))ҍ*)) ^#V")]͠.*)DM\ -°!\6:\ͣ:ͱ*}DM'ͫ*)%) N#F'ͫ*) *) ~e *) * ~o&͞ *)%) q#p!)6* >!)6!)6>!)=:)!)w=*)&*)~2):ͱ !+s#r!+s#r#4D ͠:\ʹ :\=Oͳͩ !6!)6l :) :)=2) :] & !"}2\!h6?!99:Y=/9&ͩ c,Hͩ 9 EHͺ i`N#Fog_og_ogD!) N#F'k͐ͫ*)) N#FͫR͐/͐ *) ~IO͐NW͐ͫ8AO͐:͐ *) ~2)t(͐:)҃))*)& *):)2):):*)!) *)) s, >X\:)“>!d!")>!)d!"j6?\:'C:'ƀo&")!)6!"):)/)HҘ]!)6> !)ڎ*)&*)*)&*) y!)6 Ä:) M!>))덑o|gҘ =†DM!>))ҭ =¥~ ³^#V) ½^#V|g}o _{ozgi`N#Fogo&og_{_z#W*  copyright(c) 1977, digital research $Error On Line $SUBNo 'SUB' File Present$Disk Write Error$Command Buffer Overflow$Commv ~_{ozg001 $$$$ SUBA2A2!ͮ͐ 6ͤ!6!.ͳC2ͤ!@îMorrow Designs Sysgen Version 4.5Source drive name (OrʉSͧ!v6!"v!|6:|Ҁ!x6 2}:} Hk:} h:}$6 2}$*}M3:}02}O> ͧ3!z6|3 ^#V"`#2_+?~(?>2_>(2)>2(w ~#f>P2)>2(rzbzw>2)bzrͿ:_ʝand Too Long$Parameter Error$Invalid Control Character$Directory Full$Cannot Close, Read/Only?$!9"!͇͊!p+q* return if in memory)Source on , then type returnDestination drive name (Or return to warm boot)Destination on 6, then type 6ͭ:}"!}5́ͭ́3*yM"h:}^a a2}O>Vͧ^:}2!4:(BN>2:)!4!^!*FNyͅ*DM:ʼ! ͊!p+q*͍2!p+q*͍2!p+q*͊!p+q*͍!p+q*͍!p+q*͍2!s+p+q+p+q:returnPermanent error, Type return to ignoreFunction completeInvalid drive (Use A through P)No such fileSource file incompl*z& ~2y :yHڪ!z4>>*z& ~ !z4í!{q*v#"v͙dͧ*vv :{w:x<2xO>}|ͧͳ͐ͤ ʼ!6"@!":_?!">62)!:(=?bͿè1!Iͳ:] ʡ\?@ABCDEFGHIJKLMNOP~#eteCan not generate systems on 5 1/4 diskettes that are formatted in single density.o warm boot)Destination on 6, then type -!6]:ͧz2~e:~2O! 6*~& 6$>!~_z*~& w!~5Bx:yͧ*v+"vDM\À!mͮ6!kͮ͐ AڼCáA2A2ͤ!ͳ͐ 6ͤ2!.ͳ!ͮ͐ 6ACͧ!t6>!t%\= >!t6:t<2t=O! ~2u b:<2O>9b!60+~9b!60+4:uat:u_2u:uM |o&)))))))a{__> ͞> Þͤ~͞#ó*`z:O!$'*!+ returnPermanent error, Type return to ignoreFunction completeInvalid drive (Use A through PNo such fileSourc? 1 20 2 244 8 21 512 M20 Drive C 672 2036 0 1 20 2 244 dw uc1ist ;CON: = UC1: xxxxxx11 rdrin: mvi e,7 ;Reader input call redir ; IOBYTE: 76543210 dw ttyin ;RDR: = TTY: 2% ͋*-"*$$$ SUBq:(=2(N *$*& w*$#"$*&#"&' !"N*M^7 !)6:!)ھ *N*DM͆ W Extended Submit Vers 2.0Xsub Already Present$Requires CP/M Version 2.0 or later$:y*###ƒ# yk 8 21 512 M20 Drive A or B 1024 1973 0 0 31 2 202 8 32 512 M26 Drxxxx00xx dw ptrin ;RDR: = PTR: xxxx01xx dw ur1in ;RDR: = UR1: xxxx10xx dw ur2in ;RDR: = UR2: xxxx11xx rdrist: mvicpmspt cpmdsm mapcyl maphed mapsec maplen ncyls nheds nsecs secsize name (20) 336 1269 0 1 20 2 22*ʭ :*ʗ ͯ *N"P*6:2)÷ *N"N!) $@BA$! A "!$""  җ 4!~=ŐW!xʵ ~#èbx {~#o}où.xsubb!np+q*m2_!pp+q*oive A, B, or C 1024 2015 0 0 31 2 202 8 32 512 M26 Drive A or B 1024 2047  e,7 ;Reader input status call redir ; IOBYTE: 76543210 dw ttyist ;RDR: = TTY: xxxx00xx dw ptrist ;RDR: = PTR: xxx44 4 21 512 M10 Drive A 336 1280 0 1 20 2 244 4 21 512 M10  ]xsub*"-!/"*"+!""1 M*!"́!"* (xsub active)$|*y ʥ*"*7* 0 0 31 2 202 8 32 512 M26 Drive C x01xx dw ur1ist ;RDR: = UR1: xxxx10xx dw ur2ist ;RDR: = UR2: xxxx11xx punout: mvi e,5 ;Punch output call redir Drive B 672 2015 0 1 20 2 244 8 21 512 M20 Drive A or B 672 1028 0 **x*́͋<͛ :%*=26͋!7^#6 #6 #6$ 8*7~O #w# !6:6=, ; IOBYTE: 76543210 dw ttyout ;PUN: = TTY: xx00xxxx dw ptpout ;PUN: = PTP: xx01xxxx dw up1out ;PUN: = UP1: xx10xxxx  * * ************************************************************************* if contyp eq 1 ;User defined IO ar: 1 Blank space for console driver * * * * The driver entries CONOUT, CONIN, CONIST are defined in the CP/M * * almand "STAT LST:=UL1:" is used if you have a * * printer connected to the parallel port. * * * ******************** iobyte redir0: rlc ;Shift the next field in dcr e ;Bump the shift count jnz redir0 redir1: ani 110b ;Mask the reg of * * the logical to physical entry points is performed as follows: * * * * Device name Left Right Parallel *  dw up2out ;PUN: = UP2: xx11xxxx lstout: mvi e,3 ;List output call redir ; IOBYTE: 76543210 dw ttyout ;LST: = TTYea ttyset equ $ ;Console initialization conout equ $ ;Console output conin equ $ ;Console input conist equ $ ;Consolternation guide. Eg. Input parameters are in register C and * * results are returned in register A. The TTYSET routine is us***************************************************** if contyp eq 6 ;Use North Star I/O? nsldat equ 2 ;Left serial podirection field mov e,a ;Make the word table offset mvi d,0 pop h ;Get the table base dad d ;Offset into our table * serial serial port * * * * Console CON: = TTY: CRT: UC1: * * Reader RDR: = TTY: PTR: UR1: * * Punch P: 00xxxxxx dw crtout ;LST: = CRT: 01xxxxxx dw lptout ;LST: = LPT: 10xxxxxx dw ul1out ;LST: = UL1: 11xxxxxx lstoste input status jmp $ ds 125 endif ;User IO *************************************************************************ed * * for initialization code. It should execute a RET when complete. * * * * The TTYSET routine could be placed jurt data port nslsta equ 3 ;Left serial port status port nsrdat equ 4 ;Right serial port data port nsrsta equ 5 ;Right mov a,m ;Load the low level i/o routine pointer inx h mov h,m mov l,a pchl ;Execute the low level i/o driver UN: = TTY: PTP: UP1: * * List LST: = TTY: CRT: UL1: * * * * For example, to use a printer connected to the rig: mvi e,3 ;List output status call redir ; IOBYTE: 76543210 dw ttyost ;LST: = TTY: 00xxxxxx dw crtost ;LST: = CRT: * * * CONYTP: 6 North Star * * * * The following code implements the North Star console I/O system. * st below the CBOOT routine. * * This space (below CBOOT) is recyled for use as a disk buffer * * after CBOOT is done. * serial port status port nsstbe equ 1 ;Transmitter buffer empty status bit nssrbr equ 2 ;Reciever buffer ready status bi endif ;IOBYTE redirector ************************************************************************* * * * CONTYPht serial port, * * use the CP/M command: * * * * STAT LST:=CRT: * * * * Likewise, the CP/M com 01xxxxxx dw lptost ;LST: = LPT: 10xxxxxx dw ul1ost ;LST: = UL1: 11xxxxxx redir: lda iobyte ;Get the INTEL standard * This system is for users who purchase a Morrow Designs disk * * system to replace their North Star disk system. The Mappin- t ;See the 8251 data sheets for more ; configuration information. nslin1 equ 0ceh ;Left serial port initiale. * * * ************************************************************************* ttyin: ;Read a character  ;xx1xxxxx Assert RTS* ;x1xxxxxx Internal reset ;1xxxxxxx Enter hunt mode (for sync) nspdat equ 0 ;Parallpout: in nsrsta ani nsstbe jz crtout ;Wait till the buffer is empty mov a,c ;Write the character out nsrdat ret xxxxx Even parity generation/check ;00xxxxxx Invalid ;01xxxxxx 1 stop bit ;10xxxxxx 1.5 stop bits ;11xxx;Return not ready mvi a,0ffh ret ;Return ready ***********************************************************************ization # 1 nsrin1 equ 0ceh ;Right serial port initialization # 1 ;76543210 Bit definations ;11001110 Default con in nslsta ani nssrbr jz ttyin ;Wait till a character is ready in nsldat ;Get the character ani 7fh ;Strip parityel data port nspsta equ 6 ;Parallel status port nsprbr equ 1 ;Reciever buffer ready status bit nsptbe equ 2 ;Transmit crtist: ;Return input buffer status ptrist: in nsrsta ani nssrbr rz ;Return not ready mvi a,0ffh ret ;Thxxx 2 stop bits nslin2 equ 37h ;Left serial port initialization # 2 nsrin2 equ 37h ;Right serial port initialization # 2** * * * Right serial port routines. Use CRT:, PTR:, and PTP: devices. * * * ******************************figuration ;xxxxxx00 Synchronous mode ;xxxxxx01 1X clock rate ;xxxxxx10 16X clock rate ;xxxxxx11 64X clo ret ttyout: ;Write a character in nslsta ani nsstbe jz ttyout ;Wait till the buffer is empty mov a,c ;Writter buffer empty status bit nsram equ 0c0h ;North Star memory parity port, ; set to 0 for no North Star RAM ****ere is a character ready crtost: ;Return output buffer status in nsrsta ani nsstbe rz ;Return not ready mvi a, ;76543210 Bit definations ;00110111 Default configuration ;xxxxxxx1 Enable transmitter ;xxxxxx1x Assert******************************************* crtin: ;Read a character ptrin: in nsrsta ani nssrbr jz crtin ;Wait ck rate ;xxxx00xx 5 bit characters ;xxxx01xx 6 bit characters ;xxxx10xx 7 bit characters ;xxxx11xx 8 bite the character out nsldat ret ttyist: ;Return input buffer status in nslsta ani nssrbr rz ;Return not ready********************************************************************* * * * Left serial port routines. Use TTY: devic0ffh ret ;Return ready ************************************************************************* * * * Paralle DTR* ;xxxxx1xx Enable reciever ;xxxx1xxx Send break character, TxD low ;xxx1xxxx Reset PE, OE, FE error flagstill a character is ready in nsrdat ;Get the character ani 7fh ;Strip parity ret crtout: ;Write a character pt characters ;xxx0xxxx Parity disbable ;xxx1xxxx Parity enable ;xx0xxxxx Odd parity generation/check ;xx1 mvi a,0ffh ret ;There is a character ready ttyost: ;Return output buffer status in nslsta ani nsstbe rz . l port routines. Use UC1:, UR1:, UR2:, UP1:, UP2:, LPT:, * * and UL1: devices. * * * ************************************************************************************* ************************************************************************************** * * * LST: device driver routines. * * * * Routine used depends on the value of ttyp ge 2) and (lsttyp le 5) lstout: call lstost ;Check printer status ora a jz lstout ;Loop if not ready mov a,c mov a,c ;Write the character, strobe bit 7 nspout: ori 80h out nspdat ani 7fh out nspdat ori 80H out nspdat ret  after CBOOT is done. * * * ************************************************************************* if lst************************************************ uc1in: ;Read a character ur1in: ur2in: in nspsta ani nsprbr jz u********* * * * lsttyp: 1 Blank space for printer driver * * * * The driver entries LSTOUT and LSTOST arelsttyp. Possible LSTTYP * * values are listed as follows: * * * * LSTTYP is: 0 Nothing, used for patching to P;Print the character out thr ret lstost: call sellst ;Printer status routine in lsr ;Check if transmitter buffer em uc1ist: ;Return input buffer status ur1ist: ur2ist: in nspsta ani nsprbr rz ;Return not ready mvi a,0ffh retyp eq 1 lstset equ $ ;Printer initialization lstout equ $ ;Printer output lstost equ $ ;Printer output status ret c1in ;Wait till a character is ready in nspdat ;Get the character push psw mvi a,30h ;Reset the parallel input flag  defined in the CP/M * * alternation guide. Eg. Input parameters are in register C and * * results are returned in registerROM's * * 1 Provide for 128 bytes of patch space * * 2 Multio serial, no protocol * * 3 Multio serial, Clear To Send ppty ani thre rz ;Return busy if buffer is not empty lhld lstand ;Fetch handshake mask bits in msr ;Get MODEM Stat ;Return ready lptost: ;Return output buffer status ul1ost: in nspsta ani nsptbe rz ;Return not ready mvids 127 endif ;User IO ***************************************************************** * * * lsttyp: 2, 3, 4,  out nspsta pop psw ani 7fh ;Strip parity ret uc1out: ;Write a character up1out: up2out: lptout: ul1out: i A. The LSTSET routine is used * * for initialization code. It should execute a RET when complete. * * * * The LSTSrotocol * * 4 Multio serial, Data Set Ready protocol * * 5 Multio serial, Xon/Xoff protocol * * * *************tus Register ana l ;Strip out hand-shake lines xra h ;Invert status rz ;Return busy if printer is busy lda lastch  a,0ffh ret ;Return ready endif ;North Star I/O configuration ***************************************************or 5 Serial printer, multi protocol * * * ***************************************************************** if (lsn nspsta ani nsptbe jz uc1out ;Wait till the buffer is empty mvi a,20h ;Reset the parallel output flag out nspsta ET routine could be placed just below the CBOOT routine. * * This space (below CBOOT) is recyled for use as a disk buffer * */  ;Get last character recieved from the printer mov b,a in lsr ;Check for a character from the printer ani dr jz xskip t ;Move command to internal CCP buffer lda cwflg ;Figure out whether or not to send message ora a lda autoflg jz cldboto unknown state sta bufwrtn ;Set buffer not dirty flag sta error ;Clear buffer error flag lda cwflg ;Get cold/warm bual read or write is attempted. * * * ***************************************************************** setsec: mtializes some of the locations in page 0, and sets up the * * initial DMA address (80h). * * * ****************************************************************** wboot: lxi sp,tpa ;Set up stack pointer mvi a,1 sta cwflg ;Set cold/war;Skip if no character present in rbr ;Get the character ani 7fh ;Strip parity sta lastch ;Save last character recieved t rar cldbot: rar lda cdisk ;Jump to CP/M with currently selected disk in C mov c,a jc ccp ;Enter CP/M, send message oot flag ora a lxi h,coldmes ;Pointer to initial cold command jz cldcmnd lxi h,warmes ;Pointer to initial warm command ov h,b ;Enter with sector number in (bc) mov l,c shld cpmsec donop: ret ********************************************************************************************* gocpm: lxi h,buff ;Set up initial DMA address call setdma mvi a,(jmp) ;Im boot flag mvi h,wmdrive ;Move drive to warm boot off of into (h) mvi l,d$wboot ;Peform warm boot operation call jumper mov b,a xskip: mov a,b sui xoff ;Check for Xoff char (control S) jnz xsdone ;Printer ready ret ;Printer not ready ( jmp ccp+3 ;Enter CP/M, no message cwflg: db 0 ;Cold/warm boot flag ***************************************************cldcmnd:mov e,m ;Do one level of indirection inx h mov d,m ldax d ;Get command length inr a ;Bump length to include l****************** * * * Setdma saves the DMA address for the data transfer. * * * **************************nitialize jump to warm boot sta wbot sta entry ;Initialize jump to BDOS lxi h,wboote ;Set up low memory entry to CBIOS wa jnc gocpm ;No error hlt ;Halt computer db 0 jmp wboot ;In case user restarts the computer ******************return zero) xsdone: mvi a,0ffh ;Printer ready for data ret endif ;Multi I/O serial driver ************************************ * * * WBOOT loads in all of CP/M except the CBIOS, then initializes * * system parameters as in cold boength byte itself lxi h,ccp+7 ;Command buffer (includes length byte) mov c,a ;Set up for block move mvi b,0 call movby*************************************** setdma: mov h,b ;Enter with DMA address in (bc) mov l,c shld cpmdma ;CP/M dma arm boot shld wbot+1 lxi h,bdos+6 ;Set up low memory entry to BDOS shld entry+1 xra a ;A <- 0 sta bufsec ;Set buffer *********************************************** * * * Setsec just saves the desired sector to seek to until an * * act******************************************* * * * Gocpm is the entry point from cold boots, and warm boots. It * * iniot. See the Cold Boot Loader * * listing for exactly what happens during warm and cold boots. * * * ******************0 ddress ret ***************************************************************** * * * Home is translated into a seek  * * * ***************************************************************** setdrv: mov a,c ;Save the logical driel sector translation routines ***************************************************************** * * * Setdrv selectv ;Save current drive as old drive sta lastdrv ; in case of select errors ret setd3: push d ;Save DPH address mov h,***************************************************************** settrk: mov h,b ;Enter with track number in (bc) mov l,c DPH -> (de) mov m,e ;Put address of DPH in table inx h mov m,d inx h mov m,c ;Put sector size in table inx h movto track zero. * * * ***************************************************************** home: lda bufwrtn ;Test buve number sta cpmdrv cpi maxlog ;Check for a valid drive number jnc zret ;Illegal drive mov a,e ;Check if bit 0 of s the next drive to be used in read/write * * operations. If the drive has never been selected it calls * * a low level drivec ;Drive in (h) mvi l,d$sel2 ;Select drive call jumper call gdph ;Quick select pop d mov e,m ;DPH -> (de) inx h  shld cpmtrk ret ***************************************************************** * * * Sectran translates a log a,m ;Check if bad map has ever been read for this ora a ; drive cz getbad ;Never been read so read in bad map xchg ;ffer dirty flag ora a jnz dohome ;Skip buffer disable if buffer dirty xra a ;Invalidate buffer on home call sta bufsec(e) = 1 ani 1 jnz setd3 ;Drive has allready been accessed mov h,c ;Move logical drive into (h) mvi l,d$sel1 call j select routine that should perform some * * sort of check if the device is working. If not working then * * it should report mov d,m inx h mov c,m ;Sector size -> (c) xchg ;DPH -> (hl) jmp setd0 gdph: lda cpmdrv ;Return pointer to DPH saical sector number into a physical * * sector number. * * * *****************************************************DPH -> (hl) setd0: mov a,c ;Move sector size code into (a) sta secsiz ;Save sector size xra a setd1: dcr c ;Create nu dohome: lxi b,0 ;Track to seek to ***************************************************************** * * * Settrk umper ;Call low level drive select mov a,h ;Check if the low level drive select returned ora l ; zero to indicate an erro an error. If the logical drive has been * * selected before then setdrv just returns the DPH without * * checking the drive.ve area rlc ;Each entry is 4 bytes long rlc mov e,a mvi d,0 lxi h,dphtab ;DPH save area table dad d ;Add offset ************ sectran:lda cpmdrv ;Get the Drive Number mov h,a ;Drive in (h) mvi l,d$stran jmp jumper ;See device levmber of (128 bytes/physical sector)-1 jz setd2 rlc ori 1 jmp setd1 setd2: sta secpsec ;Save for deblocking lda cpmdrsaves the track # to seek to. Nothing is done at this * * point, everything is deffered until a read or write. * * * r jz zret ;Yes, an error so report to CP/M push h ;Save DPH address call gdph ;Get entry if DPH save table pop d ;1  ret ;(hl) = DPH save area for current drive zret: lxi h,0 ;Seldrv error exit lda lastdrv ;Get last selected drive mobuffer ;Start at beginning of buffer badl: ldax d ;Pick up an entry from the buffer ora a jz bade ;All done mov a,m ;P;the track and sector of the bad map call jumper mov a,h ;If routine returns 0 then the device has ora l ; no bad sectdata is transferred into the buffer. * * * ***************************************************************** write:  dphtab: rept maxlog*4 db 0 endm ***************************************************************** * * * Getbavailable bad map entry ***************************************************************** * * * Write routine moves dv c,a lda cdisk ;Pick up user/drive ani 0f0h ;Save user number ora c ;Put together with old drive sta cdisk ret ick up entry from bad map table inr a jz overflo ;Bad map overflow lda cpmdrv ;Put drive in table mov m,a inx h lxor map jz badret mov e,m ;Pick up track number of bad sector map -> (de) inx h mov d,m inx h xchg shld cpmtrk mov a,c ;Save write command type sta writtyp mvi a,1 ;Set write command jmp rwent ***********************************d - Check if a device has a bad map. If the device has * * a bad sector map then append bad entries to end of badmap * * tablata from memory into the buffer. If the * * desired CP/M sector is not contained in the disk buffer, the * * buffer is first f***************************************************************** * * * DPH save area. Each entry is 4 bytes long: *i b,8 call movbyt ;Move the rest of information into the table jmp badl bade: shld badptr ;Restore new bad map pointer  xchg mov a,m ;Pick up sector number of of bad sector map inx h mov h,m mov l,a shld truesec call fill ;Read in ba****************************** * * * Read routine to buffer data from the disk. If the sector * * requested from CP/M e. * * * ***************************************************************** getbad: mvi m,1 ;Set drive initililushed to the disk if it has ever been * * written into, then a read is performed into the buffer to get * * the desired secto * 0 - LSB of DPH address * * 1 - MSB of DPH address * * 2 - Sector size code (1 = 128, 2 = 256, 3 = 512... * * 3 -  badret: pop d pop b ret overflo:lxi h,omes call message jmp badret omes: db 0dh, 0ah, 'BAD MAP OVERFLOW!', 0dh, 0d sector map into the buffer jc badret ;Ignore the map if it can't be read lhld badptr ;Pick up bad map pointer lxi d,is in the buffer, then the data is simply * * transferred from the buffer to the desired dma address. If * * the buffer does nzed push b push d lda cpmdrv ;Pick up current drive mov h,a ;Call drive routine to return a pointer to mvi l,d$bad r. Once the correct sector is in memory, the * * buffer written indicator is set, so the buffer will be * * flushed, then the Bad map has been initilized (0 = Uninitilized) * * * ***************************************************************** ah, 0 nobad: lxi h,0 ;Used by device drives to indicate no bad ret ; sector map badptr: dw badmap ;Pointer to next a2 ot contain the desired sector, the buffer is * * flushed to the disk if it has ever been written into, then * * filled with thount loop dtslop: dcr b ;Test if done with compare jz move ;Yes, match. Go move the data ldax d ;Get a byte to compare i 7fh ;Forget the side bit mov h,a dcx h ;Temporary adjustment divloop:dcr b ;Update repeat count jz divdone ora a  buffer dad h dad h dad h dad h dad h dad h lxi d,buffer ;Beginning address of buffer dad d ;Form beginning add* sector currently in the buffer. If no match is made, the * * buffer is flushed if necessary and the correct sector read * * ********************************** * * * Move has been modified to cause either a transfer into or out * * the buffer.e sector from the disk that contains the * * desired CP/M sector. * * * ***************************************** cmp m ;Test for match inx h ;Bump pointers to next data item inx d jz dtslop ;Match, continue testing ************* mov a,h rar mov h,a mov a,l rar ;Divide the CP/M sector # by the size ; of the physical sectors mov l,a jmp ress of sectgr to transfer xchg ;DE = address in buffer lxi h,0 ;Get DMA address, the 0 is modified t/ ; contain thefrom the disk. * * * ***************************************************************** redwrt: mvi b,0 ;The 0  * * * ***************************************************************** move: lda cpmsec ;Get the CP/M secto************************ read: xra a ;Set the command type to read if nostand ne 0 sta unaloc ;Clear unallocated write **************************************************** * * * Drive, track, and sector don't match, flush the buffer if * divloop ; divdone:inx h mov a,h ora c ;Restore the side bit mov h,a shld truesec ;Save the physical sector number  DMA address cpmdma equ $-2 mvi a,0 ;The zero gets modified to contain ; a zero if a read, or a 1 if write rdwr equ $-is modified to contain the log2 secsiz equ $-1 ; of the physical sector size/128 ; on the currently selected disk lhld r to transfer dcr a ;Adjust to proper sector in buffer ani 0 ;Strip off high ordered bits secpsec equ $-1 ;The 0 is modiflag endif rwent: sta rdwr ;Save command type ***************************************************************** *  * necessary and then refill. * * * ***************************************************************** call filllxi h,cpmdrv ;Pointer to desired drive,track, and sector lxi d,bufdrv ;Pointer to buffer drive,track, and sector mvi b,6 ;C1 ana a ;Test which kind of operation jnz into ;Transfer data into the buffer outof: call mov128 lda error ;Get the bucpmsec ;Get the desired CP/M sector # mov a,h ani 80h ;Save only the side bit mov c,a ;Remember the side mov a,h anfied to represent the # of ; CP/M sectors per physical sectors mov l,a ;Put into HL mvi h,0 dad h ;Form offset into * * Redwrt calculates the physical sector on the disk that * * contains the desired CP/M sector, then checks if it is the *  ;Fill the buffer with correct physical sector rc ;No good, return with error indication *******************************3 ffer error flag ret into: xchg ; call mov128 ;Move the data, HL = destination ; DE = source mvi a,1 sta bufwrec call jumpbuf lxi b,buffer ;Set the DMA address mvi l,d$sdma call jumpbuf rwop: mvi l,0 ;Get operation address  ;Check for alternate sectors di ;Reset interrupts xra a ;Reset buffer written flag sta bufwrtn mvi b,retries ;Maxrty) check ora a jnz fnaloc ;Skip if not an allocated write lda unaloc ;Check unallocated write in progress flag orao bufwrtn equ $-1 ora a ;Test if written into rz ;Not written, all done mvi a,d$write sta rwop+1 call prep ;Do th buffer with a new sector from the disk. * * * ***************************************************************** filtn ;Set buffer written into flag mvi a,0 ;Check for directory write writtyp equ $-1 dcr a ;Test for a directory write  call jumpbuf pop b ;Restore the retry counter mvi a,0 ;No error exit status rnc ;Return no error dcr b ;Update timum number of retries to attempt retrylp:push b ;Save the retry count mvi l,d$sel2 ;Select drive call jumpbuf lhld  a jz fwritin ;We are doing an allocated write lhld cblock ;Get current block address xchg lhld oblock ; and old ble physical write sta error ;Set up the error flag ret ***************************************************************** l: call flush ;Flush buffer first rc ;Check for error lxi d,cpmdrv ;Update the drive, track, and sector lxi h,bufdrv mvi a,0 rnz ;No error exit ***************************************************************** * * * Flush writes he retry counter stc ;Assume retry count expired mvi a,0ffh ;Error return rz ;Return sad news mov a,b cpi retriesalttrk ;Track number -> (hl) mov a,h ;Test for track zero ora l push h ;Save track number mvi l,d$home cz jumpbock address mov a,d ;Compare old versus new cmp h jnz awritin ;Different, clear unallocated writting mode mov a,e cm * * * Prep prepares to read/write the disk. Retries are attempted. * * Upon entry, H&L must contain the read or write lxi b,5 ;Number of bytes to move call movbyt ;Copy the data lda rdwr ;Test read write flag ora a jz fread ;Skip wrthe contents of the buffer out to the disk if * * it has ever been written into. * * * ****************************/2 jnz retrylp ;Try again push b ;Save retry count mvi l,d$home ;Home drive after (retries/2) errors call jumpbuf pouf pop b ;Restore track # mvi l,d$strk call jumpbuf lhld altsec ;Sector -> (hl) mov b,h mov c,l mvi l,d$ssp l jnz awritin lxi h,cpmdrv ;Test for different drive lda unadrv cmp m jnz awritin ;Drive is different, clear unallooperation * * address. * * * ***************************************************************** prep: call altite type check if reading lda writtyp ;0 = alloc, 1 = dir, 2 = unalloc if nostand ne 0 ;Do non standard (but quick and di************************************* flush: mvi a,0 ;The 0 is modified to reflect if ; the buffer has been written intp b jmp retrylp ;Try again ***************************************************************** * * * Fill fills the4 cated mode ret ;Unallocated write, do nothing... fnaloc: dcr a jz awritin ;Do a directory write ;We are now doing ;Bump (hl) to point to start of dispatch table pop d ;Real (hl) -> (de) mov a,e ;Move offset number into (a) rlc ;Ea ***************************************************************** jumpbuf:lda bufdrv ;Dispatch with bufdrv for drive mov hld bufsec shld altsec ret alt2: push h ;Save current bad map entry address mov a,c ;Move drive into (a) cmp m ;Chad sta rwop+1 call prep ;Read the physical sector the buffer sta error ;Set the error status ret ******************naltered. * * * ***************************************************************** alt: lxi h,badmap ;Address of ba an unallocated write lhld cblock ;Save current block number shld oblock lda cpmdrv ;Save drive that this block belongs ch entry is 2 bytes mov e,a ;Make an offset mvi d,0 dad d ;(hl) = **Routine mov a,m ;Pick up address of handler for sh,a jumper: push d push b push h mov a,h ;Logical drive into (a) lxi d,dsttab ;Drive specification pointer table jueck if drive in table matches jnz altmis ;Does not match skip this entry inx h ;Point to LSB of alternate track lda buft*********************************************** * * * Jumpbuf, jumper are used to dispatch to a low level device * * sd map -> (hl) lda bufdrv ;Pick up drive number currently working on mov c,a ;Move drive into (c) for speed in search all:to sta unadrv mvi a,1 ;Set unallocated write flag sta unaloc ret ; and we do nothing about the write awritin:xraelected inx h ; function mov h,m mov l,a ;(hl) = *routine mov a,c ;Logical in (a) pop b ;Restore saved registers mpl: mov c,a ;Save logical in (c) ldax d mov l,a inx d ldax d mov h,a ;Get a DST pointer in (hl) inx d mov a,c rk ;Pick up LSB of buffer track cmp m jnz altmis inx h ;Point to MSB alternate track lda buftrk+1 ;Pick up MSB of buffubroutine. Jumper is called with the drive in (h) and the * * routine number (see description above) in (l). It passes * * a xchg lhld badptr ;Get bad map pointer xchg ; -> (de) mov a,d ;Check if at end of bad map table cmp h jnz alt2 ;S a ;Clear unallocated writting mode sta unaloc else ;Do standard unallocated test sui 2 ;Test for an unallocated w pop d pchl ***************************************************************** * * * Check for alternate sectors in;Logical in (a) sub m ;Subtract from first entry in DST jnc jumpl ;Keep scanning table till correct driver found inx her track cmp m jnz altmis inx h ;Point to LSB of alternate sector lda bufsec ;Pick up LSB of buffer sector cmp m jlong the (bc) and (de) registers unaltered. Jumpbuf is * * a call to jumper with the drive number from bufdrv. * * * till more mov a,e cmp l jnz alt2 ;Still more lhld buftrk ;No alternate sector so use selected sector shld alttrk lrite rz endif fwritin:lda secsiz ;Check for 128 byte sectors dcr a rz ;No deblocking needed fread: mvi a,d$re bad sector table. If an * * alternate sector is found replace alttrk and altsec with * * new sector number else pass along u5 nz altmis inx h ;Point to MSB of alternate sector lda bufsec+1 ;Pick up MSB of buffer sector cmp m jnz altmis ;Found a******************** * * * Utility routine to output the message pointed at by (hl) * * terminated with a null. * *************************************************************** * * * Return DPH pointer. Enter with (de) with DPH basopdone equ 02h ;Operation done complt equ 04h ;Seek complete tmout equ 08h ;Time out wfault equ 10h ;Write fault drv * pointer in HL. * * * ***************************************************************** mov128: lxi b,128 ;L* * * ***************************************************************** if hdca ne 0 ;Want HDC3 or 4 controller inn alternate sector inx h ;Point to real info on the alternate sector lxi d,alttrk xchg ;MOVLOP (de) = source, (hl) = de * * ***************************************************************** message:mov a,m ;Get a character of the messae address * * and (a) with logical drive number. Returns with DPH address * * in (hl). * * * *****************rdy equ 20h ;Drive ready index equ 40h ;Delta index ; Control port (50) hdfren equ 01h ;Enable external drivers hdength of transfer movbyt: xra a ;Check if host processor is a Z80 adi 3 jpo z80mov ;Yes, Its a Z80 so use block move mcluded ? hdorg equ 50h ;Hard Disk Controller origin hdstat equ hdorg ;Disk Status hdcntl equ hdorg ;Disk Control hst push b lxi b,4 call movbyt ;Move alternate sector info in correct place pop b pop h ret altmis: pop h ;Currege inx h ;Bump text pointer ora a ;Test for end rz ;Return if done push h ;Save pointer to text mov c,a ;Output ************************************************ retdph mov l,a ;Move logical drive into (l) mvi h,0 dad h ;Multiply byrun equ 02h ;Enable controllers state machine hdclok equ 04h ;Clock source control bit, high = disk hdwprt equ 08h ;Writ8080: ldax d ;Get a byte of source mov m,a ;Move it inx d ;Bump pointers inx h dcx b ;Update counter mov a,b ;Tesdreslt equ hdorg+1 ;Disk Results hdcmnd equ hdorg+1 ;Disk Commands hdskomp equ hdorg+2 ;Seek complete clear port (on HDCnt alternate did not match lxi d,9 ;Bump pointer by the length of an entry dad d jmp all ;Loop for more *************character in C call cout ;Output the character pop h ;Restore the pointer jmp message ;Continue until null reached * 16 (size of DPH) dad h dad h dad h dad d ;(hl) = pointer to DPH ret *********************************************e protect a drive ; Result port (51) retry equ 02h ;Retry flag ; Command port (51) idbuff equ 0 ;Initialize datat for end ora c jnz m8080 ret z80mov: xchg ;Source in (hl), Destination in (de) dw 0b0edh ;ldir xchg ret **4) hdfunc equ hdorg+2 ;Function port hddata equ hdorg+3 ;Data port ; Status port (50) tkzero equ 01h ;Track zero **************************************************** * * * Mover moves 128 bytes of data. Source pointer in DE, Dest * **************************************************************** * * * The following code is for the Diskus Hard disk 6  buffer pointer rsect equ 1 ;Read sector wsect equ 5 ;Write sector isbuff equ 8 ;Initialize header buffer pointer ; ot too many errors stc ;Error flag ret hdtran: mov h,b ;Sector translation is handled via mov l,c ; physical s first sector - 1 call hdd2 ;Select drive mvi c,0 call hdhome ;Home the drive hdwrld: pop psw ;Restore sector popugart M26's have 30 ms head settle xra a ;HL/2 + HL (same as HL*1.5) mov a,h rar mov d,a mov a,l rar mov e,a d dw hdtran ;Sector translation dw hdldrv ;First time select dw hddrv ;General select dw hdhome ;Home current seleve not ready error in hdstat ;Test if ready yet ani drvrdy jnz hdtdel if not fujitsu lxi h,0 ;Time one revolutioFunction port (52) pstep equ 04h ;Step bit nstep equ 0ffh-pstep ;Step bit mask null equ 0fch ;Null command ; Misc cector header skewwing inx h ret hdldrv: sta hdcur ;Save logical disk call divlog ;Divide by logical disks per drive h ;Restore DMA address inr a sta hdsect cpi 13 ;Past BDOS ? rz ;Yes, all done inr h ;Update DMA address inad d endif shld settle ;Save the count for timeout delay endif call hdhome hdl2: lda hdcur ;Load logical drivcted drive dw hdseek ;Seek to selected track dw hdsec ;Select sector dw hddma ;Set DMA address dw hdread ;Read an of the drive mvi c,index in hdstat ana c mov b,a ;Save current index level in B hdinxd1:in hdstat ana c cmp b onstants hdrlen equ 4 ;Sector header length seclen equ 512 ;Sector data length ************************************** mov a,c sta hddisk ;Save new physical drive call hdptr ;Get track pointers mov a,m ;Get current track inr a ;r h shld hdadd push h push psw hdwrrd: lxi b,retries*100h+0 ;Retry counter hdwr: push b ;Save the retry count call he lxi d,dphhd0 ;Start of hard disk DPH's mvi c,3 ;Hard disk sector size equals 512 bytes jmp retdph dcrc: dcr c ;C sector dw hdwrite ;Write a sector dw nobad ;No bad sector map hdwarm: call divlog ;Get physical drive number in (c ;Loop untill index level changes jz hdinxd1 hdindx2:inx h in hdstat ;Start counting untill index returns to ana c ; *************************** * * * Device Specification Table for HDCA controller driver * * * ***************Check if -1 jnz hdl2 ;Nope, allready accessed ori null ;Select drive out hdfunc mvi a,hdfren+hdclok ;Enable driversdread ;Read the sector pop b jnc hdwrld ;Test for error dcr b ;Update the error count jnz hdwr ;Keep trying if nonditional decrement C routine ret divlog: mvi c,0 divlx: sui hdlog rc inr c jmp divlx hddrv: sta hdcur call di) xra a lxi h,ccp-200h ;Initial DMA address push h sta head ;Select head zero inr a ; 1 -> (a) push psw ;Saveprevious state cmp b jnz hdindx2 if m10 ;Memorex M10's have 40 ms head settle dad h ;HL*2 endif if m26 ;Sh************************************************** hddst: db maxhd*hdlog ;Number of logical drives dw hdwarm ;Warm boot  out hdcntl mvi c,239 ;Wait 2 minutes for disk ready lxi h,0 hdtdel: dcx h mov a,h ora l cz dcrc jz zret ;Dri7 vlog ;Get the physical drive # hdd2: mov a,c sta hddisk ;Select the drive ori null out hdfunc mvi a,hdfren+hdrun+hdranslated sector number (1-32) mvi a,0e0h ;Get the head number ana c rlc rlc rlc sta head ;Save the head number  high step line dcr b ;Update repeat count jnz sloop ;Keep going the required # of tracks jmp wsdone hddma: mov h,bret process:in hdstat ;Wait for command to finish mov b,a ani opdone jz process mvi a,hdfren+hdrun+hdclok ;Write prjnz deloop ret endif hdseek: call hdptr ;Get pointer to current track mov e,m ;Get current track mov m,c ;Updat inx h in hddata mov m,a inx h in hddata mov m,a inx h in hddata mov m,a inx h dcr b jnz rtloop ret clok+hdwprt ;Write protect out hdcntl ret hdhome: call hdptr ;Get track pointer mvi m,0 ;Set track to zero in hds getspt: mvi a,hdspt ret else hdsec: mov a,c call divspt adi hdspt ana a cz getspt sta hdsect mov a,c sta ;Save the DMA address mov l,c shld hdadd ret wsdone: in hdstat ;Wait for seek complete to finish ani complt jzotect out hdcntl in hdstat ani tmout ;Timed out ? stc rnz in hdreslt ani retry ;Any retries ? stc rnz xre the track mov a,e ;Need to seek at all ? sub c rz cmc ;Get carry into direction jc hdtrk2 cma inr a if fu hdwrite:call hdprep ;Prepare header rc xra a out hdcmnd lhld hdadd mvi b,seclen/4 wtloop: mov a,m ;Move 4 bytes tat ;Test status ani tkzero ;At track zero ? rz ;Yes if not fujitsu hdstepo:in hdstat ;Test status ani tkzer head getspt: mvi a,hdspt dcr c ret divspt: mvi c,0 divsx: sui hdspt rc inr c jmp divsx endif hdread: call h wsdone in hdskomp ;Clear sdone bit on an HDCA4 ret if m26 hdsec: mvi a,01fh ;For compatibility with Cbios revs. a a ret hdprep: in hdstat ani drvrdy stc rnz mvi a,isbuff ;Initialize pointer out hdcmnd call build ori 0ch jitsu hdtrk2: jmp accok else hdtrk2: call accok jmp hddelay endif accok: mov b,a ;Prep for build call build sloo out hddata inx h mov a,m out hddata inx h mov a,m out hddata inx h mov a,m out hddata inx h dcr b jnz o ;At track zero ? jz hddelay mvi a,1 stc call accok ;Take one step out jmp hdstepo else xra a jmp accokdprep rc xra a out hdcmnd cma out hddata out hddata mvi a,rsect ;Read sector command out hdcmnd call process ; 2.3 and 2.4 ana c ;Mask in sector number (0-31) cz getspt ;Translate sector 0 to sector 32 sta hdsect ;Save t out hdfunc lda head out hddata ;Form head byte call hdptr ;Get pointer to current drives track mov a,m ;Form trap: ani nstep ;Get step pulse low out hdfunc ;Output low step line ori pstep ;Set step line high out hdfunc ;Outputwtloop mvi a,wsect ;Issue write sector command out hdcmnd call process rc mvi a,wfault ana b stc rz xra a  endif if not fujitsu hddelay:lhld settle ;Get hddelay deloop: dcx h ;Wait 20ms mov a,h ora l inx h dcx h  rc xra a out hdcmnd mvi b,seclen/4 lhld hdadd in hddata in hddata rtloop: in hddata ;Move four bytes mov m,a8 ck byte out hddata ana a mvi b,80h jz zkey mvi b,0 zkey: lda hdsect ;Form sector byte out hddata mov a,b out ack seek routine fdsec equ fdorig+0fh ;Disk Jockey 2D set sector routine fddma equ fdorig+12h ;Disk Jockey 2D set DMA address  be changed. * * * ***************************************************************** if maxfd ne 0 ;Include Discudlhome ;Home drive dw fdseek ;Seek to specified track dw fdssec ;Set sector dw fddma ;Set DMA address dw fdread ;Re ;Current physical head number hdsect: db 0 ;Current physical sector number hdtrak: db 0ffh ;Track pointer for each drivqu 20h ;Side bit from controller io equ fdorig+3f8h ;Start of I/O registers dreg equ io+1 cmdreg equ io+4 clrcmd equ 0d0h hddata mvi a,hdfren+hdrun+hdclok ;Write protect out hdcntl mvi a,hdfren+hdrun+hdclok+hdwprt ;Write protect out hdcntl  fdread equ fdorig+15h ;Disk Jockey 2D read routine fdwrite equ fdorig+18h ;Disk Jockey 2D write routine fdsel equ fdorig+1bh s 2D ? ;note: DJ2D/B origin equate move to start of CBIOS ;fdorig equ 0f800h ;Origin of Disk Jockey PROM fdboot equ fdorig+0ad a sector dw fdwrite ;Write a sector dw nobad ;No bad sector map ****************************************************e db 0ffh ;All drive default to an uncalibrated db 0ffh ; state (ff) db 0ffh settle: dw 0 ;Time delay constant  ***************************************************************** * * * Device Specification Table for the Disk Jockexra a ret hdptr: lhld hddisk ;Get a pointer to the current drives mvi h,0 ; track position xchg lxi h,hdtrak ;Disk Jockey 2D select drive routine fdtstat equ fdorig+21h ;Disk Jockey 2D terminal status routine fdstat equ fdorig+27h ;Dis0h ;Disk Jockey 2D initialization fdcin equ fdorig+03h ;Disk Jockey 2D character input routine fdcout equ fdorig+06h ;Disk Joc************* * * * Floppy disk warm boot loader * * * ***************************************************for head settle endif ***************************************************************** * * * The following equay 2D/B * * * ***************************************************************** fddst: db maxfd ;Number of logical dad d ret build: lda head ;Build a controller command byte ral ral ral ral lxi h,hddisk ora m xri 0f0h rek Jockey 2D status routine fderr equ fdorig+2ah ;Disk Jockey 2D error, flash led fdden equ fdorig+2dh ;Disk Jockey 2D set denskey 2D character output routine fdhome equ fdorig+09h ;Disk Jockey 2D track zero seek fdseek equ fdorig+0ch ;Disk Jockey 2D tr************** fdwarm: mov c,a call fdsel ;Select drive A mvi c,0 ;Select side 0 call fdside wrmfail:call fdhome ;Ttes relate the Morrow Designs 2D/B * * controller. If the controller is non standard (0F800H) * * only the FDORIG equate needdrives dw fdwarm ;Warm boot dw fdtran ;Sector translation dw fdldrv ;Select drive 1 dw fdsel2 ;Select drive 2 dw ft hdcur: db 0 ;Current logical disk hdadd: dw 0 ;DMA address hddisk: db 0 ;Current physical disk number head: db 0 ity routine fdside equ fdorig+30h ;Disk Jockey 2D set side routine fdram equ fdorig+400h ;Disk Jockey 2D RAM address dblsid e9 rack 0, single density jc wrmfail ;Loop if error ;The next block of code re-initializes ; the warm boot loader ave it inx d ;Bump pointers inx h dcx b ;Bump counter mov a,b ;Check if done ora c jnz wrmcpy ; if not, loop ny errors, flash the light ;Load track 1, sector 1, sector 3 (partial), sector 2 (1024 byte sectors) t1boot: mvi c,1 ;Tra d ;Restore address of xlt table sideone:xchg ;hl <- &(translation table) dad b ;bc = offset into table mov l,m ;hl <- mov c,a call fdsec ;Set up the sector lxi h,ccp-100h ;Memory address of sector - 100h newdma equ $-2 lxi d,100h ;Updat dcr b ;Bump error count jnz wrmfrd jmp fderr ;Error, flash the light fdtran: inx b push d ;Save table address pusfor track 0 mvi a,5-2 ;Initialize the sector to read - 2 sta newsec lxi h,ccp-100h ;First revolution DMA - 100h shld ne lxi b,ccp+0f00h ;Address for sector 2 lxi d,10*100h+2 ;Retry count + sector 2 call wrmread xra a ;Clear error indicack 1 call fdseek lxi b,ccp+0b00h ;Address for sector 1 lxi d,10*100h+1 ;Retry count + sector 1 call wrmread lxi b,ccp+ physical sector mvi h,0 ret sidetwo:call fdgsid ;Check out number of sides jz sidea ;Single sided pop psw ;Retriee DMA address dad d nowrp: shld newdma ;Save the updated DMA address mov b,h mov c,l call fddma ;Set up the new DMA ah b ;Save sector # call fdget ;Get DPH for current drive lxi d,10 ;Load DPH pointer dad d mov a,m inx h mov h,m wdma ;Load all of track 0 t0boot: mvi a,5-2 ;First sector - 2 newsec equ $-1 inr a ;Update sector # inr a cpi 2tor ret wrmread:push d call fddma ;Set DMA address pop b call fdsec ;Set sector wrmfrd: push b ;Save error count 0f00h ;Address for sector 2 lxi d,10*100h+3 ;Retry count + sector 3 call wrmread lxi b,0300h ;Size of partial sector ve adjusted sector pop b cma ;Make sector request positive inr a mov c,a ;Make new sector the requested sector pop ddress lxi b,retries*100h+0;Maximum # of errors, track # wrmfred:push b call fdseek ;Set up the proper track call fdread mov l,a mov a,m ;Get # of CP/M sectors/track ora a ;Clear carry rar ;Divide by two sub c ;Subtract sector number 7 ;Size of track in sectors + 1 jc nowrap ;Skip if not at end of track jnz t1boot ;Done with this track sui 27-6 ;Back call fdread ;Read a sector jc wrmerr ;Do retry stuff on error call fdstat ;Sector size must be 1024 bytes ani 0ch ;Mlxi d,ccp+1300h ;Address for sector 3 lxi h,ccp+0f00h ;Address of sector 3 wrmcpy: mov a,m ;Get a byte and stax d ; sd call sideone mvi a,80h ;Side two bit ora h ; and sector mov h,a ret fdldrv: sta fdlog ;Save logical drive mo ;Read the sector pop b jnc t0boot ;Continue if no error dcr b jnz wrmfred ;Keep trying if error jmp fderr ;Too ma push psw ;Save adjusted sector jm sidetwo sidea: pop psw ;Discard adjusted sector pop b ;Restore sector requested pop up to sector 6 lxi h,ccp-80h ;Memory address of sector - 100h shld newdma nowrap: sta newsec ;Save the updated sector # ask length bits sui 0ch ;Carry (error) will be set if < 0c0h wrmerr: pop b ;Fetch retry count rnc ;Return if no error : v c,a ;Save drive # mvi a,0 ;Have the floppies been accessed yet ? flopflg equ $-1 ana a jnz flopok mvi b,17 ;FlopH.DPB pop psw ;Offset to correct DPB ral ral ;Make 0, 10, 20, 30 mov c,a mvi b,0 ;Make offset dad b ;(hl) is noh ;Save pointer to proper XLT call fdget ;Get pointer to proper DPH pop d lxi b,2 ;Copy XLT pointer into DPH call mov 0 parameters db 0ffh ;Drive 0 track address db 9 ;Drive 1 parameters db 0ffh ;Drive 1 track address db 9 ;Drive 2 pg ;Select new drive mov c,a call fdsel call fdlhome ;Recalibrate the drive lxi h,1 ;Select sector 1 of track 2 shld side A, 1 = Side B pop b jmp fdsec fdgsid: lxi h,fdlsid ;Side flag table lda fdlog ;Drive number push d mov e,a pies havn't been accessed lxi h,fdboot ;Check if 2D controller is installed mvi a,(jmp) clopp: cmp m ;Must have 17 jumps w a DPB pointer xchg ;Put proper DPB address in DPH.DPB mov m,e inx h mov m,d lxi h,15 ;Offset to DPB.SIZ dad d byt lxi d,8 ;Offset to DPB pointer in DPH dad d ;HL <- &DPH.DPB push h call fdgsid ;Get pointer to side flag table enarameters db 0ffh ;Drive 2 track address db 9 ;Drive 3 parameters db 0ffh ;Drive 3 track address db 9 ;Current param truesec inx h shld cpmtrk xra a ;Make sure we are doing a read sta rdwr call fill ;Fill in buffer with sector jc ;Make offset mvi d,0 dad d ;Offset to proper entry pop d mov a,m ;Set up flags ora a ret fdinit: dw 0 ;Initial jnz zret inx h inx h inx h dcr b jnz clopp lxi d,fdinit ;Initialization sequence lxi h,fdorig+7e2h ;Load address  mov c,m ;Fetch sector size code fdget: lda fdlog ;Return proper DPH lxi d,dphfd0 jmp retdph fdsel2: sta fdlog mov ctry lda fdldst ;Get drive status ani dblsid ;Check double sided bit mov m,a ;Save sides flag lxi d,dpb128s ;Base for eters db 0 ;Side desired db 1 ;Sector desired db 0 ;Track desired db 0 ;Header image, track db 0 ;Sector db 0zret ;Test for error return call fdstat ;Get status on current drive sta fdldst ;Save drive status ani 0ch ;Mask in seization bytes loaded onto 2D/B dw 1800h ;Head loaded timeout dw 0 ;DMA address db 0 ;Double sided flag db 0 ;Read he lxi b,30 ;Byte count call movbyt ;Load controller RAM mvi a,0ffh ;Start 1791 sta dreg mvi a,clrcmd ;1791 reset st,a jmp fdsel fdlhome:mvi c,0 ;Select side 0 call fdside jmp fdhome ;Do actual home fdssec: push b ;Save sector nusingle sided DPB's jz sideok lxi d,dpb128d ;Base of double sided DPB's sideok: xchg pop d ;(HL) -> DPB base, (DE) -> &DP ;Side db 0 ;Sector dw 0 ;CRC fdlog: db 0 fdldst: db 0 ;Floppy drive status byte fdlsid: rept maxfd db 0ffh ;Dctor size bits push psw ;Used to select a DPB rar lxi h,xlts ;Table of XLT addresses mov e,a mvi d,0 dad d push ader flag db 07eh ;Drive select constant db 0 ;Drive number db 8 ;Current disk db 0 ;Head loaded flag db 9 ;Drivea cmdreg mvi a,1 ;Set 2D initialized flag sta flopflg flopok: call flush ;Flush buffer since we are using it lda fdlomber mov a,b ;Check side select bit rlc ;Move high bit to bit zero ani 1 mov c,a call fdside ;Call select side 0 =; ouble sided flag 0 = single, 1 = double endm endif if (maxfd ne 0) or (maxdm ne 0) **********************************29,30,31,32 db 49,50,51,52,53,54,55,56 db 9,10,11,12,13,14,15,16 db 33,34,35,36,37,38,39,40 db 57,58,59,60,61,62,63,64 ,18,24 db 4,10,16,22 xlt256: db 0 db 1,2,19,20,37,38 db 3,4,21,22,39,40 db 5,6,23,24,41,42 db 7,8,25,26,43,44 db ************* dpb256s:dw 52 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 1 ;EXM dw 242 ;DSM dw 127 ;DRM db 02.0. These tables * * define the sector translation that occurs when mapping CP/M * * sectors to physical sectors on the disk. * ***************************************************************** dpb128s:dw 26 ;CP/M sectors/track db 3 ;BSH db ******************************* * * * Xlts is a table of address that point to each of the xlt * * tables for each sec db 17,18,19,20,21,22,23,24 db 41,42,43,44,45,46,47,48 ***************************************************************** *9,10,27,28,45,46 db 11,12,29,30,47,48 db 13,14,31,32,49,50 db 15,16,33,34,51,52 db 17,18,35,36 xlt512: db 0 db 1,2,c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF db 2 ;256 byte sectors ************************************************* There is one skew * * table for each of the possible sector sizes. Currently the * * tables are located on track 0 sectors 6 7 ;BLM db 0 ;EXM dw 242 ;DSM dw 63 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 16 ;CKS dw 2 ;OFF db 1 ;128 byte secttor size. * * * ***************************************************************** xlts: dw xlt128 ;Xlt for 128  * * Each of the following tables describes a diskette with the * * specified characteristics. * * * *****3,4,17,18,19,20 db 33,34,35,36,49,50,51,52 db 5,6,7,8,21,22,23,24 db 37,38,39,40,53,54,55,56 db 9,10,11,12,25,26,27,28 **************** * * * The following DPB defines a diskette as 512 byte sectors, * * double density, and single sided.and 8. They are * * loaded into memory in the Cbios ram by the cold boot routine. * * * ******************************ors ***************************************************************** * * * The following DPB defines a diskette forbyte sectors dw xlt256 ;Xlt for 256 byte sectors dw xlt512 ;Xlt for 512 byte sectors dw xlt124 ;Xlt for 1024 byte secto************************************************************ **************************************************************** db 41,42,43,44,57,58,59,60 db 13,14,15,16,29,30,31,32 db 45,46,47,48 xlt124: db 0 db 1,2,3,4,5,6,7,8 db 25,26,27,28, * * * ***************************************************************** dpb512s:dw 60 ;CP/M sectors/track db *********************************** xlt128: db 0 db 1,7,13,19,25 db 5,11,17,23 db 3,9,15,21 db 2,8,14,20,26 db 6,12 256 byte sectors, * * double density, and single sided. * * * ****************************************************rs ***************************************************************** * * * Xlt tables (sector skew tables) for CP/M * * * * The following DPB defines a diskette for 128 byte sectors, * * single density, and single sided. * * < 4 ;BSH db 15 ;BLM db 0 ;EXM dw 280 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF db 3 ouble density, and double sided. * * * ***************************************************************** dpb512d:owing DPB defines a diskette as 256 byte sectors, * * double density, and double sided. * * * *********************20h ;Read sector command wrsect equ 21h ;Write a sector command gstat equ 22h ;Get drive status dmsdma equ 23h ;Set DMA a******************************** * * * The following DPB defines a diskette for 128 byte sectors, * * single density,  db 0 ;EXM dw 599 ;DSM dw 255 ;DRM db 0f0h ;AL0 db 0 ;AL1 dw 64 ;CKS dw 2 ;OFF db 4 ;1024 byte sectors  ;512 byte sectors ***************************************************************** * * * The following DPB definesdw 120 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;EXM dw 561 ;DSM dw 255 ;DRM db 0f0h ;AL0 db 0 ;AL1 ******************************************** dpb256d:dw 104 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;EXM dwddress intrqc equ 24h ;Set Interrupt request dmhaltc equ 25h ;Halt command bracha equ 26h ;Channel branch setcha equ 27h and double sided. * * * ***************************************************************** dpb128d:dw 52 ;CP/M se endif ***************************************************************** * * * The following equates relate the Mor a diskette as 1024 byte sectors, * * double density, and single sided. * * * ************************************* dw 64 ;CKS dw 2 ;OFF db 3 ;512 byte sectors ***************************************************************** *  486 ;DSM dw 255 ;DRM db 0f0h ;AL0 db 0 ;AL1 dw 64 ;CKS dw 2 ;OFF db 2 ;256 byte sectors ***************** ;Set channel address setcrc equ 28h ;Set CRC retry count rdtrck equ 29h ;Read track command wrtrck equ 2ah ;Write track cctors/track db 4 ;BSH db 15 ;BLM db 1 ;EXM dw 242 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS drow Designs DJDMA * * controller. * * * ***************************************************************** i**************************** dp1024s:dw 64 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;EXM dw 299 ;DSM dw 1 * * The following DPB defines a diskette as 1024 byte sectors, * * double density, and double sided. * * * **************************************************** * * * The following DPB defines a diskette as 512 byte sectors, * * dommand serout equ 2bh ;Serial ouput through bit banger serial port senabl equ 2ch ;Enable serial input trksiz equ 2dh ;Setw 2 ;OFF db 1 ;128 byte sectors ***************************************************************** * * * The follf (maxdm ne 0) or (maxmf ne 0) dmchan equ 50h ;Default channel address dmkick equ 0efh ;Kick I/O port address rdsect equ 27 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF db 4 ;1024 byte sectors ********************************************************************************************** dp1024d:dw 128 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM =  number of tracks setlog equ 2eh ;Set logical drives readm equ 0a0h ;Read from controller memory writem equ 0a1h ;Write to;Set track 0 DMA address dw ccp-512 ;First track DMA address - boot loader db 0 db rdtrck ;Read track command db 0 ;T inx h mvi m,(low dmwchn) ;Low address byte inx h mvi m,(high dmwchn) ;High address byte inx h mvi m,0 dmwbad: lxi h push psw ;Save adjusted sector jm dmside2 dmsidea:pop psw ;Discard adjusted sector pop b ;Restore sector requested f maxdm ne 0 dmdst: db maxdm ;Number of logical drives dw dmwarm ;Warm boot dw dmtran ;Sector translation dw dmldrv ; ;Room for the halt dmwsec: dw 0ffffh, 0ffffh ;Do not load boot loader dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;22 sectors to  controller memory dmfstp equ 3*341/10 ;Fast stepping rate constant is 3 ms * 34.1 dmfset equ 15*341/10 ;Fast settling rate rack 0 db 0 ;Side 0 db 0 ;Drive 0 dw dmwsec ;Sector load/status map db 0 dmwst: db 0 ;Track read status db dmsdma,dmwend-1 ;Pointer to end of command structure call docmd ;Read in tracks lda dmwst ;Get track read status ani 40h jz pop d ;Restor address of xlt table dmside1:xchg ;hl <- &(translation table) dad b ;bc = offset into table mov l,m ;hl Select drive 1 dw dmselr ;Select drive 2 dw dmhome ;Home drive dw dmseek ;Seek to specified track dw dmssec ;Set secbe loaded dw 0, 0ffffh, 0ffffh, 0ffffh ;First 2 sectors on track 2 dmselr: sta dmlog mvi b,0 ;8 inch logical drives starconstant is 15 ms * 34.1 n$dubl equ 80h ;Double density n$2side equ 40h ;2 sided drive serin equ 03eh ;Address of seri dw ccp+dmtrck ;DMA address for track 1 db 0 db rdtrck db 1 ;Track 1 db 0 ;Side 0 db 0 ;Drive 0 dw dmwsec+26 ;Mdmwbad ;Loop on 'terrible' errors like no disk lxi b,300h ;3/4 K bytes of sector 3 needs to be moved lxi d,buffer ;Sector <- physical sector mvi h,0 ret dmside2:call dmstat ani 20h jz dmsidea pop psw ;Retrieve adjusted sector pop b tor dw dmdma ;Set DMA address dw dmread ;Read a sector dw dmwrite ;Write a sector dw nobad ;No bad sector map dmtt at zero jmp dmsel2 dmtran: inx b push d ;Save table address push b ;Save sector # call dmget lxi d,10 dad d al input data, (status - 1) ***************************************************************** * * * Device Specificaap is loaded right after track 0 status map db 0 db 0 ;Track read status db dmsdma dw buffer ;Sector 3 gets loaded in 3 is in our buffer lxi h,ccp+1300h ; and this is where we want it to go... call movbyt xra a ret dmwchn: db dmsdma cma ;Make sector request positive inr a mov c,a ;Make new sector the requested sector pop d call dmside1 mvi a,80h rck equ 22*128 ;Amount of code on track 0 dmwarm: call dmselr ;Select drive 0 lxi h,dmchan ;Set up branch mvi m,bracha  mov a,m inx h mov h,m mov l,a mov a,m ;Get # of CP/M sectors/track ora a ;Clear cary rar ;Divide by two sub ction Table for the Disk Jockey DMA floppy * * * ***************************************************************** isystem buffer db 0 db rdsect db 1 ;Track 1 db 3 ;Side 0, sector 3 db 0 ;Drive 0 dmwend: db 0 ;Read status dw 0 >  ;Side two bit ora h ; and sector mov h,a ret dmldrv: sta dmlog call dminit ;Test for a drive jc zret lxi h,1 the Stepping rate constant mvi m,(low dmfstp) ;Fast stepping rate constant inx h mvi m,(high dmfstp) lxi d,5 ;Skip ovad d mov c,m dmget: lda dmlog lxi d,dphdm0 jmp retdph ; ; The current drive is double sided. Thus is it safe to set i m,0 mfwfal: lxi h,mfwend-1 ;Pointer to end of command structure call docmd ;Read in tracks lda mfwst ;Check out drive s lxi d,8 ;Offset to DPB pointer dad d ;HL <- &DPH.DPB push h call dmstat ani 20h ;Check double sided bit lxi d,dpblation dw mfldrv ;Select drive 1 dw mfsel2 ;Select drive 2 dw dmhome ;Home drive dw mfseek ;Seek to specified track ;Select sector 1 of track 2 shld truesec inx h shld cpmtrk xra a ;Make sure we are doing a read sta rdwr call fill er the reserved fields dad d mvi m,(low dmfset) ;Fast settling rate constant inx h mvi m,(high dmfset) call dmparm the ; stepping rate to 3 ms with 15 ms settling. ; sethigh:lhld dmlog ;Get the current drive number mvi h,0 ;Drive nutatus ani 40h ;Test for ok jz mfwfal ;Failed, loop xra a ;Return no error ret mfwchn: db dmsdma ;Set track 0 DMA 128s ;Base for single sided DPB's jz dmsok call sethigh ;Set controller to know about fast steping lxi d,dpb128d ;Base of dw mfssec ;Set sector dw dmdma ;Set DMA address dw dmread ;Read a sector dw dmwrite ;Write a sector dw nobad ;No  ;Flush buffer and refill jc zret ;Test for error return call dmstat ;Get status on current drive ani 0ch ;Mask in se;Set drive parameters for the SA850 ret endif ***************************************************************** * mber is a byte dad h ;Ten bytes per parameter table entry mov d,h mov e,l dad h dad h dad d lxi d,dparam+1 ;Paraddress dw ccp-512 ;First track DMA address - boot loader db 0 db rdtrck ;Read track command db 0 ;Track 0 db 0 ;S double sided DPB's dmsok: xchg ;HL <- DBP base, DE <- &DPH.DPB pop d ;Restore DE (pointer into DPH) pop psw ;Offset tobad sector map mftrck equ 9*512 ;Amount of code on track 0 mfwarm: call mfsel2 ;Select drive 0 lxi h,dmchan ;Set up brctor size bits push psw ;Used to select a DPB rar lxi h,xlts ;Table of XLT addresses mov e,a mvi d,0 dad d push  * * Drive specification table for DJDMA 5 1/4 inch drives * * * **************************************************ameter table address dad d ;Skip the track size byte mvi m,0 ;Force reparamitization of this drive inx h ;Offset to ide 0 db 0 ;Drive 0 dw mfwsec ;Sector load/status map db 0 mfwst db 0 ;Track read status db dmsdma dw ccp+mftrck ; correct DPB ral ral mov c,a mvi b,0 dad b xchg ;Put DPB address in DPH mov m,e inx h mov m,d lxi h,15 danch mvi m,bracha inx h mvi m,(low mfwchn) ;Low address byte inx h mvi m,(high mfwchn) ;High address byte inx h mvh ;Save pointer to proper XLT call dmget pop d lxi b,2 ;Number of bytes to move call movbyt ;Move the address of XLT *************** if maxmf ne 0 mfdst: db maxmf ;Number of logical drives dw mfwarm ;Warm boot dw mftran ;Sector trans? DMA address for track 1 db 0 db rdtrck db 1 ;Track 1 db 0 ;Side 0 db 0 ;Drive 0 dw mfwsec+10 ;Map is loaded rightmov c,a mvi b,0 lxi h,mfscon dad b mvi a,n$dubl mov m,a sta mfpcon lxi h,1 ;Select sector 1 of track 0 shld t nothing happened mvi b,4 ;5 1/4 inch drives start at drive 4 jmp dmsel2 mftran: lda mfpcon ani n$dubl lxi h,mfxltmp mfl2 mfl3: inx h mov a,m ;Pick up drive type sta mfpcon mov e,a push h lda mflog ;Get proper physical confige jz dmseek ;Only single sided mov a,c ;Move selected track in (a) sbi 35 ;Subtract by track by number of tracks jcIf zero then determine sector size ani 80h ;Check density bit jnz mfl9 ;Its double density mvi a,10h ;Single density de after track 0 status map db 0 mfwend: db 0 ;Track read status dw 0 ;Room for the halt mfwsec: dw 0ffh, 0, 0, 0, 0 ;Doruesec dcx h shld cpmtrk xra a ;Make sure we are doing a read sta rdwr call fill ;Flush buffer and refill jc zret d ;Point to double sided sector translation table jnz mftdubl ;Single density sector translation lxi h,mfxlts mftdubl:dad uration byte mov c,a mvi b,0 lxi h,mfscon dad b mov m,e pop h inx h mov a,m inx h mov h,m mov l,a ;DPB  dmseek ;Less than track 35 mov d,a ;Save adjusted track number mvi a,34 sub d ;Adjust to count tracks back out movfault configuration byte mfl9: mov c,a ;Move configuration byte into (c) lxi h,mfs ;Address of configuration table -> ( not load boot loader dw 0, 0ffffh, 0ffffh, 0ffffh, 0ffffh ;first two sectors loaded mfssec: dcr c ;Minnie floppy sectors  ;Test for error return lda buffer+5ch ;Get diskette configuration byte push psw ;Save configuration byte lxi h,1 shlb ;Add offset sector number to table mov l,m ;Pick up sector number from table mvi h,0 ;MSB of sector number equal 0 readdress -> (hl) push h ;Save DPB address call mfgdph ;Get DPH lxi d,10 ;Offset to DPB address in DPH dad d pop d  c,a ;Resave new track number mvi a,0ffh ;Set double sided flag sta dblflg jmp dmseek mfsel2: sta mflog mov c,ahl) mfl2: mov a,m ;Get an entry ora a ;Check for end of the table jz zret ;Yes, select error cmp c ;Check if entry mastart at zero lda dblflg ;Get double sided flags ora a jz dmssec ;Nope, single sided mvi b,80h ;Set high bit for doubd cpmtrk ;Load track 1 sector 1 call fill ;This is to fix bug with DJDMA firmware on jc zret ; returning single density st mfldrv: sta mflog call dminit ;Test for a controller jc zret lda mflog ;Get proper physical configuration byte mov m,e ;Store DPB address in DPH inx h mov m,d call mfgdph push h call dmstat ;Get status pop h ani 80h ;Check ;Get proper physical configuration byte mvi b,0 lxi h,mfscon dad b mov a,m sta mfpcon mov a,c ;Shhh, pretend thattches selected drive jz mfl3 inx h ;Skip onfiguration byte inx h ;Skip drive type inx h ;Skip DPB address inx h jle sided select jmp dmssec dblflg: db 0 mfseek: xra a ;Clear double sided select sta dblflg lda mfpcon ani n$2sidtatus on track 0 pop psw ora a jnz mfl9 ;Non zero mvi a,90h ;Double density default configuration call dmstat ;@  density bit mvi c,3 ;512 byte sectors rnz mvi c,2 ;256 byte sectors ret mfgdph lda mflog lxi d,dphmf0 jmp retd ;Move drive into (c) lxi h,dmchan mvi m,setlog ;Set logical drives inx h mov m,b ;Drive in (b) push b call docmd ,23,24 db 5, 6, 7, 8 db 25,26,27,28 db 9,10,11,12 db 29,30,31,32 db 13,14,15,16 db 33,34,35,36 db 17,18,19,20 been calibrated then that drives track count, ; stepping rate, and head settling time are loaded. ; dmparm: mvi a,8 ;Eighouble density, 35 tracks, double sided dw dpbmf3 ;2K groups db 0e5h ;North Star CP/M 1.4 db n$dubl ;Double density, 3oller lxi d,0 ;Set up timeout counter dminwt mov a,m ora a jnz dmiok ;Controller has responded dcx d ;Bump timeout cph mfpcon: db 0 ;Physical configuration byte mflog: db 0 mfscon: db 0, 0, 0, 0 ;Saved physical configuration bytes mf pop b jmp dmsel dmssec: push b ;Save sector number mov a,b rlc ani 1 mov c,a call dmside pop b jmp dmsec db 37,38,39,40 mfxlts db 1, 2 db 3, 4 db 5, 6 db 7, 8 db 9,10 db 11,12 db 13,14 db 15,16 db 17,18 db 1t drives lxi d,1340h ;Start with drive 0's table lxi h,dparam+1 ;Drive parameter table dmstr0: push psw ;Save the dr5 tracks, single sided dw dpbmf1 ;1K groups db 0a0h ;North Star CP/M 2.x (fake 40 track) db n$dubl ;Double density, ounter mov a,d ora e jnz dminwt stc ;Set error flag ret dmiok push h ;Set drive parameters call dmparm pop hs: db 10h ;North Star CP/M 1.4 db 0 ;Single density, 35 tracks, single sided dw dpbmf0 ;1K groups db 90h ;North Star dmdma lxi h,dmchan ;Default channel address mvi m,dmsdma ;Set DMA address inx h mov m,c ;Low byte first inx h mov m,9,20 endif ***************************************************************** * * * Common routines for the DJDMA wive count mov a,m ;Load flags ora a ;Does the drive need to be calibrated? jnz dmstr1 ;No, do not fiddle around pu35 tracks, single sided dw dpbmf2 ;2K groups db 0d0h ;North Star CP/M 2.x (fake 40 track) db n$dubl+n$2side ;Double de dcx h ;Back to start of command mvi m,setcrc ;Set CRC error retry count to one inx h mvi m,1 xra a jmp docmd2 ;Do CP/M 1.4 db n$dubl ;Double density, 35 tracks, single sided dw dpbmf1 ;1K groups db 0b0h ;North Star CP/M 2.x db nb ;High byte next docmd xra a inx h mov m,a docmd2 inx h mvi m,dmhaltc inx h mov m,a out dmkick tests ora m ith 8 and 5 1/4 inch drives * * * ***************************************************************** dmsel2: mov c,a sh h ;Save the parameter table pointer push d ;Save the controllers table pointer dcr m ;Set to calibrated mode (0ffh)nsity, 35 tracks, double sided dw dpbmf3 ;2K groups db 0 ;End of configuration table mfxltd db 1, 2, 3, 4 db 21,22 command ; ; Set floppy drive parameters ; ; This routine reads the dparam table and if the a drive has not ; previously $dubl ;Double density, 35 tracks, single sided dw dpbmf2 ;2K groups db 0f0h ;North Star CP/M 2.x db n$dubl+n$2side ;Djz tests ret dminit: lxi h,dmchan ;See if controller will halt mvi m,dmhaltc inx h mvi m,0 out dmkick ;Start contrA  dcx h ;Back up to the track size byte shld dmntrk ;Set the number of tracks pointer inx h inx h shld dmspar ;Se---------+ ; dmstat lxi h,dmchan mvi m,gstat ;Set up read status inx h lda lldrv ;Get last selected drive mov m,a t ;Double density only ; ; Return status in the (a) register in the form: ; ; 7 6 5 5 3 2 1 0 ; ^ ^ ^ ^ y: ; DE = offset to the halt status ; HL = pointer to the start of the command ; ; Returns: ; nothing ; dmdoit: mvi mstr0 ;Set up next drive ret dmhome xra a mov c,a ;Put a zero into (c) for track zero dmseek mov a,c ;Enter withov c,a inx h mvi a,3 ;Sector length mask ana m ;And in rlc ;Move to bits 2 & 3 rlc ora c mov c,a inx h mvit the stepping constants pointer xchg ;Set the local parameter table pointer shld dmloc0 inx h ;Offset to the steppin ;Store drive in command inx h ;Skip over returned status inx h inx h call docmd ;Issue command lda llss ;Get side ^ ^ ^ ^ ; Density --------------+ | | | | | | | ; Side select -------------+ | | | | | | ; Double sided -----a,bracha ;Branch channel command sta dmchan shld dmchan+1 ;Load command vector xra a ;Clear extended address sta dmchan track in (c) sta lltrk ;Save for use later ret dmsec lda llss ;Load sector ani 80h ;Save side select bit stores or a,4 ;Mask for double sided bit ana m rlc ;8 rlc ;10 rlc ;20 ora c ret dmwrite mvi a,wrsect db 01 ;Ugh.g parameters inx h inx h inx h shld dmloc1 lxi h,dmwcon ;Write the drive constants out lxi d,17 ;Halt status offsbit of last operation ani 80h rrc ;Move to bit 7 mov c,a lxi h,dmchan+1 ;Point to drive mov a,m ;Load drive ora c----------+ | | | | | ; 5 1/4 -------------------------+ | | | | ; Sector size MSB ------------------+ | | | ; Se+3 dad d ;Offset to the halt status mov m,a ;Clear the halt status indicator out dmkick ;Start the controller dma c sta llss ret dmside: mov a,c ;Move side bit into (a) ani 1 rrc ;Move around to bit 7 mov c,a ;Resave in (c).. dmread mvi a,rdsect lxi h,dmchan lxi d,lltrk-1 mvi b,4 cload mov m,a inx h inx d ldax d dcr b jnz cload det call dmdoit pop d ;Retrieve the table pointers pop h dmstr1: lxi b,10 ;Bump parameter table pointer dad b xc ani 4 ;Mask upper drive select bit for 5 1/4 rlc rlc ;Move to bit 4 ora m ;Put together with lower drive bits oractor size LSB ---------------------+ | | ; Drive select MSB -----------------------+ | ; Drive select LSB -----------------wait: ora m ;Wait for the operation complete status jz dmwait ret dmwcon: db writem ;Write track size dmntrk: dw 0  lda llss ani 7fh ;Mask out old side select bit jmp stores dmsel: mov a,c ;Move drive into (a) sta lldrv dmden: recx h call docmd lda dmchan+4 cpi 80h cmc ret ; ; Execute a DJDMA command, no command status is returned ; ; Entrhg lxi b,16 ;Bump controller tables pointer dad b xchg pop psw ;Retrieve drive count dcr a ;Bump count jnz d c mov c,a inx h mvi a,10h ;Double density bit ana m rlc ;20h rlc ;40h rlc ;80h for density bit ora c mB  ;Number of tracks + desync db 0 ;X-address dw 2 ;Two bytes dmloc0: dw 0 ;Local controller address db writem ;e sector dmarhed equ 2 ;Find a sector dmawhed equ 3 ;Write headers (format a track) dmalcon equ 4 ;Load disk parameters dly equ 0 steprcl equ 30 headdly equ 0 endif if cm5619 ;Specifications for an CMI 5619 cyl equ 306 heads equ 6 precom ;Seek to selected track dw mwsec ;Select sector dw mwdma ;Set DMA address dw mwread ;Read a sector dw mwwrite ;Writ? if st506 ;Specifications for a Seagate Technology 506 cyl equ 153 ;Number of cylinders heads equ 4 ;Number of heads pereek complete ***************************************************************** * * * Drive Specification Table for tWrite stepping rate data dmspar: dw 0 ;Pointer to the stepping parameters db 0 dw 8 dmloc1: dw 0 db dmhaltc ;Contrmassta equ 5 ;Sense disk drive status dmanoop equ 6 ;Null controller operation reset equ 54h ;Reset controller attn equ p equ 128 lowcurr equ 128 stepdly equ 2 steprcl equ 30 headdly equ 0 endif sectsiz equ 7 ;Sector size code (must be 7 e a sector if heads > 2 ;Test if drive is big enough for a bad spot map dw mwbad ;Return bad sector map info else dw no cylinder precomp equ 64 ;Cylinder to start write precomensation lowcurr equ 128 ;Cylinder to start low current stepdly equhe HD DMA hard disk controller * * * ***************************************************************** mwdst: db maxoller halt db 0 ;Status ; ; Driver variables ; lltrk db 0 llss db 1 lldrv db 0 dmlog db 0 endif **********55h ;Send a controller attention chan equ 50h ;Default channel address stepout equ 10h ;Step direction out stepin equ 0 for this Cbios) ; 0 = 128 byte sectors ; 1 = 256 byte sectors ; 3 = 512 byte sectors ; 7 = 1024 byte sectbad endif ***************************************************************** * * * The following are the lowest lev 30 ;Step delay (0-12.7 milliseconds) steprcl equ 30 ;Recalibrate step delay headdly equ 0 ;Settle delay (0-25.5 milliseconmw*mwlog ;Number of logical drives dw mwwarm ;Warm boot dw mwtran ;Sector translation dw mwldrv ;Select logical drive 1******************************************************* * * * The follwing equates are for the HDDMA hard disk controll ;Step direction in band1 equ 40h ;No precomp, high current band2 equ 0c0h ;Precomp, high current band3 equ 80h ;precomp, ors (default) ; f = 2048 byte sectors ;Define controller commands dmaread equ 0 ;Read sector dmawrit equ 1 ;Writel drivers for the Morrow * * Designs Hard Disk DMA controller. * * * *********************************************ds) endif if st412 ;Specifications for a Seagate ST412 cyl equ 306 heads equ 4 precomp equ 128 lowcurr equ 128 stepd (First time select) dw mwdrv ;Select logical drive 2 (General select) dw mwhome ;Home current selected drive dw mwseek er * * * ***************************************************************** if maxmw ne 0 ;HDDMA controller present low current track0 equ 1 ;Track zero status wflt equ 2 ;Write fault from drive dready equ 4 ;Drive ready sekcmp equ 8 ;SC ******************** mwwarm xra a call mwdrv ;Select drive A call mwhome ;Home and reset the drive lxi b,0 ;Make surcute disk command mwdlog: mvi c,0 mwllx: sui mwlog rc inr c jmp mwllx mwstat mvi a,dmassta ;Sense status operation ret ;Controller failure lda mwcurl call mwdrv ;Select drive jc zret ;Select error call mwstat ;Get drive status ov l,c call mwhlmde mvi c,stepout mov a,h ani 80h ;Check hit bit for negitive direction jnz mwsout ;Step in mvi c,done inr h ;Update DMA address by 1024 bytes inr h inr h inr h shld dmadma push h push psw call mwwread ;Read i h,mwbtab ;Return pointer to bad sector location ret mwbtab: dw 0 ;Track 0 dw 19 ;Head 2, sector 0 = (2 * SPT + 0) + e we are on track 0 call mwseek xra a sta mwhead ;Select head zero sta mwsectr ;Select sector 1 lxi h,buffer ;Load scode jmp mwprep ;Execute disk command mwhome call mwreset ;Reset controller, do a load constants lxi h,dmarg1 ;Load arg ani dready ;Check if drive ready jnz zret call mwhome ;Home drive lxi d,dphmw0 ;Start of hard disk DPH's lda mwc0 jmp mwskip mwsout: call mwneghl mwskip: shld dmastep lda mwdrive ora c sta dmasel0 mvi a,dmanoop ;No-operation cin a sector jnc mwwlod ret ;Return with error mwwread mvi c,retries ;Retry counter mwwerr push b ;Save the retry coun1 mwseek call mwptr ;Get track pointer mov e,m ;Get old track number inx h mov d,m dcx h mov m,c ;Store new tracector 1 into buffer shld dmadma call mwwread ;Read CCP into buffer rc ;Return if error lxi d,buffer+200h lxi h,ccp uments mvi m,steprcl ;Load step delay (slow rate) inx h mvi m,headdly ;Head settle delay call mwissue ;Do load constanturl mov l,a mvi h,0 dad h dad h dad h dad h dad d ;(hl) = pointer to DPH mvi c,4 ;Return sector size of 1024 ommand for the channel call mwprep ;Step to proper track lxi h,0 ;Clear step counter shld dmastep ret mwdma mov h,bt call mwread ;Read the sector pop b rnc dcr c ;Update the error count jnz mwwerr ;Keep trying if not too many errok number inx h mov m,b mov l,c ;Build cylinder word mov h,b shld dmarg0 ;Set command channel cylinder number mov a lxi b,200h ;Move 200h bytes call movbyt lxi h,ccp-200h ;Initial DMA address push h xra a push a ;Save first sectors again call mwptr ;Get pointer to current cylinder number mvi m,0ffh ;Fake at cylinder 65535 for max head travel inx h  ret mwdrv sta mwcurl call mwdlog mov a,c sta mwdrive ;Save new selected drive mwsel mvi a,dmanoop jmp mwprep ;Exe ;Set DMA address mov l,c shld dmadma ret mwsec mov a,c ;Load sector number dcr a ;Range is actaully 0-16 call mrs stc ;Set error flag ret mwldrv sta mwcurl ;Save current logical drive call mwreset ;Reset controller card jc z,d inr a lxi h,0ffffh jnz mwskip0 mvi c,stepout jmp mwskip mwskip0:mov h,b ;(hl) = new track, (de) = old track m -1 mwwlod pop psw ;Restore sector pop h ;Restore DMA address inr a sta mwsectr cpi 6 ;Past BDOS ? rz ;Yes, all  mvi m,0ffh lxi b,0 ;Seek to cylinder 0 call mwseek ;Recal slowly jmp mwreset ;Back to fast stepping mode mwbad: lxD wdspt ;Figure out head number -> (c) adi mwspt ;Make sector number sta mwsectr mov a,c sta mwhead ;Save head number  ;Negative logic for the controller ani 7 ;3 bits of head select rlc ;Shove over to bits 2 - 4 rlc ora c ;Add on ls lhld tempb ;Restore memory used for the channel pointer shld chan lda tempb+2 sta chan+2 pop psw ret mwread mv$ else mwissue equ $ ;Do a disk command, handle timeouts + errors endif lxi h,dmastat ;Clear status byte mvi mlhld dmarg0 ;Save the track number push h lxi h,dmasel1 ;Load arguments lda mwdrive ;Get the currently selected drive t a byte of the status line call spout pop h pop b inx h ;Bump command channel pointer dcr c jnz mwerr mvi c,0ah  ret mwdspt mvi c,0 ;Clear head counter mwdsptx sui mwspt ;Subtract a tracks worth of sectors rc ;Return if all done ow current and precomp bits mov c,a lda mwdrive ;Load drive address ora c ;Slap in drive bits sta dmasel1 ;Save in coi a,dmaread ;Load disk read command jmp mwprep mwwrite mvi a,dmawrit ;Load disk write command mwprep: sta dmaop ;Save c,0 out attn ;Start the controller lxi d,0 ;Time out counter (65536 retries) mwiloop mov a,m ;Get status ora a ;Set upori 03ch ;Raise *step and *dir mov m,a ;Save in drive select register lxi d,5 ;Offset to dmarg1 dad d mvi m,stepdly ; ;Terminate with a CRLF call pout mvi c,0dh call pout pop psw ;Restore error status ret dspout: call spout ;Print inr c ;Bump to next head jmp mwdsptx mwreset lhld chan ;Save the command channel for a while shld tempb lda chan+2 mmand channel head select lda mwsectr ;Load sector address sta dmarg3 if 0 ;Set to 1 for MW error reporter mwissue caommand channel op code mvi c,band1 lhld dmarg0 lxi d,precomp call mwhlcde jc mwpreps mvi c,band2 lxi d,lowcurr CPU flags rm ;Return no error (carry reset) stc rnz ;Return error status xthl ;Waste some time xthl xthl xtLoad step delay inx h mvi m,headdly ;Head settle delay inx h mvi m,sectsiz ;Sector size code inx h mvi m,dmalcon ;Lo two spaces spout: mvi c,' ' ;Print a space jmp pout hexout: push psw ;Poor persons number printer rrc rrc rrc r sta tempb+2 out reset ;Send reset pulse to controller lxi h,dmachan ;Address of command channel shld chan ;Default chanll mwdoit ;Do desired operation rnc ;Do nothing if no error push psw ;Save error info call hexout ;Print status cal call mwhlcde jc mwpreps mvi c,band3 ;cylinder > low_current mwpreps lda mwhead ;Load head address sta dmarg2 cmahl dcx d ;Bump timeout counter mov a,d ora e jnz mwiloop ;Loop if still busy stc ;Set error flag ret mwptr ldad constants command call mwissue ;Do load constants pop h ;Restore the track number shld dmarg0 push psw ;Save staturc call nibout pop psw nibout: ani 0fh adi '0' cpi '9'+1 jc nibok adi 27h nibok: mov c,a jmp pout mwdoit equ nel address xra a sta chan+2 ;Clear extended address byte shld 40h ;Set up a pointer to the command channel sta 42h l dspout ; and a space lxi h,dmachan mvi c,16 ;16 bytes of status mwerr: push b push h mov a,m call hexout ;PrinE a mwdrive ;Get currently select drives track address rlc mov e,a mvi d,0 lxi h,mwtab dad d ;Offset into track table # truesec:dw 0 ;Physical sector that contains CP/M sector error: db 0 ;Buffer's error status flag bufdrv: db 0 ;Drive th*********************************************************** * * * Cbios ram locations that don't need initialization. n the initial value of * * 'off' should be adjusted accordingly. * * * * hdtrks = tracks - 1 * * * * 0 ;Currently selected sector dmachan equ $ ;Command channel area dmasel0 db 0 ;Drive select dmastep dw 0 ;Relative stelog dphgen hd,%dphdsk,dpbhd,%ldsk ldsk set ldsk+1 dphdsk set dphdsk+1 endm endm if hdpart ne 0 ;Use non-standard par ret mwtran: mov h,b mov l,c inx h ret mwneghl:mov a,h cma mov h,a mov a,l cma mov l,a inx h ret mat buffer belongs to buftrk: dw 0 ;Track that buffer belongs to bufsec: dw 0 ;Sector that buffer belongs to alttrk: dw 0 * * * ***************************************************************** if nostand ne 0 ;Unallocated writting varia**************************************************************** if m10 ne 0 hdsectp equ 336 ;Sectors per track hdtrks p counter dmasel1 db 0 ;Head select dmadma dw 0 ;DMA address db 0 ;Extended address dmarg0 db 0 ;First argument dmarg1titioning ***************************************************************** * * * hdsectp is the number of 128 byte whlmde:xchg call mwneghl xchg dad d ret mwhlcde:mov a,h cmp d rnz mov a,l cmp e ret mwtab equ $ ;Collec ;Alternate track altsec: dw 0 ;Alterante sector lastdrv:db 0 ;Last selected drive **************************************bles unaloc: db 0 ;Unallocated write in progress flag oblock: dw 0 ;Last unallocated block number written unadrv: db 0 ;Drequ 243 ;Total data tracks endif if m20 ne 0 hdsectp equ 672 hdtrks equ 243 endif if m26 ne 0 hdsectp equ 102 db 0 ;Second argument dmarg2 db 0 ;Third argument dmarg3 db 0 ;Fourth argument dmaop db 0 ;Operation code dmastat db 0 sectors per cylinder. * * * * hdtrks is the total number of data cylinders. Eg. it is * * the number of cyliders on tion of track addresses rept maxmw db 0ffh ;Initialize to (way out on the end of the disk) db 0ffh endm db 0ffh mw*************************** * * * DPB and DPH area. * * * ***********************************************ive that the block belongs to endif cpmsec: dw 0 ;CP/M sector # cpmdrv: db 0 ;CP/M drive # cpmtrk: dw 0 ;CP/M track 4 hdtrks equ 201 endif ldsk set 0 ;Use non-standard partitioning tracks set hdtrks/hdlog ;Number of tracks per partitio ;Controller status byte dmalnk dw dmachan ;Link address to next command channel db 0 ;extended address endif ******the drive minus the number of * * cylinders that are used for the system. If the number of * * 'system tracks' is not one thecurl db 0 ;Current logical drive mwdrive db 0ffh ;Currently selected drive mwhead db 0 ;Currently selected head mwsectr db****************** if maxhd ne 0 dphdsk set 0 ;Generate DPH's for the HDCA hard disks rept maxhd ldsk set 0 rept hdF n dsm set hdsectp/8*tracks/4-1 ;Number of groups per partition off set 1 rept hdlog dpbgen hd,%ldsk,%hdsectp,5,31,1,%dsm028 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1 dw 0 ;CKS dw 195 ;OFF db 3 ;SECSIZ endif endif endif ;0 ;CKS dw 122 ;OFF db 3 ;SECSIZ endif if m20 ne 0 dpbhd0 dw 672 ;CP/M sectors/track db 5 ;BSH db 31 ;BLM  mwsecpt set 288 mwtrks set 305 endif if cm5619 ne 0 mwsecpt set 432 mwtrks set 305 endif dphdsk set 0 ;Generasectors/track db 5 ;BSH db 31 ;BLM db 1 ;EXM dw 2047 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1 dw 0 ;CKdn set dn+1 endm endif if maxmw ne 0 ***************************************************************** * * *,511,0ffh,0ffh,0,%off,3 off set off+tracks ldsk set ldsk+1 endm else ;Else use standard DPB's if m26 ne 0 dpbhd0 End of HD DPH's and DPB's if maxmf ne 0 dpbgen mf, 0, 20, 3, 7, 0, 04fh, 63, 0c0h, 0, 16, 3, 2 dpbgen mf, 1, 40, 3, db 1 ;EXM dw 2036 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1 dw 0 ;CKS dw 1 ;OFF db 3 ;SECSIZ dpbhd1 dwte DPH's for the HDDMA hard disks rept maxmw ldsk set 0 rept mwlog dphgen mw,%dphdsk,dpbmw,%ldsk dphdsk set dphdsk+1 ldS dw 127 ;OFF db 3 ;SECSIZ endif if m10 ne 0 dpbhd0 dw 336 ;CP/M sectors/track db 5 ;BSH db 31 ;BLM db 1  mwsectp is the number of 128 byte sectors per cylinder. * * mwsectp = 72 * heads * * * * mwtrks is the total numdw 1024 ;CP/M sectors/track db 5 ;BSH db 31 ;BLM db 1 ;EXM dw 2015 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ; 7, 0, 0a4h, 63, 0c0h, 0, 16, 2, 3 dpbgen mf, 2, 40, 4, 15, 1, 051h, 63, 80h, 0, 16, 2, 3 dpbgen mf, 3, 40, 4, 15, 1, 0a9 672 ;CP/M sectors/track db 5 ;BSH db 31 ;BLM db 1 ;EXM dw 2036 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1sk set ldsk+1 endm endm if mwpart ne 0 ;Generate DPB's for a HDDMA hard disk ldsk set 0 ;Use non-standard partitioni;EXM dw 1269 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1 dw 0 ;CKS dw 1 ;OFF db 3 ;SECSIZ dpbhd1 dw 336 ber of data cylinders. * * mwtrks = tracks - 1 * * * **********************************************************AL1 dw 0 ;CKS dw 1 ;OFF db 3 ;SECSIZ dpbhd1 dw 1024 ;CP/M sectors/track db 5 ;BSH db 31 ;BLM db 1 ;EXM dh, 63, 80h, 0, 16, 2, 3 dn set 0 rept maxmf dphgen mf,%dn,dpbmf,%dn dn set dn+1 endm endif if maxfd ne 0 dn s dw 0 ;CKS dw 98 ;OFF db 3 ;SECSIZ dpbhd2 dw 672 ;CP/M sectors/track db 5 ;BSH db 31 ;BLM db 1 ;EXM dw 1ng tracks set mwtrks/mwlog ;Number of tracks per partition dsm set mwsectp/8*tracks/4-1 ;Number of groups per partition off s;CP/M sectors/track db 5 ;BSH db 31 ;BLM db 1 ;EXM dw 1280 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1 dw ******* if st506 ne 0 mwsecpt equ 288 ;Sectors per track mwtrks equ 152 ;Total data tracks endif if st412 ne 0 w 2015 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1 dw 0 ;CKS dw 64 ;OFF db 3 ;SECSIZ dpbhd2 dw 1024 ;CP/M et 0 rept maxfd dphgen fd,%dn,0,0 dn set dn+1 endm endif if maxdm ne 0 dn set 0 rept maxdm dphgen dm,%dn,0,0 G et 1 rept mwlog dpbgen mw,%ldsk,%mwsecpt,5,31,1,%dsm,1023,0ffh,0ffh,0,%off,4 off set off+tracks ldsk set ldsk+1 endm /10h prnib digit endm prnib macro digit ;Write a digit in hex temp set digit and 0fh if temp < 10 db temp + '0' db '0'+(msize mod 10) db 'K CP/M ' ;CP/M version number db cpmrev/10+'0' db '.' db (cpmrev mod 10)+'0' db ' ' db (r5 1/4"' endif dn set dn+1 endm db acr,alf db 0 ;End of message *********************************************** 256 ;If there is any stuff left, then use it blocks set blocks-1 dpbgen mw,%ldsk,%mwsecpt,5,31,1,%blocks,1023,0ffh,0ffh,0,%owlog db 'HDDMA' if mwquiet eq 0 db ' ' if maxmw gt 1 db '(', maxmw+'0', ')' endif if st506 ne 0 db 'M5' endif  else ;Use standard partitioning off set 1 ;Initial system track offset trkoff set 8192/(mwsecpt/8)+1 ;The number of telse db temp - 10 + 'A' endif endm dn set 1 ;Generate the drive messages rept 16 ;Run off at least 16 drives evnum/10)+'A'-1 db (revnum mod 10)+'0' db acr, alf ; ; Print a message like: ; ; AB: DJDMA 8", CD: DJDMA 5 1/4", E: H****************** * * * Cboot is the cold boot loader. All of CP/M has been loaded in * * when control is passed hereff,4 endif endif endif buffer equ $ ***************************************************************** * * * if st412 ne 0 db 'M10' endif if cm5619 ne 0 db 'M16' endif endif endif if dn eq fdorder ;Generate the 2D/B racks in a partition blocks set mwsecpt/8*mwtrks ;The number of blocks on the drive psize set trkoff*(mwsecpt/8) ;The number o if dn eq hdorder ;Generate the HDCA's message msbump maxhd*hdlog db 'HDCA ' if maxhd gt 1 db '(', maxhd+'0', ')' enDDMA M5 ; msdrv set 0 ;Start with drive A: msbump macro ndrives ;Print a drive name if dn gt 1 db ', ' endif . * * * ***************************************************************** cboot: lxi sp,tpa ;Set up stack  Signon message output during cold boot. * * * ***************************************************************** pmessage msbump maxfd db 'DJ2D/B @' prhex fdorig/100h prhex fdorig endif if dn eq dmorder ;Generate the DJDMA 8 mef blocks in a partition ldsk set 0 rept blocks/8192 ;Generate some 8 megabyte DPB's dpbgen mw,%ldsk,%mwsecpt,5,31,1,2047,dif if m10 ne 0 if m10m ne 0 db 'Memorex' else db 'Fujitsu' endif db ' M10' endif if m20 ne 0 db 'Fujitsu M2rept ndrives db msdrv+'A' msdrv set msdrv+1 endm db ': ' endm prhex macro digit ;Write a byte in hex prnib digitxra a ;Clear cold boot flag sta cwflg sta group ;Clear group select byte sta cpmdrv ;Select disk A: sta cdisk rompt: db 80h, clear ;Clean buffer and screen db acr, alf, alf db 'Morrow Designs ' db '0'+msize/10 ;CP/M memory size ssage msbump maxdm db 'DJDMA 8"' endif if dn eq mforder ;Generate the DJDMA 5 1/4 message msbump maxmf db 'DJDMA 1023,0ffh,0ffh,0,%off,4 off set off+trkoff blocks set blocks-psize ldsk set ldsk+1 endm blocks set blocks/4 if blocks gt0' endif if m26 ne 0 db 'Shugart M26' endif endif if dn eq mworder ;Generate the HDDMA's message msbump maxmw*mH lxi h,bios+3 ;Patch cold boot to warm code shld bios+1 lda iobyt ;Initialize the IOBYTE sta iobyte lxi d,badmap ******************************* ttyset: call selg0 ;Select group 0 in sensesw ;Get sense switch (ff on a Multio) push*************************************************************** * * * Console and list device initialization routines fr xra a out ier ;Set no interrupts out lsr ;Clear status mvi a,dtrenb+rtsenb ;Enable DTR and RTS outputs to termina a,d ;Test for the end of the table ora e jz cboot2 push h ;Save the table pointer lxi h,cboot1 ;Return address pinto (de) mvi d,0 dad d ;Get a pointer into baud rate table mov e,m ;Get lower byte of word inx h ;Bump to high by;Clear out bad map stax d lxi h,badmap+1 lxi b,9*badsiz ;32 map entries call movbyt mvi m,0ffh ;End marker if c psw call selcon ;Select console pop psw push psw call tini0 ;Initialize the console pop psw push psw call selollow. * * * ***************************************************************** if contyp eq 2 ;Multi I/O, Decisionl out mcr in msr ;Clear MODEM Status Register in lsr ;Clear Line Status Register in rbr ;Clear reciever buffers ush h xchg pchl ;'CALL' a device setup routine cboot1: pop h ;Restore the table pointer jmp cboot0 devset: dw ttyte of word mov d,m ;Get upper byte. (de) now has divisor jmp setit ;Set baud rate dfbaud: lhld defcon ;Use default ontyp ne 6 ;Non IOBYTE inits if contyp ne 0 ;Do not call TTYSET for PROM's call ttyset ;Initialize the terminal endif rdr ;Select the reader/punch pop psw call tini0 ;Initialize the reader/punch ret tini0: ani 0e0h ;Mask in upper t I ***************************************************************** * * * Terminal initilization routine. This rouin rbr ret btab: dw 1047 ;110 Baud 000 dw 384 ;300 001 dw 96 ;1200 010 dw 48 ;2400 011 dw 24 ;4800 10set, crtset, uc1set ;Device setup routine pointers dw ptrset, ur1set, ur2set dw ptpset, up1set, up2set dw lptset, ul1set, baud rate xchg setit: mvi a,dlab+wls1+wls0+stb ;Enable divisor access latch out lcr ;Set the baud rate in (de) mov a, if lsttyp ne 0 ;Do not call LSTSET for PROM's call lstset ;Initialize the list device endif else ;Do IOBYTE inithree bits rlc ;Move into lower 3 bits rlc rlc cpi 7 ;check for sense = 7 (Default setting) jz dfbaud ;Use defautine reads the sense * * switch on the WB-14 and sets the speed accordingly. * * * **********************************0 dw 12 ;9600 101 dw 6 ;19200 110 ;DEFCON 111 endif ;Multi I/O, Decision I if contyp eq 3 ;2D/B con0 cboot2 equ $ endif lxi h,prompt ;Prep for sending signon message call message ;Send the prompt jmp gocpm **d out dlm ;Set upper divisor mov a,e out dll ;Set lower divisor mvi a,wls1+wls0+stb ;Clear Divisor latch out lcs lxi h,devset ;Device setup routine pointer table cboot0: mov e,m ;Load a routine address inx h mov d,m inx h movlt baud rate lxi h,btab ;Pointer to baud rate table add a ;Table of words so double mov e,a ;Make a 16 bit number I sole initialization ttyset: call fdtstat ;Clean input buffer rnz ;All empty call fdcin jmp ttyset endif ;2Dinput/output buffers out nsrdat in nsrdat in nsrdat if nsram ne 0 ;Reset parity on North Star RAMs mvi a,40h ;Dislag out nspsta mvi a,60h ;Set the parallel port output flag out nspsta mvi a,acr ;Force a CR out the parallel port  endif ;North Star drivers if (lsttyp ge 2) and (lsttyp le 5) ;Serial Multi I/O list drivers lstset: call sellst ;S endif ************************************************************************* * * * Initialize the North Star Mo change mov m,a cmp m ;Test for a change mov m,b ;Restore the original value jz nset0 ;Value complemented, must be/B console if contyp eq 4 ttyset: call dminit ;See if controller present rc ;No controller, return lxi d,dmaci ;able parity logic out nsram lxi h,0 ;Starting address nset0: mov a,m ;Get a byte mov m,a ;Rewrite, set proper par call nspout ;Initialize the left serial port mvi a,nslin1 ;See the equates for bit definations out nslsta mvi a,elect printer group mvi a,dlab ;Access divisor latch out lcr lhld deflst ;Get LST: baud rate divisor mov a,h out dther board, left serial port, right * * serial port, and North Star RAM parity. * * * **************************** RAM ora a ;Test for no memory present jz nset1 ;Skip to the next page if no memory lxi d,700h ;Skip 2K bytes of 'PRConsole initialization sequence lxi h,dmchan lxi b,10 ;Command length call movbyt dcx h xra a ;Clear serial input ity inr l ;Bump the address pointer jnz nset0 nset1: inr h ;Skip to the next memory page jz nset2 ;Skip if all donslin2 out nslsta xra a ;Clear the input/output buffers out nsldat in nsldat in nsldat ;Initialize the rightlm ;Set upper baud rate mov a,l out dll mvi a,stb+wls0+wls1 ;2 stop bits + 8 bit word out lcr mvi a,dtrenb+rtsenb ********************************************* if contyp eq 6 ;North Star drivers ttyset: ;Set up the parallel port +OM' dad d jnc nset1 ;Do a page check if no overflow nset2: mvi a,41h ;Re-enable parity on the memory boards out nsrstatus sta serin+1 jmp docmd2 ;Do stuff and return dmaci: db writem ;Zot monitor disable flag dw ttyset ;Any non-ne mvi a,(high $) + 1 ;Is the pointer above us? cmp h ;Set carry if pointer is <= our page+1 jc nset0 ;Reset the nex serial port mvi a,nsrin1 ;See the equates for bit definations out nsrsta mvi a,nsrin2 out nsrsta xra a ;Clear the ;DTR + RTS enabled out mcr in rbr ;Clear input buffer xra a out ier ;No interrupts ret endif db 0,0ffh,0  motherboard xra a ;Initialize mother board out 6 out 6 out 6 out 6 mvi a,30h ;Reset the parallel port input fam endif crtset: ;Null routines ptrset: ptpset: uc1set: ur1set: ur2set: up1set: up2set: lptset: ul1set: ret zero byte will do db 0 dw 1 ;One byte dw 13f5h ;Magical place in monitor db senabl ;Enable serial input db 1 t pages parity mov a,m ;Test for a PROM or no memory mov b,a ;Save the original byte cma ;See if this location willJ  codelen equ ($-bios) ;Length of Cbios code if codelen gt 1000h ;Test for SYSGEN problems 'FATAL ERROR, system is too bi52,0 dn set dn+1 alloc hd,%dn,256,0 dn set dn+1 endif if m10 ne 0 alloc hd,%dn,159,0 dn set dn+1 alloc hd,%dn,161 * ***************************************************************** if maxhd ne 0 if hdpart ne 0 ;Use non-standat dn+1 endm blocks set blocks/4 if blocks gt 256 ;Use the remainder blocks set blocks-1 alv set (blocks/8)+1 allocsector (2 bytes) * * Sector number of bad sector (2 bytes) * * Track number of alternate sector (2 bytes) * * Sector numing tracks set mwtrks/mwlog ;Number of tracks per partition dsm set mwsectp/8*tracks/4-1 ;Number of groups per partition ag for SYSGEN rev. 4.X' dbgtmp set codelen ;Cbios code length ! endif if debug dbgtmp set codelen ;Cbios co,0 dn set dn+1 endif if m20 ne 0 alloc hd,%dn,255,0 dn set dn+1 alloc hd,%dn,255,0 dn set dn+1 alloc hd,%dn,129,0rd partitioning tracks set hdtrks/hdlog ;Number of tracks per partition dsm set hdsectp/8*tracks/4-1 ;Number of groups per  mw,%dn,%alv,0 dn set dn+1 endif endm endif endif bioslen equ (high ($-bios))+1 ;BIOS length in pages if bioslber of alternate sector (2 bytes) * * * ***************************************************************** badmap: dlv set (dsm/8)+1 dn set 0 rept maxmw*mwlog ;Generate CKS and ALV tables alloc mw,%dn,%alv,0 dn set dn+1 endm elsede length ! endif ds 512-($-buffer) ;Buffer for 512 byte sectors if (maxfd ne 0) or (maxdm ne 0) or (maxm dn set dn+1 endif endm endif endif if maxfd ne 0 dn set 0 rept maxfd alloc fd,%dn,75,64 dn set dn+1 enpartition alv set (dsm/8)+1 dn set 0 rept maxhd*hdlog ;Generate CKS and ALV tables alloc hd,%dn,%alv,0 dn set dn+1 een gt biosln ;Test for overflow 'FATAL ERROR, system overflow. BIOSLN must be at least' dbgtmp set bioslen ;BIOSLN! s badsiz*9+1 ;32 entries + end marker dirbuf: ds 128 ;Directory buffer tempb: ds 16 ;A little temporary buffer *** ;Use standard partitioning dn set 0 trkoff set 8192/(mwsecpt/8)+1 psize set trkoff*(mwsecpt/8) rept maxmw blocksw ne 0) ds 512 ;Additional space for 1k sector devices endif **********************************************************dm endif if maxdm ne 0 dn set 0 rept maxdm alloc dm,%dn,75,64 dn set dn+1 endm endif if maxmf ne 0 dn setndm else ;Standard partitioning dn set 0 rept maxhd if m26 ne 0 alloc hd,%dn,252,0 dn set dn+1 alloc hd,%dn,2 endif if debug dbgtmp set biosln ;Current BIOSLN! if biosln gt bioslen dbgtmp set bioslen ;Optimal BIOSLN! ************************************************************** * * * Allocation and checked directory table area * * set mwsecpt/8*mwtrks rept blocks/8192 ;Generate some 8 megabyte ALV's alloc mw,%dn,256,0 blocks set blocks-psize dn se******* * * * Each bad map entry consists of 9 bytes: * * Logical drive number (1 byte) * * Track number of bad  0 rept maxmf alloc mf,%dn,22,16 dn set dn+1 endm endif if maxmw ne 0 if mwpart ne 0 ;Use non-standard partitionK  endif endif end L