;********************************************************************** Title 'Cold Boot Loader Rev_E4 27_Jan_83 Copyright_1983 Morrow Designs' ;********************************************************************** ; ;The following Cold Boot Loader Programs are included in this module ;------------------------------------------------------------------- ; DJDMA Disk Jockey DMA controller with 8" Drives ; DJDMA Disk Jockey DMA controller with 5 1/4" Drives ; DJ2DB Disk Jockey 2D Rev_B (8" floppy) controller ; HDDMA Hard Disk DMA controller ; HDC3 Hard Disk Controller rev_3 ; ;Note: ;----- ; Provisions have been made for a Micronix boot loader for use with ; the DJDMA Controller. This loader always gets loaded to 0100h. ; ;System Memroy Maps ;================== ; 1) The following table gives a general idea as to where the ; various parts of of the operating system are in memory. ; 2) The amount of code and table space that can actually be ; loaded from the disk is fixed by the amount of space available ; on the system tracks. ; 3) Our most restrictive (smallest) drive is the 5 1/4 inch ; 'minnie floppy'. This drive has 20 512 byte sectors for ; a total of 10k bytes on the system tracks. The 8 inch ; floppy disk drive is also very close to being filled up. ; 4) Since 512 bytes are reserved for the cold boot loader we ; have a total of 9.5k bytes for the operating 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 data space ; to play with. Right now we are using all of this space ; so any major additions will have to result in a little ; (lot?) of code shuffeling or in the creation of a Cbios ; that simply will not fit on a small disk drive. ; 5) The BIOS can take up as much as 6.4k bytes of space; However, ; only 4k bytes are actually on the disk. The remaining space is ; used for uninitialized storage. ; ; sysgen 48k 56k 60k 62k 64k ; image CP/M CP/M CP/M CP/M CP/M ; ; 900 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ Loader ; B00 9100 B100 C100 C900 D100 CCP ; 1300 9900 B900 C900 D100 D900 BDOS ; 2100 A700 C700 D700 EF00 E700 Cbios ; 3100 B700 D700 E700 FF00 F700 Tables (approx.) ; 35FF BFFF DFFF EFFF F7FF FFFF End of Memory ; ; ~~~~ 8900 A900 B900 C100 C900 DDT page ;***************************** ;Begin User Configuration Area ;***************************** ; ;Define TRUE and FALSE ;--------------------- ; TRUE equ 1 FALSE equ 0 ;Set the Memory Size ;------------------- ; msize equ 48 ;Memory size of target CP/M ;Boot Controller Selection ;------------------------- ; Only one of the following equates should be set to TRUE. The ; others sould be set to FALSE. These equates define the boot loader ; that is to be used. ; dmorder equ TRUE ;Set to boot a DJDMA controller 8" Drives) mforder equ FALSE ;Set to boot a DJDMA controller (5 1/4" Drives) fdorder equ FALSE ;Set to boot a DJ2D/B controller mworder equ FALSE ;Set to boot a HDDMA controller hdorder equ FALSE ;Set to boot an HDC3 controller ;Misc Equates ;------------ ; micron equ FALSE ;Set for Micronix boot loader (only DJDMA) absasm equ TRUE ;set for MAC retries equ 10 ;Maximum # of disk retries page ;***************************** ;Begin Internal System Equates ;***************************** ; ;Sizes ;----- ; biosln equ 14h ;BIOS length in pages ccpln equ 800h ;Length of the CCP bdosln equ 0e00h ;Length of the BDOS size equ (msize*1024) ;Memory size in Kilo-bytes ;Starting addresses ;------------------ ; ccp equ size-(biosln*100h+ccpln+bdosln) bdos equ ccp+ccpln bios equ ccp+ccpln+bdosln if not absasm aseg endif ccpln equ 800h bdosln equ 0e00h bios equ ccp+ccpln+bdosln size equ msize*1024 retries equ 10 load1 equ 100h ;read offset#1 for movcpm ;Load and execution addresses ;---------------------------- ; 1) If this program is being used to boot Micronix, and the load ; address is moved forward from 0100h, then the starting extended ; address for the djdma boot loader should be adjusted. ; if micron eq FALSE loaddr equ ccp ;Load address for floppy cboot equ bios ;Cold boot address for CP/M else ;Micronix boot loader loaddr equ 0100h cboot equ 0100h ;Cold boot address for the loader endif page if (dmorder eq 1) ;****************************************************************** ;Cold boot loader for the Disk Jockey DMA controller using 8" Disks ;****************************************************************** ; ;Disk Map of the Boot Sectors ;============================ ; 1) The loading is identical to that of of the DJ2DB except ; that the loader itself is loaded at 80h ; 2) This program makes use of the fact that the DJDMA has a load track ; command. ; 3) Track 1 is recorded in double density format. There are ; 1024 bytes per sector. ; 4) The warm boot starts from track 0 sector 1 and continues ; through to track 1 sector 1. ; 5) The load address assumes that you're using a 48k system ; ; track sector sysgen load Name ; ; 0 1 900 ff00 Boot loader ; 0 2 980 Unused ; 0 3 a00 ; 0 4 a80 ; 0 5 b00 9100 CCP ; 0 6 b80 9180 ; 0 7 c00 9200 ; 0 8 c80 9280 ; 0 9 d00 9300 ; 0 10 d80 9380 ; 0 11 e00 9400 ; 0 12 e80 9480 ; 0 13 f00 9500 ; 0 14 f80 9580 ; 0 15 1000 9600 ; 0 16 1080 9680 ; 0 17 1100 9700 ; 0 18 1180 9780 ; 0 19 1200 9800 ; 0 20 1280 9880 ; 0 21 1300 9900 BDOS ; 0 22 1380 9980 ; 0 23 1400 9a00 ; 0 24 1480 9a80 ; 0 25 1500 9b00 ; 0 26 1580 9b80 ; ; 1 1 1600 9c00 ; 1 2 1a00 a000 ; 1 3 1e00 a400 CBIOS (@ a700h) ; 1 4 2200 a800 ; 1 5 2600 ac00 ; 1 6 2a00 b000 ; 1 7 2e00 b400 ; 1 8 3200 b800 Unused page ;8" DJDMA Equates ;================ ; ;Define Boot Address for DJDMA boot equ 80h org boot djkick equ 0EFh ;I/O port to start DJDMA controller activity channl equ 50h ;Default Channel Address trkoff equ 22*128 ;Number of bytes loaded from track 0 setdma equ 23h ;Set DMA address djhalt equ 25h ;Halt controller djbran equ 26h ;Branch controller command redtrk equ 29h ;Read track command load2 equ 100h ;read offset#2 for movcpm offset equ 900h-boot ;read offset for DDT page ;Begin 8" DJDMA Executable Code ;============================== ; mvi a,djbran ;Load branch channel command sta channl lxi h,commnd ;Load new command channel address shld channl+1 xra a sta channl+3 djstrt: out djkick ;Start controller djwait: lda djdone ;Get final status ora a ;0 = still busy jz djwait ;Loop if busy lxi h,sectb0 ;Check for bad load lxi b,40ffh ;b = ok, c = loaded lxi d,endtbl-sectb0 ;Error count + # of sectors djloop: mov a,m ;Load sector code cmp c ;Check for 0ffh (already loaded) jz djcont ;Skip if load was 'ok' mov m,c ;Load 'loaded' flag cmp b ;Check for 'ok' status jz djcont ;Skip if load ok inr m ;Make flag = 0 inr d ;Bump error counter djcont: dcr e ;Bump sector count inx h ;Bump table pointer jnz djloop mov a,d ;Check out error counter ora a jz cboot ;Start CP/M if no errors dcr m ;Drop retry counter jnz djstrt ;Retry load operation jmp $ ;Dynamic error halt ;DJDMA Command Strings ;--------------------- ; ;Set the DMA Address commnd: db setdma dw loaddr-512 ;Start at CCP if micron eq FALSE db 0 ;Extended address for CP/M else db 0ffh ;Wrap around from ffff00 to 000100 endif ;Read a Track db redtrk db 0 ;Track 0 db 0 ;Side 0 db 0 ;Drive 0 dw sectb0 ;Sector table 0 db 0 ;Extended address db 0 ;Returned status ;Set the DMA Address db setdma dw loaddr+trkoff ;Load address for track 1 db 0 ;Extended address ;Read a Track db redtrk db 1 ;Track 1 db 0 ;Side 0 db 0 ;Drive 0 dw sectb1 ;Sector table 1 db 0 ;Extended address db 0 ;Returned status ;Halt Command db djhalt djdone: db 0 ;Returned status ;Sector Tables for read track command ;------------------------------------ ; 1) Boot + 5ch contains 'configuration byte' for 5" systems ; org boot+5dh sectb0: dw 0ffffh, 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, 0ff00h ;First seven sectors ;Other Storage ;------------- ; db retries ;Retry counter endtbl equ $-1 ;end of table marker endif ;End of 8" DJDMA Cold Boot Loader page if (mforder eq 1) ;********************************************************************** ;Cold boot loader for the Disk Jockey DMA controller using 5 1/4" Disks ;********************************************************************** ; ;DJDMA Disk Controller (5 1/4" Disks) ;==================================== ; 1) The warm boot starts from track 0 sector 1 and continues ; through to track 1 sector 1. ; 2) The cold boot loader (track 0, sector 0) is loaded into ; RAM at 80h. This loader will start loading from track 0, ; sector 1 and stops at track 1, sector 9. The load ; sequence is as follows: ; ; track sector sysgen load order Name ; 0 0 900 80 0 Cold boot ; 0 1 b00 9500 1 CCP ; 0 2 d00 9700 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 a100 7 ; 0 8 1900 a300 8 ; 0 9 1b00 a500 9 ; ; 1 0 1d00 a700 10 ; 1 1 1f00 a900 11 ; 1 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 ; 1 7 2b00 b500 17 ; 1 8 2d00 b700 18 ; 1 9 2f00 b900 19 page ;5 1/4" DJDMA Equates ;==================== ; ;Define Boot Address for DJDMA boot equ 80h org boot djkick equ 0EFh ;I/O port to start DJDMA controller activity channl equ 50h ;Default Channel Address trkoff equ 9*512 ;Number of bytes loaded from track 0 setdma equ 23h ;Set DMA address djhalt equ 25h ;Halt controller djbran equ 26h ;Branch controller command redtrk equ 29h ;Read track command load2 equ 100h ;read offset#2 for movcpm offset equ 900h-boot ;read offset for DDT page ;Begin 5 1/4" DJDMA Executable Code ;================================== ; mvi a,djbran ;Load branch channel command sta channl lxi h,commnd ;Load new command channel address shld channl+1 xra a sta channl+3 djstrt: out djkick ;Start controller djwait: lda djdone ;Get final status ora a ;0 = still busy jz djwait ;Loop if busy lxi h,sectb0 ;Check for bad load lxi b,40ffh ;b = ok, c = loaded lxi d,endtbl-sectb0 ;Error count + # of sectors djloop: mov a,m ;Load sector code cmp c ;Check for 0ffh (already loaded) jz djcont ;Skip if load was 'ok' mov m,c ;Load 'loaded' flag cmp b ;Check for 'ok' status jz djcont ;Skip if load ok inr m ;Make flag = 0 inr d ;Bump error counter djcont: dcr e ;Bump sector count inx h ;Bump table pointer jnz djloop mov a,d ;Check out error counter ora a jz cboot ;Start CP/M if no errors dcr m ;Drop retry counter jnz djstrt ;Retry load operation jmp $ ;Dynamic error halt ;DJDMA Command Strings ;--------------------- ; ;Set the DMA Address commnd: db setdma dw loaddr-512 ;Start at CCP if micron eq 0 db 0 ;Extended address for CP/M else db 0ffh ;Wrap around from ffff00 to 000100 endif ;Read a Track db redtrk db 0 ;Track 0 db 0 ;Side 0 db 0 ;Drive 0 dw sectb0 ;Sector table 0 db 0 ;Extended address db 0 ;Returned status ;Set the DMA Address db setdma dw loaddr+trkoff ;Load address for track 1 db 0 ;Extended address ;Read a Track db redtrk db 1 ;Track 1 db 0 ;Side 0 db 0 ;Drive 0 dw sectb1 ;Sector table 1 db 0 ;Extended address db 0 ;Returned status ;Halt Command db djhalt ;Halt controller djdone: db 0 ;Returned status ;Sector tables for read track command ;------------------------------------ ; 1) Boot + 5ch contains 'configuration byte' for 5" drives org boot+5dh sectb0: dw 0ffh, 0, 0, 0, 0 ;Do not load boot loader sectb1: dw 0, 0, 0, 0, 0 ;Load ten sectors ;Other storage ;------------- ; db retries ;Retry counter endtbl equ $-1 ;end of table marker endif ;End of 5 1/4" DJDMA Cold Boot Loader page if (fdorder eq 1) ;************************************************************* ;Cold boot loader for the Disk Jockey 2D Revision B controller ;************************************************************* ; ;Disk Map of the Boot Sectors ;============================ ; 1) The 'order' column is the interleave sequence used by the ; loader during the load. ; 2) Three spare sectors (track 0, sectors 2 to 4) have been ; provided for a more advanced boot loader at a later date. ; 3) The warm boot loader starts on track 0, sector 5 and ; continues through to track 1 sector 3. Only the first ; 3/4 K bytes of track 1, sector 3 is loaded since CP/M ; requires that the warm boot loader load up to the start ; of (but not past) the Cbios jump table. ; ; track sector sysgen load order Name ; ; 0 1 900 ff00 0 Boot loader ; 0 2 980 Unused ; 0 3 a00 ; 0 4 a80 ; 0 5 b00 9100 1 CCP ; 0 6 b80 9180 12 ; 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 ; 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 17 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 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 1 is recorded in double density format. There are ;1024 bytes per sector. ; ; 1 1 1600 9c00 4 ; 1 2 1a00 a000 1 ; 1 3 1e00 a400 5 CBIOS (@ a700h) ; 1 4 2200 a800 2 ; 1 5 2600 ac00 6 ; 1 6 2a00 b000 3 ; 1 7 2e00 b400 7 ; 1 8 3200 b800 Unused page ;DJ2DB Equates ;============= ; ;Define Boot Address for DJ2DB boot equ djram+300h ;Upper 3/4 of on board floppy RAM org boot origin equ 0f800h ;Orgin of DJ 2D Mod B PROM djram equ origin+400h ;Disk Jockey 2D Mod B routines tkzero equ origin+9h ;Track 0 seek trkset equ origin+0ch ;Set track setsec equ origin+0fH ;Set sector setdma equ origin+12h ;Set DMA address dread equ origin+15h ;Read sector dmast equ origin+24h ;Get DMA address status equ origin+27h ;Disk status dskerr equ origin+2ah ;Flash error light setden equ origin+2dh ;Set density load2 equ 100h ;read offset#2 for movcpm offset equ 900h-boot ;read offset for DDT page ;Begin DJ2DB Executable Code ;=========================== t0boot: mvi a,5-2 ;First sector - 2 newsec equ $-1 inr a ;Update sector # inr a 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 track exit equ $-2 sui 27-6 ;Back up to sector 6 backup equ $-1 lxi h,loaddr-80h ;Memory address of sector - 100h nxtdma equ $-2 shld newdma nowrap: sta newsec ;Save the updated sector # mov c,a call setsec ;Set up the sector lxi h,loaddr-100h ;Memory address of sector - 100h newdma equ $-2 lxi d,100h ;Update DMA address secsiz equ $-2 dad d nowrp: shld newdma ;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 # of errors, track # nxtrty equ $-2 fread: push b call trkset ;Set up the proper track call dread ;Read the sector pop b jnc t0boot ;Continue if no error dcr b jnz fread ;Keep trying if error jmp dskerr ;Too many errors, flash the light t1boot: lxi h,cboot ;We jump to cboot next time shld exit mvi c,1 ;Select double density call setden xra a ;First sector - 2 sta newsec mvi a,8 ;Size of (logical) track + 1 sta trksiz dcr a ;Number of sectors to back up sta backup lxi h,loaddr+0700h ;DMA start address for first revolution - 2048 shld newdma lxi h,loaddr+0300h ;DMA start address for second revolution - 2048 shld nxtdma lxi h,2048 ;Difference between DMA addresses shld secsiz lxi h,retries*100h+1;Maximum # of errors, track # shld nxtrty jmp t0boot ;Go load in track 1 endif ;End of DJ2DB Cold Boot Loader page if (mworder eq 1) ;***************************************** ;Cold Boot loader for the HDDMA Controller ;***************************************** ; ;Disk Map of the Boot Sectors (Shugart SA1000 disk interface) ;============================================================ ; 1) Since 1k byte sectors were implemented on this disk ; track 0, sector 1 contains both the cold boot loader and ; part of the CCP. The cold boot loader relocates this ; piece of the CCP to it proper resting place as part of ; the boot process. ; ; track sector sysgen load order Name ; 0 1 900 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 9f00 4 ; 0 6 1d00 a300 5 ; 0 7 2100 a700 6 Cbios ; 0 8 2500 ab00 7 ; 0 9 2900 af00 8 ; ; 1 10 2d00 b300 9 page ;HDDMA Equates ;============= ; ;Define Boot Address for HDDMA boot equ 100h org boot cyl equ 153 ;Specifications for a Seagate Technology 506 heads equ 4 ;Number of heads per cylinder spt equ 9 ;Sectors per track precomp equ 64 ;Cylinder to start write precomensation lowcurr equ 128 ;Cylinder to start low current stepdly equ 30 ;Step delay (0-12.7 milliseconds) headdly equ 20 ;Settle delay (0-255 milliseconds) sectsiz equ 7 ;Sector size code (must be 7 for this Cbios) ;0 = 128 byte sectors ;1 = 256 byte sectors ;3 = 512 byte sectors (default for Micronix) ;7 = 1024 byte sectors (default for CP/M) ;f = 2048 byte sectors ;Define controller commands dmaread equ 0 ;Read sector dmawrit equ 1 ;Write sector dmarhed equ 2 ;Find a sector dmawhed equ 3 ;Write headers (format a track) dmalcon equ 4 ;Load disk parameters dmassta equ 5 ;Sense disk drive status dmanoop equ 6 ;Null controller operation reset equ 54h ;Reset controller attn equ 55h ;Send a controller attention chan equ 50h ;Default channel address stepout equ 10h ;Step direction out stepin equ 0 ;Step direction in band1 equ 40h ;No precomp, high current band2 equ 0c0h ;Precomp, high current band3 equ 80h ;precomp, low current track0 equ 1 ;Track zero status wfault equ 2 ;Write fault from drive dready equ 4 ;Drive ready load2 equ 100h ;read offset#2 for movcpm offset equ 900h-boot ;read offset for DDT page ;Begin HDDMA Executable Code ;=========================== ; lxi sp,cstkhd ;Set up stack at end of this sector lxi h,boot+200h ;Copy part of CCP up lxi d,loaddr lxi b,200h movlop: mov a,m ;Get 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 lxi b,10*100h+2 ;B = sector count, C = sector # call clodhd jmp cboot ;Go to CP/M clodhd: push b ;Save sector and count mov a,c ;Load sector sta hdsec lxi h,loaddr-200h ;Get DMA address (self modifying) cdmahd equ $-2 ;Storage for previous DMA address lxi d,400h dad d ;Add in offset, HL = new DMA address shld cdmahd ;Save new DMA address call crdhd ;Attempt a read pop b ;Recover sector number and count ; B = count, C = number dcr b ;Update sector count rz ;All done ? inr c ;Bump sector number jmp clodhd ;Continue reading page ;Low level HDDMA drivers ;------------------------ ; crdhd does the actual read from the controller, the DMA ; address and sector # have already been set up. ; crdhd: call hdsetup ;Set up parameters lxi b,retries*100h+1 ;Maximum # of attempts crhd: push b ;Save error count call hdissue ;Attempt the read pop b ;Restore the error count rnc ;Return if no error dcr b ;Update error count jnz crhd ;Try again if not too many errors error: jmp $ ;Dynamic error halt hdsetup:shld dmadma ;Set up DMA address call hdreset ;Reset controller lda hdsec ;Set logical sector number dcr a ;Range is actaully 0-16 call divspt ;Figure out head number -> (c) adi spt ;Make real sector number sta dmarg3 mov a,c sta dmarg2 ;Save head number cma ;Negative logic for the controller ani 7 ;3 bits of head select rlc ;Shove over to bits 2 - 4 rlc sta dmasel1 ;Save in command channel head select ret divspt: mvi c,0 ;Clear head counter divsptx:sui spt ;Subtract a tracks worth of sectors rc ;Return if all done inr c ;Bump to next head jmp divsptx hdreset:mvi a,(ret) ;One time code sta hdreset out reset ;Send reset pulse to controller lxi h,dmachan ;Address of command channel shld chan ;Default channel address xra a sta chan+2 ;Clear extended address byte xthl ;Wait for reset (around 10 uSEC's) xthl call hdissue ;Do load constants jc error ;Controller not present mvi a,dmassta ;Sense status command sta dmaop rdychek:call hdissue ani dready ;Check for drive ready jnz rdychek ;Loop if not ready lxi h,0ffffh shld dmastep ;Do recalibrate call hdissue lxi h,0 shld dmastep ;Clear step counter shld dmarg0 ;Clear cylinder # shld dmarg3 ;Clear sector # + read disk command ret hdissue:lxi h,dmastat ;Status byte mvi m,0 out attn ;Start controller lxi d,0 ;Time out counter mov b,e ;Controller busy status hdiloop:mov a,m ;Get status ora a ;Set up CPU flags rm ;Return no error (carry reset) stc rnz ;Return error status xthl ;Waste some time xthl xthl xthl dcx d ;Bump timeout counter mov a,d ora e jnz hdiloop ;Loop if still busy stc ;Set error flag ret hdsec: db 0 ;Currently selected sector dmachan equ $ ;Command channel area dmasel0:db 10h ;Drive select (step out, drive 0) dmastep:dw 0 ;Relative step counter dmasel1:db 0 ;Head select dmadma: dw 0 ;DMA address db 0 ;Extended address dmarg0: db 0 ;First argument dmarg1: db stepdly ;Second argument (stepping time) dmarg2: db headdly ;Third argument (Settle time) dmarg3: db sectsiz ;Fourth argument (Sector size) dmaop: db dmalcon ;Operation code dmastat:db 0 ;Controller status byte dmalnk: dw dmachan ;Link address to next command channel db 0 ;extended address org boot+200h cstkhd equ $ ;Stack area at end of sector endif ;End of HDDMA Cold Boot Loader page if (hdorder eq 1) ;************************************ ;Cold Boot loader for HDC3 Controller ;************************************ ; ;Disk Map of the Boot Sectors (Shugart SA4000 disk interface) ;============================================================ ; 1) The cold boot loader (track 0, sector 1) is loaded into ; RAM in the very last part of the Cbios. This area is ; used for uninitialized tables and thus is a safe place ; for the loader. This cold boot loader will start loading ; the CCP from track 0, sector 2 and will finish up with ; the last part of the Cbios on track 0, sector 20. ; 2) The warm boot load sequence starts at track 0, sector 2 ; and goes straight through to sector 12. There is still ; plenty of room left in this loader for more advanced ; things like sector interleaving although this is hardly ; necessary on a hard disk. ; ; track sector sysgen load order Name ; 0 1 900 fc00 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 1300 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 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 16 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 3100 Unused page ;HDC3 Equates ;============ ; ;Define Boot Address for HDC3 boot equ size-512 ;very last part of CP/M system org boot hdorg equ 50h ;Hard Disk Controller hdstat equ hdorg ;Hard Disk Status hdcntl equ hdorg ;Hard Disk Control hddata equ hdorg+3 ;Hard Disk Data hdfunc equ hdorg+2 ;Hard Disk Function hdcmnd equ hdorg+1 ;Hard Disk Command hdreslt equ hdorg+1 ;Hard Disk Result retry equ 2 ;Retry bit of result tkz equ 1 ;Track zero bit of status opdone equ 2 ;Operaction done bit of status complt equ 4 ;Complete bit of status tmout equ 8 ;Time out bit of status wfault equ 10h ;Write fault bit of status drvrdy equ 20h ;Drive ready bit of status indx equ 40h ;Index bit of status pstep equ 4 ;Step bit of function nstep equ 0fbh ;Step bit mask of function hdrlen equ 4 ;Sector header length secln equ 512 ;Sector data length wenabl equ 0fh ;Write enable wreset equ 0bh ;Write reset of function scenbl equ 5 ;Controller control dskclk equ 7 ;Disk clock for control mdir equ 0f7h ;Direction mask for function null equ 0fch ;Null command idbuff equ 0 ;Initialize data command isbuff equ 8 ;Initialize header command rsect equ 1 ;Read sector command wsect equ 5 ;Write sector command load2 equ 0h ;read offset#2 for movcpm offset equ 900h-boot ;read offset for DDT page ;Begin HDC3 Executable Code ;========================== ; lxi sp,cstkhd ;Set up stack at end of this sector lxi b,19*100h+2 ;B = sector count, C = sector # call clodhd jmp cboot ;Go to CP/M clodhd: push b ;Save sector and count mov a,c ;Load sector sta hdsec lxi h,loaddr-200h ;Get DMA address (self modifying) cdmahd equ $-2 ;Storage for previous DMA address lxi d,200h ;Offset to new DMA address dad d ;Add in offset, HL = new DMA address shld cdmahd ;Save new DMA address call crdhd ;Attempt a read pop b ;Recover sector number and count ; B = count, C = number dcr b ;Update sector count rz ;All done ? inr c ;Bump sector number jmp clodhd ;Continue reading page ;Low level HDC3 drivers ;---------------------- ; crdhd does the actual read from the controller, the DMA ; address and sector # have already been set up. ; crdhd: lxi b,retries*100h+1 ;Maximum # of attempts crhd: push b ;Save error count call hdread ;Attempt the read pop b ;Restore the error count rnc ;Return if no error dcr b ;Update error count jnz crhd ;Try again if not too many errors jmp $ ;Dynamic error halt hdread: call hdprep ;Prepare the sector header image rc ;Error exit mvi a,rsect ;Read sector command out hdcmnd call process ;Process the read rc ;Error exit xra a ;Pointer to data buffer out hdcmnd mvi b,secln/4 ;Number of bytes to read lhld cdmahd ;Get destination of data in hddata ;Two dummy data bytes in hddata rtloop: in hddata ;Move four bytes mov m,a ;Byte one 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 inx h dcr b ;Update byte count jnz rtloop ret process:in hdstat ;Wait for command to finish mov b,a ani opdone jz process mvi a,dskclk ;Turn on Disk Clock out hdcntl in hdstat ani tmout ;Timed out ? stc rnz in hdreslt ani retry ;Any retries ? stc rnz xra a ;No error exit ret hdprep: in hdstat ;Is Drive ready ? ani drvrdy stc rnz mvi a,isbuff ;Initialize pointer to header buffer out hdcmnd mvi a,null out hdfunc ;Select drive A xra a out hddata ;Form head byte out hddata ;Form track byte mvi a,0 ;Form sector byte hdsec equ $-1 out hddata mvi a,80h ;Form Key out hddata mvi a,dskclk ;Turn on Disk clock out hdcntl mvi a,wenabl ;Write enable on out hdcntl ret org boot+200h-2 ;Last word on sector is load address cstkhd equ $ dw boot endif ;End of HDC3 Cold Boot Loader end