title TRACK 0 LOADER -- WD 1793, 2793; HDC-1001 ;-------------------------------- ; author Marcus G. Calescibetta ; date October 20, 1983 ; version 2.42 ;-------------------------------- .z80 ; Zilog mneumonics used ;------------------------- ; HDC-1001 PORT ADDRESSES ;------------------------- hbase equ 0e0h ; base port address of hdc-1001 hdata equ hbase+0 ; data register herror equ hbase+1 ; error register hwrtpre equ hbase+1 ; write pre-compensation register hseccnt equ hbase+2 ; sector count register hsec equ hbase+3 ; sector number register hcyllow equ hbase+4 ; cylinder low register hcylhi equ hbase+5 ; cylinder high register hsdh equ hbase+6 ; size - drive - head register hstatus equ hbase+7 ; status register hcmd equ hbase+7 ; command register ;------------------- ; HDC-1001 COMMANDS ;------------------- cmdrst1 equ 01eh ; restore soft sector drive cmdrst2 equ 01fh ; restore hard sector drive cmdrd equ 020h ; read sector command cmdwrt equ 030h ; write sector command ;----------------------------- ; STATUS REGISTER BIT TESTERS ;----------------------------- bsybit equ 080h ; busy bit rdybit equ 040h ; data request bit errbit equ 001h ; error bit ;----------------------------- ; FLOPPY CONTROLLER REGISTERS ;----------------------------- fbase equ 0ch ; base port addr of wd-1793 or wd-27 fcmd equ fbase+0 ; command register fstat equ fbase+0 ; status register ftrk equ fbase+1 ; track register fsec equ fbase+2 ; sector register fdata equ fbase+3 ; data register fwait equ 014h ; wait register fdsd equ 014h ; density - size - drive register fcb equ 00005Ch ; fcb base addr fcbcr equ fcb+32 ; fcb current record addr buf equ 00900h ; buffer for track 0 loader boot equ 00000h ; jump to warm boot addr bdos equ 00005h ; jump to bdos addr coni equ 01h ; bdos console input function no. cono equ 02h ; bdos console output function no. cr equ 0dh ; ascii value for carriage return lf equ 0ah ; ascii value for line feed ;------------------ ; START OF PROGRAM ;------------------ start: ld sp,stack ; initalize stack pointer ld hl,signon ; load hl w addr of signon msg call outmsg ; display signon msg on console ;-------------------------------- ; CHECK FOR FILE IN COMMAND LINE ;-------------------------------- ckf: ld a,(fcb+1) ; load a w. first letter of cmd tail cp ' ' ; check if its blank jp z,getldr ; jump if no command tail ;----------- ; OPEN FILE ;----------- opf: ld de,fcb ; load de w fcb addr for bdos call call open ; try and oper file given if cmd line inc a ; bdos returns a 255 if file not found jp z,fnf ; jump if no file ;----------- ; READ FILE ;----------- rdf: xor a ; clear a register ld (fcbcr),a ; set current record to zero ld de,buf ; this is where the file is read into rdflp: push de ; save buffer addres so can update call dma ; tell bdos to read file into buffer ld de,fcb ; set up for bdos read call dread ; read one logical record pop de ; recall current buffer address or a ; check if read successful jr nz,putldr ; assume EOF if error on read ld hl,080h ; load hl w size of logical record add hl,de ; add in curr bf addr so hl is new addr ex de,hl ; put new bf add in de for dma call jr rdflp ; read in next logical record ;------------------------------ ; GET SYSTEM FROM SOURCE DRIVE ;------------------------------ getldr: ld hl,stypmsg call crmsg call getcc ld (drvtyp),a cp cr jp z,putldr cp 'H' jr z,gethrd cp 'F' jr nz,getldr getfpy: ld hl,smsg call getdrv ld (sdrv),a ld a,(sdrv) call setden call frdtrk jp putldr gethrd: ld hl,smsg call getdrv ld (sdrv),a ld a,(sdrv) call hrdtrk jp putldr ;--------------------------------- ; PUT SYSTEM ON DESTINATION DRIVE ;--------------------------------- putldr: ld a,(drvtyp) and a jr z,getdtyp cp 0dh jr nz,putjmp getdtyp: ld hl,dtypmsg call crmsg call getcc cp cr jp z,reboot putjmp: cp 'H' jp z,puthd cp 'F' jr nz,putldr putfpy: ld hl,dmsg call getdrv ld (ddrv),a ld a,(ddrv) call setden ld a,(ddrv) call patchden ld a,(ddrv) call setden call fwrttrk jp reboot puthd: ld hl,dmsg call getdrv ld (ddrv),a ld a,(ddrv) call hwrttrk jp reboot ;-------------------------- ; SET DISK DENSITY TRK 000 ;-------------------------- setden: tst5dd: ld (drv),a ld b,018h or b out (fwait),a ld (dsd),a ld d,04 ld a,d ld (buf+07eh),a ld hl,tst8sd jr frestore tst8sd: ld a,(drv) out (fwait),a ld (dsd),a ld hl,tst8dd ld d,026d ld a,d ld (buf+07eh),a jr frestore tst8dd: ld a,(drv) ld b,08h or b out (fwait),a ld (dsd),a ld hl,trk0err ld d,04 ld a,d ld (buf+07eh),a jò frestore trk0err: ld hl,tk0rder call crmsg jp 0 frestore: call tstrdy ld a,0fh out (fcmd),a call delay in a,(fwait) in a,(fcmd) and 018h ret z jp (hl) ;----------------------------------------------------- ; GET DISK DENSITY OF TRK 001 AND PATCH TO LOC. buf+07fh ;----------------------------------------------------- patchden: chk5dd: ld (drv),a ld b,018h or b out (fwait),a ld (dsd),a ld hl,chk8sd jr fseek chk8sd: ld a,(drv) out (fwait),a ld (dsd),a ld a,0e5h ld (buf+07fh),a ld hl,chk8dd jr fseek chk8dd: ld a,(drv) ld b,08h or b out (fwait),a ld (dsd),a ld a,0e6h ld (buf+07fh),a ld hl,sekerr jò fseek sekerr: ld hl,sekmsg call crmsg jp 0 fseek: call tstrdy ld a,1 out (fdata),a ld a,01eh out (fcmd),a call delay in a,(fwait) in a,(fcmd) and 018h jr z,chkds jp (hl) chkds: ld a,(buf+07fh) and 0e5h ret z ld a,(dsd) set 2,a out (fwait),a ; call tstrdy di ld c,fdata ld hl,trkid ld a,0c4h out (fcmd),a call delay frdalp: in a,(fwait) or a jp p,frdax ini jr frdalp frdax: in a,(fcmd) and 018h ret nz ld a,(sideno) and a ret z ld a,0e7h ld (buf+07fh),a ret ;-------------------- ; FLOPPY WRITE TRACK ;-------------------- fwrttrk: call tstrdy in a,(fstat) bit 6,a jr z,nwrtpro ld hl,wrpmsg call crmsg call getcc cp 3 jp z,reboot jp fwrttrk nwrtpro: ld e,1 ld c,fdata ld hl,buf nextsec: di ld a,e out (fsec),a xor a out (ftrk),a ld a,0a4h out (fcmd),a fwrtlp: in a,(fwait) or a jp p,fwrtout outi jr fwrtlp fwrtout: ei ld a,d cp e jp z,reboot inc e jr nextsec ;----------------- ; HARD READ TRACK ;----------------- hrdtrk: ld (drv),a ld de,0512d ; bytes per sector ld b,020h ; sdh reg sec. size setting ld c,016d ; sector per track call settsk ld a,cmdrst1 out (hcmd),a call polbsy ld a,cmdrd out (hcmd),a call polbsy jr z,hrdsec ld de,0256 ld b,0 ld c,32d call settsk ld a,cmdrst2 out (hcmd),a call polbsy ld a,cmdrd out (hcmd),a call polbsy jr z,hrdsec hrderr: ld hl,tk0rder call crmsg jp 0 hrdsec: ld (bps),de ld de,0 ld hl,buf hrdnx: ld a,d out (hsec),a ld a,cmdrd out (hcmd),a call polbsy call rxdata call polbsy jp nz,hrderr inc d ld a,c cp d jp nz,hrdnx ret ;------------------ ; HARD WRITE TRACK ;------------------ hwrttrk: ld (drv),a ld de,0512d ; bytes per sector ld b,020h ; sdh reg sec. size setting ld c,016d ; sector per track call settsk ld a,cmdrst1 out (hcmd),a call polbsy ld a,cmdrd out (hcmd),a call polbsy jr z,hwrtsec ld de,0256 ld b,0 ld c,32d call settsk ld a,cmdrst2 out (hcmd),a call polbsy ld a,cmdrd out (hcmd),a call polbsy jr z,hwrtsec hwrterr: ld hl,tk0wrer call crmsg jp 0 hwrtsec: ld (bps),de ld de,0 ld hl,buf hwrtnx: ld a,d out (hsec),a ld a,cmdwrt out (hcmd),a call polbsy call snddata call polbsy jp nz,hwrterr inc d ld a,c cp d jp nz,hwrtnx ret ;------------------------------ ; HARD DISK SET TASK REGISTERS ;------------------------------ settsk: ld a,(drv) sla a sla a sla a or b out (hsdh),a xor a out (hcylhi),a out (hcyllow),a out (hsec),a ret ;----------- ; POLL BUSY ;----------- polbsy: in a,(hstatus) and a jp m,polbsy and 1 ret ;-------------- ; RECIEVE DATA ;-------------- rxdata: push bc ld a,(bps) ld b,a ld c,hdata inir ld a,(bps+1) and 2 jp z,rxx inir rxx: pop bc ret ;----------- ; SEND DATA ;----------- snddata: push bc ld a,(bps) ld b,a ld c,hdata otir ld a,(bps+1) and 2 jp z,sndx otir sndx: pop bc ret ;-------------------- ; FLOPPY READ TRACK ;-------------------- frdtrk: call tstrdy ld e,1 ld c,fdata ld hl,buf rdsec: di ld a,e out (fsec),a xor a out (ftrk),a ld a,084h out (fcmd),a frdlp: in a,(fwait) or a jp p,frdout ini jr frdlp frdout: ei ld a,d cp e ret z inc e jr rdsec ;-------------------------------- ; GET SOURCE - DESTINATION DRIVE ;-------------------------------- getdrv: push hl call crmsg call getc pop hl cp cr jð z,reboot cp '0' jp c,getdrv cp '4' jp nc,getdrv and 00fh ret ;------------------------------- ; TEST IF FLOPPY DRIVE IS READY ;------------------------------- tstrdy: push hl push de push bc push af tststart: ld a,0d0h out (fcmd),a call delay ld de,0ffffh ld hl,tstnidx tstnidx: in a,(fstat) bit 1,a jr nz,decde ld hl,tstidx tstidx: in a,(fstat) bit 1,a jr z,decde ld hl,tstrdx tstrdx: in a,(fstat) bit 7,a jr z,tstx decde: dec de ld a,d or e jr z,notready jp (hl) tstx: pop af pop bc pop de pop hl ret notready: ld hl,nrdymsg call crmsg call getcc cp 3 jp z,reboot jp tststart ;--------------------- ; DELAY 28 US AT 6MHZ ;--------------------- delay: ld a,3 delaylp: ex (sp),hl ex (sp),hl dec a jr nz,delaylp ret ;------------------------------------------------ ; GET UPPER CASE CHARACTER FROM CONSOLE KEYBOARD ;------------------------------------------------ getcc: ld c,coni call bdos and 05fh ret ;------------------------------------- ; GET CHARACTER FROM CONSOLE KEYBOARD ;------------------------------------- getc: ld c,coni call bdos ret ;------------------------------ ; DISPLAY CHARACTER ON CONSOLE ;------------------------------ putc: ld e,a ld c,cono call bdos ret ;-------------------------- ; DISPLAY CR,LF ON CONSOLE ;-------------------------- crlf: ld a,cr call putc ld a,lf call putc ret ;------------------------------ ; DISPLAY CR,LF,MSG ON CONSOLE ;------------------------------- crmsg: push hl ; display cr,lf, msg pointed to by hl call crlf ; until zero encountered pop hl ;DROP THRU TO OUTMSG0 outmsg: ld a,m or a ret z push hl call putc pop hl inc hl jp outmsg ;----------------------------------- ; READ LOGICAL SECTOR INTO DMA ADDR ;----------------------------------- dread: ld c,014h jp bdos ;----------- ; OPEN FILE ;----------- open: ld c,00fh jp bdos ;----------------- ; SET DMA ADDRESS ;----------------- dma: ld c,01ah jp bdos ;---------------- ; FILE NOT FOUND ;---------------- fnf: ld hl,nofile call crmsg xor a ld (fcb+13),a ld hl,fcb+1 call outmsg ;------ ; EXIT ;------ reboot: call crlf jp boot ;-------------- ; DATA STORAGE ;-------------- signon: db 'LDRGEN 2.42',cr,lf,0 nofile: db 'Can''nt open file: ',0 stypmsg: db 'Read loader from Hard or Floppy drive (H,F) : ',0 dtypmsg: db 'Write loader to Hard or Floppy drive (H,F) : ',0 smsg: db 'Physical drive no. of loader source (0-3) : ',0 dmsg: db 'Physical drive no. of loader destination (0-3) : ',0 nrdymsg: db 'Drive Not Ready : ',0 wrpmsg: db 'Disk Write Protected : ',0 tk0rder: db 'Cannot Read Track 000',0 tk0wrer: db 'Cannot Write Track 000',0 sekmsg: db 'Cannot Read Track 1',0 drvtyp: db 0 ; 'H' or 'F' sdrv: db 0 ; source drive ddrv: db 0 ; destination drive drv: db 0 ; working variable den: db 0 ; disk density byte dsd: db 0 ; bps: dw 0 ; hd bytes per sector trkid: trkno: db 0 sideno: db 0 secno: db 0 seclen: db 0 crc1: db 0 crc2: db 0 ds 040h stack: end