;HDDMA Set DMA Address Routine ;----------------------------- ; mwdma: mov h,b ;Set DMA address mov l,c shld dmadma ret ;HDDMA Set Sector Routine ;------------------------ ; mwsec: mov a,c ;Load sector number dcr a ;Range is actaully 0-16 call mwdspt ;Figure out head number -> (c) adi mwspt ;Make sector number sta mwsectr mov a,c sta mwhead ;Save head number ret mwdspt: mvi c,0 ;Clear head counter mwdsptx:sui mwspt ;Subtract a tracks worth of sectors rc ;Return if all done inr c ;Bump to next head jmp mwdsptx mwreset:lhld chan ;Save the command channel for a while shld tempb lda chan+2 sta tempb+2 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 shld 40h ;Set up a pointer to the command channel sta 42h lhld dmarg0 ;Save the track number push h lxi h,dmasel1 ;Load arguments lda mwdrive ;Get the currently selected drive ori 03ch ;Raise *step and *dir mov m,a ;Save in drive select register lxi d,5 ;Offset to dmarg1 dad d mvi m,stepdly ;Load step delay inx h mvi m,headdly ;Head settle delay inx h mvi m,sectsiz ;Sector size code inx h mvi m,dmalcon ;Load constants command call mwissue ;Do load constants pop h ;Restore the track number shld dmarg0 push psw ;Save status lhld tempb ;Restore memory used for the channel pointer shld chan lda tempb+2 sta chan+2 pop psw ret ;HDDMA Read/Write Sector Routines ;-------------------------------- ; mwread: mvi a,dmaread ;Load disk read commnd jmp mwprep mwwrite:mvi a,dmawrit ;Load disk write command mwprep: sta dmaop ;Save command channel op code mvi c,band1 lhld dmarg0 lxi d,precomp call mwhlcde jc mwpreps mvi c,band2 lxi d,lowcurr call mwhlcde jc mwpreps mvi c,band3 ;cylinder > low_current mwpreps:lda mwhead ;Load head address sta dmarg2 cma ;Negative logic for the controller ani 7 ;3 bits of head select rlc ;Shove over to bits 2 - 4 rlc ora c ;Add on low current and precomp bits mov c,a lda mwdrive ;Load drive address ora c ;Slap in drive bits sta dmasel1 ;Save in command channel head select lda mwsectr ;Load sector address sta dmarg3 if 0 ;Set to 1 for MW error reporter mwissue:call mwdoit ;Do desired operation rnc ;Do nothing if no error push psw ;Save error info call hexout ;Print status call dspout ; and a space lxi h,dmachan mvi c,16 ;16 bytes of status mwerr: push b push h mov a,m call hexout ;Print 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 ;Terminate with a CRLF call pout mvi c,0dh call pout pop psw ;Restore error status ret dspout: call spout ;Print two spaces spout: mvi c,' ' ;Print a space jmp pout hexout: push psw ;Poor persons number printer rrc rrc rrc rrc call nibout pop psw nibout: ani 0fh adi '0' cpi '9'+1 jc nibok adi 27h nibok: mov c,a jmp pout mwdoit equ $ else mwissue equ $ ;Do a disk command, handle timeouts + errors endif lxi h,dmastat ;Clear status byte mvi m,0 out attn ;Start the controller lxi d,0 ;Time out counter (65536 retries) mwiloop: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 mwiloop ;Loop if still busy stc ;Set error flag ret mwptr: lda mwdrive ;Get currently select drives track address rlc mov e,a mvi d,0 lxi h,mwtab dad d ;Offset into track table 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 mwhlmde:xchg call mwneghl xchg dad d ret mwhlcde:mov a,h cmp d rnz mov a,l cmp e ret mwtab equ $ ;Collection of track addresses rept maxmw db 0ffh ;Initialize to (way out on the end of the disk) db 0ffh endm db 0ffh mwcurl: db 0 ;Current logical drive mwdrive:db 0ffh ;Currently selected drive mwhead: db 0 ;Currently selected head mwsectr:db 0 ;Currently selected sector dmachan equ $ ;Command channel area dmasel0:db 0 ;Drive select 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 0 ;Second argument dmarg2: db 0 ;Third argument dmarg3: db 0 ;Fourth argument dmaop: db 0 ;Operation code dmastat:db 0 ;Controller status byte dmalnk: dw dmachan ;Link address to next command channel db 0 ;extended address tempb: ds 4 ;Command Channel Pointer Buffer endif page if maxhd ne 0 ;Want HDC3 or 4 controller included ? ;**************************************************************************** ; Begin the HDCA Driver (DDRV4) ;****************************** ; ;HDCA equates ;------------ ; hdorg equ 50h ;Hard Disk Controller origin hdstat equ hdorg ;Disk Status hdcntl equ hdorg ;Disk Control hdreslt equ hdorg+1 ;Disk Results hdcmnd equ hdorg+1 ;Disk Commands hdskomp equ hdorg+2 ;Seek complete clear port (on HDC4) hdfunc equ hdorg+2 ;Function port hddata equ hdorg+3 ;Data port ; Status port (50) tkzero equ 01h ;Track zero opdone equ 02h ;Operation done complt equ 04h ;Seek complete tmout equ 08h ;Time out wfault equ 10h ;Write fault drvrdy equ 20h ;Drive ready index equ 40h ;Delta index ; Control port (50) hdfren equ 01h ;Enable external drivers hdrun equ 02h ;Enable controllers state machine hdclok equ 04h ;Clock source control bit, high = disk hdwprt equ 08h ;Write protect a drive ; Result port (51) retry equ 02h ;Retry flag ; Command port (51) idbuff equ 0 ;Initialize data buffer pointer rsect equ 1 ;Read sector wsect equ 5 ;Write sector isbuff equ 8 ;Initialize header buffer pointer ; Function port (52) hdtrak: db 0ffh ;Track pointer for each drive db 0ffh ;All drive default to an uncalibrated db 0ffh ; state (ff) db 0ffh settle: dw 0 ;Time delay constant for head settle endif page ;******************** ; End of Disk Drivers ;******************** ; ; Cbios ram locations that don't need initialization. ;==================================================== ; if nostand ne 0 ;Unallocated writting variables unaloc: db 0 ;Unallocated write in progress flag oblock: dw 0 ;Last unallocated block number written unadrv: db 0 ;Drive that the block belongs to endif cpmsec: dw 0 ;CP/M sector # cpmdrv: db 0 ;CP/M drive # cpmtrk: dw 0 ;CP/M track # truesec:dw 0 ;Physical sector that contains CP/M sector error: db 0 ;Buffer's error status flag bufdrv: db 0 ;Drive that buffer belongs to buftrk: dw 0 ;Track that buffer belongs to bufsec: dw 0 ;Sector that buffer belongs to alttrk: dw 0 ;Alternate track altsec: dw 0 ;Alterante sector lastdrv:db 0 ;Last selected drive ;***************************************************************; ; ; ; DPB and DPH area. ; ; ; ;***************************************************************; if maxhd ne 0 dphdsk set 0 ;Generate DPH's for the HDCA hard disks rept maxhd ldsk set 0 rept hdlog dphgen hd,%dphdsk,dpbhd,%ldsk ldsk set ldsk+1 dphdsk set dphdsk+1 endm endm if m26 ne 0 dpbhd0: dw 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 ;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 dw 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 sectors/track db 5 ;BSH db 31 ;BLM db 1 ;EXM dw 2047 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1 dw 0 ;CKS 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 ;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 ;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 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 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: dw 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 ;AL1 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 1028 ;DSM dw 511 ;DRM db 0ffh ;AL0 db 0ffh ;AL1 dw 0 ;CKS dw 195 ;OFF db 3 ;SECSIZ endif endif ;End of HD DPH's and DPB's ; DPH's for DJ2DB ;---------------- ; if maxfd ne 0 dn set 0 rept maxfd dphgen fd,%dn,0,0 dn set dn+1 endm endif if maxmw ne 0 ;***************************************************************; ; ; ; mwsectp is the number of 128 byte sectors per cylinder. ; ; mwsectp = 72 * heads ; ; ; ; mwtrks is the total number of data cylinders. ; ; mwtrks = tracks - 1 ; ; ; ;***************************************************************; if st506 ne 0 mwsecpt equ 288 ;Sectors per track mwtrks equ 152 ;Total data tracks endif if st412 ne 0 mwsecpt set 288 mwtrks set 305 endif if cm5619 ne 0 mwsecpt set 432 mwtrks set 305 endif dphdsk set 0 ;Generate DPH's for the HDDMA hard disks rept maxmw ldsk set 0 rept mwlog dphgen mw,%dphdsk,dpbmw,%ldsk dphdsk set dphdsk+1 ldsk set ldsk+1 endm endm off set 1 ;Initial system track offset trkoff set 8192/(mwsecpt/8)+1 ;The number of tracks in a partition blocks set mwsecpt/8*mwtrks ;The number of blocks on the drive psize set trkoff*(mwsecpt/8) ;The number of blocks in a partition ldsk set 0 rept blocks/8192 ;Generate some 8 megabyte DPB's dpbgen mw,%ldsk,%mwsecpt,5,31,1,2047,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 gt 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,%off,4 endif endif ;********************************************************* ;Begin Definitions for the Console and List Device Drivers ;********************************************************* ; ;Define Printer Character Constants ;---------------------------------- acr equ 0Dh ;Carriage return alf equ 0Ah ;Line Feed clear equ 1Ah ;Clear screen on an ADM 3 xoff equ 13h ;Xoff character xon equ 11h ;Xon character if (contyp eq 2) or (lsttyp ge 2) ;Multio or Wunderbuss ;Multio/Wunderbuss Equates ;------------------------- ; The following equates will define the Decision I mother ; board I/O or the Multi I/O environments if needed. ; ;Location Definitions ;-------------------- mbase equ 48h ;Base address of Multi I/O or Decision I rbr equ mbase ;Read data buffer thr equ mbase ;Tranmitter data buffer dll equ mbase ;Divisor (lsb) strobe equ mbase ;parallel port strobe out status equ mbase ;parallel port status in dlm equ mbase+1 ;Divisor (msb) ier equ mbase+1 ;Interupt enable register sensesw equ mbase+1 ;Sense switches, only in gp 06 data equ mbase+1 ;parallel port data buffer clk equ mbase+2 ;WB14 printer select port lcr equ mbase+3 ;Line control register mcr equ mbase+4 lsr equ mbase+5 ;Line status register msr equ mbase+6 grpsel equ mbase+7 ;Group select port ; ;Define Transmitter/Reciever Mask Bytes ;-------------------------------------- dr equ 01h ;Line status DR bit cts equ 10h ;Clear to send dsr equ 20h ;Data set ready thre equ 20h ;Status line THRE bit dlab equ 80h ;Divisor latch access bit ; wls0 equ 1 ;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 ; ; Define Modem Control Register bits ;----------------------------------- dtrenb equ 1 ;DTR enable rtsenb equ 2 ;RTS enable ; ;Define group select Masks ;------------------------- spp equ 0 ;select parallel port s0 equ 01h ;Group number (0-3) s1 equ 02h smask equ 03h bank equ 04h enint equ 08h restor equ 10h ;Printer restore on Multi I/O busy equ 20h ;parallel printer busy mask denable equ 20h ;Driver enable on Multi I/O ; ;Group Port Assignments ;---------------------- congrð eqõ ± ;Consolå porô (1=p1¬ 2=p2¬ 3=p3) lstgrp equ 3 ;Printer port (1=p1, 2=p2, 3=p3) endif ;For Multio/Wunderbuss Definitions page ;**************************** ;Begin Console Device Drivers ;**************************** if contyp eq 0 ;************************ ;Begin Prom Patch (CDRV0) ;************************ ; This driver simply defines the four jumps normally needed to get to ; your actual console drivers. The assumption is that you already have ; these drivers in a ROM; And, furthermore, that the ROM'ed drivers ; exactly match the specs given in the CPM alteration guide for CONIN, ; CONOUT and CONST. Conint is involked du