***************************************************************** * * * CP/M vers 2.2 Cold Start Loader for Disk Jockey 2D (all revs).* * * * Written by Bobby Dale Gifford. * * 11/21/79 * * * * Thå  colä booô loadeò (sectoò 1¬  tracë 0© ió  loadeä * * intï  thå raí oæ thå controlleò bù thå colä booô  routinå  oæ * * thå firmware® The first thing the boot does is to load into * * the controller ram, a version of the Disk Jockey 2D firmware. * * From then on, all calls to the firmware will actually be * * directed to the Disk Jockey Ram. The next process is to load * * in a boot routine which can load in all of CP/M. This is * * done by determining the size of the sectors on track 1, and * * using this information to load in the proper boot into 80H. * * * * The following tables explain the order of sector loading for * * each of the different sector sizes. An entry of ------ * * represents a wrap back around (negative DMA adjustment). * * * * All sector sizes: * * Track 0 sector 1 e700 * * 0 8 3200h * * 0 10 3300h * * 0 12 3400h * * 0 14 3500h * * 0 16 3600h * * 0 18 2d80h * * 0 20 2e80h * * 0 22 2f80h * * 0 24 3080h * * 0 26 3180h * * 0 9 3280h * * 0 11 3380h * * 0 13 3480h * * 0 15 3580h * * 0 17 2d00h * * 0 19 2e00h * * 0 21 2f00h * * 0 23 3000h * * 0 25 3100h * * * * The following depend on the sector size, all sectors are from * * track 1. * * * * 256 512 1024 * * sec address sec address sec address * * 1 3200h 1 3200h 1 3200h * * 3 3400h 3 3600h 3 3a00h * * 5 3600h 5 3a00h 5 4200h * * 7 3800h 7 3e00h ------------- * * 9 3a00h 9 4200h 2 3600h * * 11 3c00h 11 4600h 4 3e00h * * 13 3e00h ------------- 6 4600h * * 15 4000h 2 3400h * * 17 4200h 4 3800h * * 19 4400h 6 3c00h * * 21 4600h 8 4000h * * 23 4800h 10 4400h * * ----------- 12 4800h * * 2 3300h * * 4 3500h * * 6 3700h * * 8 3900h * * 10 3b00h * * 12 3d00h * * 14 3f00h * * 16 4100h * * 18 4300h * * 20 4500h * * 22 4700h * * 24 4900h * * * ***************************************************************** title '*** Cold Boot Loader for CP/M Ver. 2.2 ***' ***************************************************************** * * * Cold Boot loader common to all sector sizes. * * This sector is loaded into memory at e700h in a standard * * configuration. It is responsible for reading most of track 0 * * into memory on cold boots. * * * ***************************************************************** origin equ 0E000H putden equ origin+02dh ;Set density routine on Disk Jockey 2D putdma equ origin+12h ;Disk Jockey 2D set DMA address routine getstat equ origin+27h ;Disk status routine on Disk Jockey 2D putsec equ origin+0fH ;Disk Jockey 2D set sector routine puttrk equ origin+0ch ;Disk Jockey 2D set track routine puthom equ origin+9h ;Disk Jockey 2D track 0 seek doread equ origin+15h ;Disk Jockey 2D read routine boterr equ origin+2ah ;Disk Jockey 2D flash error light routine org origin ;Disk Jockey 2D ram msize equ 24 ;Memory size of target CP/M bias equ (msize-20)*1024 ;Memory offset from 20k system ccp equ 2d00h+bias ;Console command processor bios equ ccp+1600h ;CBIOS address retries equ 10 ;Maximum # of retires diff set origin+700h-$ ;Offset to boot loader address lxi sp,stac+diff firmlod mvi a,6 ;Previous sector # newsec equ $-1 inr a ;Update sector # inr a cpi 27 ;Test if all done jz ccp+500h jc nowrap+diff ;Test if wrap around sui 19 nowrap sta newsec+diff ;Save the updated sector # mov c,a call putsec ;Set up the sector lxi h,ccp+400h ;Previous DMA address newdma equ $-2 lxi d,100h ;Update DMA address dad d mov a,h cpi (ccp+980h)/100h jc nowrp+diff jnz wrp+diff mov a,l cpi (ccp+980h) mod 100h jc nowrp+diff wrp lxi d,-980h dad d nowrp shld newdma+diff ;Save the updated DMA address mov b,h mov c,l call putdma ;Set up the new DMA address lxi b,retries*100h+0;Maximum # of errors fread push b call puttrk ;Set up the proper track call doread ;Read the sector pop b jnc firmlod+diff ;Continue if no error dcr b jnz fread+diff ;Keep trying if error jmp boterr ;To many errors, flash the light ds 80h-($ mod 80h) stac equ $ ***************************************************************** * * * The following equates relate to the Thinker Toys 2D controller* * If the controller is non standard (0E000H) only the ORIGIN * * equate need be changed. This version of the Cbios will work * * with 2D controller boards rev 0, 1, 3, 3.1, 4. * * * ***************************************************************** djram equ origin+400h ;Disk Jockey 2D ram address djboot equ djram ;Disk Jockey 2D Boot routine djcin equ djram+3h ;Disk Jockey 2D character input routine djcout equ djram+6h ;Disk Jockey 2D character output routine djhome equ djram+9h ;Disk Jockey 2D track zero seek djtrk equ djram+0ch ;Disk Jockey 2D track seek routine djsec equ djram+0fh ;Disk Jockey 2D set sector routine djdma equ djram+012h ;Disk Jockey 2D set DMA address djread equ djram+15h ;Disk Jockey 2D read routine djwrite equ djram+18h ;Disk Jockey 2D write routine djsel equ djram+1bh ;Disk Jockey 2D select drive routine djdmast equ djram+24h ;Disk Jockey 2D dma status djstat equ djram+27h ;Disk Jockey 2D status routine djerr equ djram+2ah ;Disk Jockey 2D error, blink led djden equ djram+2dh ;Disk Jockey 2D set density routine djtstat equ djram+21h ;Disk Jockey 2D terminal status routine djside equ djram+30h ;Disk Jockey 2D set side routine ***************************************************************** * * * The following three sectors of code reside at 80H. There is * * one sector for each of the possible sector sizes (256,512, * * 1024). Each sector is responsible for performing a Cold Boot * * for the specified sector size. * * * ***************************************************************** diff set 80h-$ lxi sp,cstk256+diff ;Set up stack at end of this sector lxi b,24*100h+1 ;B = sector count, C = sector # clod256 push b ;Save sector and count call djsec ;Set the next sector to read lxi h,ccp+300h ;Get DMA address (self modifying) cdma256 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 cdma256+diff ;Save new DMA address mov b,h ;Put DMA address into BC mov c,l call djdma ;Set the DMA address call crd256+diff ;Attempt a read pop b ;Recover sector number and count ; B = count, C = number dcr b ;Update sector count jz bios ;All done ? mvi a,2 ;Sector update add c ;Add in the sector skew factor mov c,a ;Put new sector back into C cpi 25 ;Past the end of the track ? jc clod256+diff ;Take jump if not past end of track sui 23 ;Perform a negative sector adjustment mov c,a ;Put new sector in C lxi h,ccp+400h ;Negative DMA adjustment shld cdma256+diff ;Save the new DMA address jmp clod256+diff ;Continue reading ***************************************************************** * * * Crd256 does the actual read from the controller, the DMA * * address and sector # have already been set up. * * * ***************************************************************** crd256 lxi b,retries*100h+1 ;Maximum # of attempts cr256 push b ;Save error count call djtrk ;Initialize the track call djread ;Attempt the read pop b ;Restore the error count rnc ;Return if no error dcr b ;Update error count jnz cr256+diff ;Try again if not to many errors jmp djerr ;Go and flash the light on controller ds 80h-($ mod 80h) cstk256 equ $ ***************************************************************** * * * The next loads CP/M from a 512 byte sector diskette. * * * ***************************************************************** diff set 80h-$ lxi sp,cstk512+diff ;Set up stack at end of this sector lxi b,12*100h+1 ;B = sector count, C = sector # clod512 push b ;Save sector and count call djsec ;Set the next sector to read lxi h,ccp+100h ;Get DMA address (self modifying) cdma512 equ $-2 ;Storage for previous DMA address lxi d,400h ;Offset to new DMA address dad d ;Add in offset, HL = new DMA address shld cdma512+diff ;Save new DMA address mov b,h ;Put DMA address into BC mov c,l call djdma ;Set the DMA address call crd512+diff ;Attempt a read pop b ;Recover sector number and count ; B = count, C = number dcr b ;Update sector count jz bios ;All done ? mvi a,2 ;Sector update add c ;Add in the sector skew factor mov c,a ;Put new sector back into C cpi 13 ;Past the end of the track ? jc clod512+diff ;Take jump if not past end of track sui 11 ;Perform a negative sector adjustment mov c,a ;Put new sector in C lxi h,ccp+300h ;Negative DMA adjustment shld cdma512+diff ;Save the new DMA address jmp clod512+diff ;Continue reading ***************************************************************** * * * Crd512 does the actual read from the controller, the DMA * * address and sector # have already been set up. * * * ***************************************************************** crd512 lxi b,retries*100h+1 ;Maximum # of attempts cr512 push b ;Save error count call djtrk ;Initialize the track call djread ;Attempt the read pop b ;Restore the error count rnc ;Return if no error dcr b ;Update error count jnz cr512+diff ;Try again if not to many errors jmp djerr ;Go and flash the light on controller ds 80h-($ mod 80h) cstk512 equ $ ***************************************************************** * * * The next sector loads CP/M from a 1024 byte sector diskette. * * * ***************************************************************** diff set 80h-$ lxi sp,cstk124+diff ;Set up stack at end of this sector lxi b,6*100h+1 ;B = sector count, C = sector # clod124 push b ;Save sector and count call djsec ;Set the next sector to read lxi h,ccp-300h ;Get DMA address (self modifying) cdma124 equ $-2 ;Storage for previous DMA address lxi d,800h ;Offset to new DMA address dad d ;Add in offset, HL = new DMA address shld cdma124+diff ;Save new DMA address mov b,h ;Put DMA address into BC mov c,l call djdma ;Set the DMA address call crd124+diff ;Attempt a read pop b ;Recover sector number and count ; B = count, C = number dcr b ;Update sector count jz bios ;All done ? mvi a,2 ;Sector update add c ;Add in the sector skew factor mov c,a ;Put new sector back into C cpi 7 ;Past the end of the track ? jc clod124+diff ;Take jump if not past end of track sui 5 ;Perform a negative sector adjustment mov c,a ;Put new sector in C lxi h,ccp+100h ;Negative DMA adjustment shld cdma124+diff ;Save the new DMA address jmp clod124+diff ;Continue reading ***************************************************************** * * * Rd124 does the actual read from the controller, the DMA * * address and sector # have already been set up. * * * ***************************************************************** crd124 lxi b,retries*100h+1 ;Maximum # of attempts cr124 push b ;Save error count call djtrk ;Initialize the track call djread ;Attempt the read pop b ;Restore the error count rnc ;Return if no error dcr b ;Update error count jnz cr124+diff ;Try again if not to many errors jmp djerr ;Go and flash the light on controller ds 80h-($ mod 80h) cstk124 equ $ ***************************************************************** * * * The next three sectors of code also reside at 80H. There is * * one sector for each of the possible sector sizes (256,512, * * 1024). Each sector is responsible for performing a WARM Boot * * for the specified sector size. * * * * The following table shows how sectors are read in, skewing * * of the sectors is necessary because sequential sectors can * * not be read without waiting one complete revolution between * * each one. Entries of ---- represent a wrap around (negative * * DMA adjustment). An entry flagged with ** represents only a * * partial load from that sector. * * * * 256 512 1024 * * sec address sec address sec address * * 1 3200h 1 3200h 1 3200h * * 3 3400h 3 3600h 3 3a00h * * 5 3600h 5 3a00h ** 5 4200h * * 7 3800h 7 3e00h ------------- * * 9 3a00h ** 9 4200h 2 3600h * * 11 3c00h ------------- 4 3e00h * * 13 3e00h 2 3400h * * 15 4000h 4 3800h * * 17 4200h 6 3c00h * * ----------- 8 4000h * * 2 3300h * * 4 3500h * * 6 3700h * * 8 3900h * * 10 3b00h * * 12 3d00h * * 14 3f00h * * 16 4100h * * * ***************************************************************** diff set 80h-$ lxi sp,wstk256+diff ;Set up stack at end of this sector lxi b,17*100h+1 ;B = sector count, C = sector # wlod256 push b ;Save sector and count call djsec ;Set the next sector to read lxi h,ccp+300h ;Get DMA address (self modifying) wdma256 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 wdma256+diff ;Save new DMA address mov b,h ;Put DMA address into BC mov c,l call djdma ;Set the DMA address call wrd256+diff ;Attempt a read pop b ;Recover sector number and count ; B = count, C = number dcr b ;Update the sector count jz bios+3 ;All done ? mvi a,2 ;Sector update add c ;Add in the sector skew factor mov c,a ;Put new sector back into C cpi 19 ;Past the end of the track ? jc wlod256+diff ;Take jump if not past end of track sui 17 ;Perform a negative sector adjustment mov c,a ;Put new sector in C lxi h,ccp+400h ;Negative DMA adjustment shld wdma256+diff ;Save the new DMA address jmp wlod256+diff ;Continue reading ***************************************************************** * * * Wrd256 does the actual read from the controller, the DMA * * address and sector # have already been set up. * * * ***************************************************************** wrd256 lxi b,retries*100h+1 ;Maximum # of attempts wr256 push b ;Save error count call djtrk ;Initialize the track call djread ;Attempt the read pop b ;Restore the error count rnc ;Return if no error dcr b ;Update error count jnz wr256+diff ;Try again if not to many errors jmp djerr ;Go and flash the light on controller ds 80h-($ mod 80h) wstk256 equ $ ***************************************************************** * * * Disk Jockey 2D CP/M from a 512 byte sector diskette. * * * ***************************************************************** diff set 80h-$ lxi sp,wstk512+diff ;Set up stack at end of this sector lxi b,1*100h+9 ;B = sector count, C = sector # call wlod512+diff ;Load sector 9 into CCP lxi h,ccp+1500h ;Destination of move lxi d,ccp+500h ;Source of move mvi c,0 mov512 ldax d ;Get a byte of source mov m,a ;Move it inx h ;Bump destination inx d ;Bump source dcr c ;All done with this page ? jnz mov512+diff lxi h,ccp+300h ;Initial DMA address shld wdma512+diff lxi b,8*100h+2 ;B = sector count, C = sector # call wlod512+diff jmp bios+3 wlod512 push b ;Save sector and count call djsec ;Set the next sector to read lxi h,ccp+100h ;Get DMA address (self modifying) wdma512 equ $-2 ;Storage for previous DMA address lxi d,400h ;Offset to new DMA address dad d ;Add in offset, HL = new DMA address shld wdma512+diff ;Save new DMA address mov b,h ;Put DMA address into BC mov c,l call djdma ;Set the DMA address call wrd512+diff ;Attempt a read pop b ;Recover sector number and count ; B = count, C = number dcr b ;Update sector count rz ;All done ?