; ; prototype cbios - utilizes RAMdisk and IDE drive ; Version 1.0 4/6/2008 ; ; System Equates ; 0040 msize equ 64 ; #K of RAM in system 0080 nbytes equ 128 ; bytes per sector (RAMdrive) a600 bias equ 0a600h ; bias to start of CCP da00 ccp equ bias+3400h ; bias + 3400h = CCP e206 bdos equ ccp+806h ; start of BDOS f000 orgadr equ ccp+1600h 1600 cpml equ orgadr-ccp ; size of warm load 0003 iob equ 3 0004 romt equ 4 ; toggles lower 32K RAM/ROM 000d cr equ 0dh ; carriage return 000a lf equ 0ah ; line feed ; ; CP/M Linkages to BIOS ; f000 org orgadr ; f000 c3 90 f0 cbios: jp boot ; enter here from cold boot f003 c3 a0 f0 wboote: jp wboot ; warm boot f006 c3 2f f1 jp const ; console status f009 c3 37 f1 jp conin ; console input f00c c3 41 f1 jp conout ; console output f00f c3 4b f1 jp list ; listing output f012 c3 4b f1 jp punch ; punch output f015 c3 55 f1 jp rdr ; reader input f018 c3 69 f1 home: jp hme ; restore drive to trk00 f01b c3 77 f4 seldsk: jp seld ; select drive f01e c3 6c f1 settrk: jp strk ; set track f021 c3 71 f1 setsec: jp ssec ; set sector f024 c3 76 f1 setdma: jp sdma ; set disk transfer address f027 c3 7b f1 rde: jp read ; read from disk f02a c3 a4 f1 wre: jp write ; write to disk f02d c3 61 f1 jp lstst ; read LST device status f030 c3 74 f4 jp sectran ; translate log. to phys. sector ; ; DISK PARAMETER HEADERS FOR BDOS ; f033 00 00 00 00 dpbase: dw 0,0 ; disk A (RAM disk) f037 00 00 00 00 dw 0,0 f03b a7 f6 63 f0 dw dirbuf,rddub f03f 68 ff 27 f7 dw csv,alv0 f043 00 00 00 00 hd1: dw 0,0 ; disk B (IDE drive) f047 00 00 00 00 dw 0,0 f04b a7 f6 72 f0 dw dirbuf,hd1dub f04f 68 ff 68 f7 dw csv,alv1 f053 00 00 00 00 hd2: dw 0,0 ; disk C (IDE drive) f057 00 00 00 00 dw 0,0 f05b a7 f6 81 f0 dw dirbuf,hd2dub f05f 68 ff 68 fb dw csv,alv2 ; ; disk parameter blocks ; ; RAMdisk --- 8 spt 256 trks. (no chksum area ... yet) ; f063 20 00 rddub: dw 32 ; sectors/trk f065 04 db 4 ; block shift (BSH) f066 0f db 15 ; block mask (BLM) f067 00 db 0 ; extent mask (EXM) f068 ff 01 dw 511 ; disk size (#alus-1) (DSM) f06a ff 00 dw 255 ; max dir entries (#-1) (DRM) f06c f0 db 0f0h ; dir. alloc. (AL0) f06d 00 db 0 ; dir. alloc. (AL1) f06e 00 00 dw 0 ; check size (CKS) f070 00 00 dw 0 ; track offset (OFF) ; ; IDE drive - c/h/s is 3148/16/63 (252 is one track) ; 4k allocation blocks, 1024 dir ent., ~32 MB ; 00fc cpmspt equ 252 f072 fc 00 hd1dub: dw cpmspt ; sectors/trk f074 05 db 5 ; block shift (BSH) f075 1f db 31 ; block mask (BLM) f076 01 db 1 ; extent mask (EXM) f077 f8 1f dw 8184 ; disk size (#blocks-1) (DSM) f079 ff 03 dw 3ffh ; max dir entries (#-1) (DRM) f07b ff db 0ffh ; dir. alloc. (AL0) f07c 00 db 0 ; dir. alloc. (AL1) f07d 00 00 dw 0 ; check size (CKS) f07f 01 00 dw 1 ; track offset (OFF) ; ; IDE drive (part two) ; f081 fc 00 hd2dub: dw cpmspt ; sectors/trk f083 05 db 5 ; block shift (BSH) f084 1f db 31 ; block mask (BLM) f085 01 db 1 ; extent mask (EXM) f086 f8 1f dw 8184 ; disk size (#blocks-1) (DSM) f088 ff 03 dw 3ffh ; max dir entries (#-1) (DRM) f08a ff db 0ffh ; dir. alloc. (AL0) f08b 00 db 0 ; dir. alloc. (AL1) f08c 00 00 dw 0 ; check size (CKS) f08e 50 06 dw 1616 ; track offset (OFF) ; ; Enter here after cold boot ; (cold boot after system reset) ; f090 21 11 f1 boot: ld hl,smsg f093 cd e7 f0 call prmsg ; print sign-on message f096 af xor a f097 32 03 00 ld (iob),a ; set I/O byte f09a 32 04 00 ld (4),a ; set disk to A: f09d c3 bf f0 jp gocpm ; ; Enter here for warm boot ; f0a0 db 04 wboot: in a,(romt) ; toggle over to ROM f0a2 21 00 0c ld hl,0c00h ; start of ROM image f0a5 11 00 da ld de,ccp ; CP/M base (CCP) f0a8 01 00 16 ld bc,cpml ; move only CCP + BDOS f0ab ed b0 ldir f0ad 11 00 d0 ld de,0d000h f0b0 13 wbt1: inc de ; stall f0b1 7a ld a,d f0b2 b3 or e f0b3 20 fb jr nz,wbt1 f0b5 db 04 in a,(romt) f0b7 11 00 d0 ld de,0d000h f0ba 13 wbt2: inc de ; stall f0bb 7a ld a,d f0bc b3 or e f0bd 20 fb jr nz,wbt2 ; f0bf 3e c3 gocpm: ld a,0c3h ; set up CP/M base page links f0c1 32 00 00 ld (0),a f0c4 21 03 f0 ld hl,wboote f0c7 22 01 00 ld (1),hl ; warm boot link f0ca 32 05 00 ld (5),a f0cd 21 06 e2 ld hl,bdos f0d0 22 06 00 ld (6),hl ; BDOS link f0d3 01 80 00 ld bc,80h f0d6 cd 76 f1 call sdma ; default buffer address f0d9 af xor a f0da 32 9a f4 ld (hstact),a ; set host buffer inactive f0dd 32 9c f4 ld (unacnt),a ; clear unalloc count f0e0 3a 04 00 ld a,(4) ; get current drive number f0e3 4f ld c,a f0e4 c3 00 da jp ccp ; start up CCP ; f0e7 7e prmsg: ld a,(hl) ; print str. @ (HL) f0e8 fe 03 cp 3 f0ea c8 ret z f0eb 4f ld c,a f0ec cd 41 f1 call conout f0ef 23 inc hl f0f0 18 f5 jr prmsg ; ; print content of (A) in hex ; f0f2 f5 phex: push af f0f3 0f rrca f0f4 0f rrca f0f5 0f rrca f0f6 0f rrca f0f7 cd ff f0 call pnib f0fa f1 pop af f0fb cd ff f0 call pnib f0fe c9 ret ; ; print nibble ; f0ff e6 0f pnib: and 0fh f101 fe 0a cp 10 f103 30 05 jr nc,pn0 f105 c6 30 add a,'0' f107 c3 0c f1 jp pn1 f10a c6 37 pn0: add a,'A'-10 f10c 4f pn1: ld c,a f10d cd 41 f1 call conout f110 c9 ret ; ; Sign-on Message ; f111 0d 0a smsg: db 0dh,0ah f113 52 6f 67 65 db 'Roger',27h,'s 55K CP/M Vers 2.2' f117 72 27 73 20 f11b 35 35 4b 20 f11f 43 50 2f 4d f123 20 56 65 72 f127 73 20 32 2e f12b 32 f12c 0d 0a 03 db 0dh,0ah,3 ; ; non-disk I/O drivers ; 0000 adat equ 0 ; serial data port A 0001 bdat equ adat+1 ; serial data port B 0002 acon equ adat+2 ; console status port A 0003 bcon equ adat+3 ; port B status reg. ; f12f db 02 const: in a,(acon) f131 e6 01 and 1 f133 c8 ret z f134 3e ff ld a,0ffh f136 c9 ret ; f137 cd 2f f1 conin: call const f13a 28 fb jr z,conin f13c db 00 in a,(adat) f13e e6 7f and 7fh f140 c9 ret ; f141 db 02 conout: in a,(acon) f143 cb 57 bit 2,a f145 28 fa jr z,conout f147 79 ld a,c f148 d3 00 out (adat),a f14a c9 ret ; f14b list: f14b db 03 punch: in a,(bcon) f14d cb 57 bit 2,a f14f 28 fa jr z,list f151 79 ld a,c f152 d3 01 out (bdat),a f154 c9 ret ; f155 cd 61 f1 rdr: call lstst f158 e6 01 and 1 f15a 28 f9 jr z,rdr f15c db 01 in a,(bdat) f15e e6 7f and 7fh f160 c9 ret ; f161 db 03 lstst: in a,(bcon) f163 e6 01 and 1 f165 c8 ret z f166 3e ff ld a,0ffh f168 c9 ret ; ; RAMdisk ACCESS ROUTINES ; ; THE FOLLOWING EQUATES DEFINE THE RAMdisk ports ; 0008 BASEP EQU 8 ; DEFAULT BASE PORT ADDRESS 0008 REG0 EQU BASEP ; DATA TRANSFER PORT 0009 REG1 EQU BASEP+1 ; LSB ADDRESS REGISTER 000a REG2 EQU BASEP+2 ; MSB ADDRESS REGISTER 000b REG3 EQU BASEP+3 ; BYTE LOCATION REGISTER ; ; IDE junk ; 0200 hstsiz equ 512 ; sector size for IDE disk 1000 blksiz equ 4096 ; CP/M allocation block size 0003 secmsk equ 3 ; sector mask ; BDOS flags for writes 0000 wrall equ 0 ; write to allocated 0001 wrdir equ 1 ; write to directory 0002 wrual equ 2 ; write to unallocated ; ; home (set trk to 0) ; f169 01 00 00 hme: ld bc,0 ; f16c ed 43 91 f4 strk: ld (sektrk),bc f170 c9 ret ; f171 79 ssec: ld a,c f172 32 93 f4 ld (seksec),a f175 c9 ret ; f176 ed 43 a5 f4 sdma: ld (dmaadr),bc f17a c9 ret ; ; read selected cp/m sector ; f17b 3a 90 f4 read: ld a,(sekdsk) ; which drive? f17e b7 or a f17f c2 94 f1 jp nz,ride ; IDE ; f182 cd 62 f4 CALL SETUP ; SET UP TRK/SEC FOR RD READ f185 78 RDLP: LD A,B ; ADDR. WITHIN 128 b. SECT. f186 d3 0b OUT (REG3),A ; SET IT f188 00 NOP f189 db 08 IN A,(REG0) ; GET DATA FROM RAMdisk f18b 77 LD (HL),A ; STORE @HL f18c 23 INC HL ; POINT TO NEXT f18d 04 INC B ; FOR ALL 128 b. f18e cb 78 BIT 7,B f190 28 f3 JR Z,RDLP ; LOOP f192 af XOR A ; 0=NO ERRORS f193 c9 RET f194 3e 01 ride: ld a,1 f196 32 a3 f4 ld (readop),a ; signal read op. f199 32 a2 f4 ld (rsflag),a ; must read data f19c 3e 02 ld a,wrual f19e 32 a4 f4 ld (wrtype),a ; treat as unalloc f1a1 c3 20 f2 jp rwoper ; combined rd/wr code ; ; write selected cp/m sector ; f1a4 3a 90 f4 write: ld a,(sekdsk) ; which drive? f1a7 b7 or a f1a8 c2 bc f1 jp nz,wride ; IDE ; f1ab cd 62 f4 CALL SETUP ; SET UP REGS. FOR RD WRITE f1ae 78 WRLP: LD A,B ; ADDR. WITHIN 128 b. SECT. f1af d3 0b OUT (REG3),A f1b1 7e LD A,(HL) ; GET DATA FROM MEMORY f1b2 d3 08 OUT (REG0),A ; STORE DATA f1b4 23 INC HL ; POINT TO NEXT f1b5 04 INC B ; FOR ALL 128 b. f1b6 cb 78 BIT 7,B f1b8 28 f4 JR Z,WRLP ; LOOP f1ba af XOR A ; 0=NO ERRORS f1bb c9 RET ; f1bc af wride: xor a f1bd 32 a3 f4 ld (readop),a ; signal write op. f1c0 79 ld a,c ; write type in C f1c1 32 a4 f4 ld (wrtype),a f1c4 fe 02 cp wrual ; unallocated write? f1c6 c2 d9 f1 jp nz,chkuna ; check for unalloc ; write to unallocated, set up parms. f1c9 3e 20 ld a,blksiz/128 ; next unalloc recs f1cb 32 9c f4 ld (unacnt),a f1ce 21 90 f4 ld hl,sekdsk ; move 'sek' stuff to 'una' f1d1 11 9d f4 ld de,unadsk f1d4 01 05 00 ld bc,5 f1d7 ed b0 ldir ; check for write to unallocated sector f1d9 3a 9c f4 chkuna: ld a,(unacnt) ; any unallocated remain? f1dc b7 or a f1dd ca 18 f2 jp z,alloc ; skip if not ; more unallocated records remain f1e0 3d dec a ; unacnt = unacnt -1 f1e1 32 9c f4 ld (unacnt),a f1e4 3a 90 f4 ld a,(sekdsk) ; same disk? f1e7 21 9d f4 ld hl,unadsk f1ea be cp (hl) ; sekdsk = unadsk? f1eb c2 18 f2 jp nz,alloc ; skip if not ; disks are the same f1ee 21 9e f4 ld hl,unatrk f1f1 cd bb f2 call sektrkcmp ; sektrk = unatrk? f1f4 c2 18 f2 jp nz,alloc ; tracks are the same f1f7 3a 93 f4 ld a,(seksec) ; same sector? f1fa 21 a0 f4 ld hl,unasec f1fd be cp (hl) ; seksec = unasec? f1fe c2 18 f2 jp nz,alloc ; skip if not ; match, move to next sector for future ref f201 34 inc (hl) ; unasec = unasec+1 f202 7e ld a,(hl) ; end of track? f203 fe fc cp cpmspt ; count cp/m sectors f205 da 11 f2 jp c,noovf ; skip if no overflow ; overflow to next track f208 36 00 ld (hl),0 ; unasec = 0 f20a 2a 9e f4 ld hl,(unatrk) f20d 23 inc hl f20e 22 9e f4 ld (unatrk),hl ; unatrk = unatrk+1 ; match found, mark as unnecessary read f211 af noovf: xor a ; clear accum. f212 32 a2 f4 ld (rsflag),a ; rsflag = 0 f215 c3 20 f2 jp rwoper ; to perform the write ; not an unallocated record, requires pre-read f218 af alloc: xor a ; clear accum. f219 32 9c f4 ld (unacnt),a ; unacnt = 0 f21c 3c inc a ; accum = 1 f21d 32 a2 f4 ld (rsflag),a ; rsglag = 1 ; ; read/write common code ; f220 af rwoper: xor a ; clear accum. f221 32 a1 f4 ld (erflag),a ; no errors (yet) f224 32 8d f4 ld (retry),a ; clear retries f227 3a 93 f4 ld a,(seksec) ; compute host sector f22a b7 or a ; carry = 0 f22b 1f rra ; shift right f22c b7 or a f22d 1f rra f22e 32 99 f4 ld (sekhst),a ; host sector to seek ; active host sector? f231 21 9a f4 ld hl,hstact ; host active flag f234 7e ld a,(hl) f235 36 01 ld (hl),1 ; always becomes 1 f237 b7 or a ; was it already? f238 ca 5f f2 jp z,filhst ; fill host if not ; host buffer active, same as seek buffer? f23b 3a 90 f4 ld a,(sekdsk) f23e 21 94 f4 ld hl,hstdsk ; same disk? f241 be cp (hl) ; sekdsk = hstdsk? f242 c2 58 f2 jp nz,nomatch ; same disk, same track? f245 21 95 f4 ld hl,hsttrk f248 cd bb f2 call sektrkcmp ; sektrk = hsttrk? f24b c2 58 f2 jp nz,nomatch ; same disk, same track, same buffer? f24e 3a 99 f4 ld a,(sekhst) f251 21 97 f4 ld hl,hstsec ; sekhst = hstsec? f254 be cp (hl) f255 ca 7c f2 jp z,match ; skip if match ; proper disk, but not correct sector f258 3a 9b f4 nomatch: ld a,(hstwrt) ; host written? f25b b7 or a f25c c4 f0 f2 call nz,writehst ; clear host buff ; may have to fill the host buffer f25f 3a 90 f4 filhst: ld a,(sekdsk) f262 32 94 f4 ld (hstdsk),a f265 2a 91 f4 ld hl,(sektrk) f268 22 95 f4 ld (hsttrk),hl f26b 3a 99 f4 ld a,(sekhst) f26e 32 97 f4 ld (hstsec),a f271 3a a2 f4 ld a,(rsflag) ; need to read? f274 b7 or a f275 c4 c7 f2 call nz,readhst ; yes, if 1 f278 af xor a ; clear accum. f279 32 9b f4 ld (hstwrt),a ; no pending write ; copy data to or from buffer f27c 3a 93 f4 match: ld a,(seksec) ; mask buffer number f27f e6 03 and secmsk ; least signif bits f281 6f ld l,a ; ready to shift f282 26 00 ld h,0 ; double count f284 29 add hl,hl f285 29 add hl,hl f286 29 add hl,hl f287 29 add hl,hl f288 29 add hl,hl f289 29 add hl,hl f28a 29 add hl,hl ; hl has relative host buffer address f28b 11 a7 f4 ld de,hstbuf f28e 19 add hl,de ; HL = host address f28f ed 5b a5 f4 ld de,(dmaadr) ; get/put CP/M data f293 01 80 00 ld bc,128 ; length of move f296 3a a3 f4 ld a,(readop) ; which way? f299 b7 or a f29a c2 a3 f2 jp nz,rwmove ; skip if read ; write operation, mark and switch direction f29d 3e 01 ld a,1 f29f 32 9b f4 ld (hstwrt),a ; hstwrt = 1 f2a2 eb ex de,hl ; source/dest swap ; bc initially 128, HL is source, DE is dest f2a3 rwmove: f2a3 ed b0 ldir ; block copy ; data has been moved to/from host buffer f2a5 3a a4 f4 ld a,(wrtype) ; write type f2a8 fe 01 cp wrdir ; to directory? f2aa 3a a1 f4 ld a,(erflag) ; in case of errors f2ad c0 ret nz ; no further processing ; clear host buffer for directory write f2ae b7 or a ; errors? f2af c0 ret nz ; skip if so f2b0 af xor a ; clear accum. f2b1 32 9b f4 ld (hstwrt),a ; buffer written f2b4 cd f0 f2 call writehst f2b7 3a a1 f4 ld a,(erflag) f2ba c9 ret ; ; 16-bit compare ; f2bb sektrkcmp: ; hl = (unatrk) or (hsttrk), compare with sektrk f2bb eb ex de,hl f2bc 21 91 f4 ld hl,sektrk f2bf 1a ld a,(de) ; low byte compare f2c0 be cp (hl) ; same? f2c1 c0 ret nz ; return if not ; low bytes equal, test high ones f2c2 13 inc de f2c3 23 inc hl f2c4 1a ld a,(de) f2c5 be cp (hl) ; sets flags f2c6 c9 ret ; Definition of IDE I/O addresses: 0030 PRIDE equ 30h ; base address of PRIDE interface 0030 IdeDat equ PRIDE ; Data Register 0031 IdeErr equ PRIDE+1 ; Error Register 0031 IdePCmp equ IdeErr 0032 IdeSCnt equ PRIDE+2 ; Sector Count 0033 IdeSNum equ PRIDE+3 ; Sector Number 0034 IdeCLo equ PRIDE+4 ; Cylinder Low 0035 IdeCHi equ PRIDE+5 ; Cylinder High 0036 IdeSDH equ PRIDE+6 ; Drive and Head 0037 IdeCmd equ PRIDE+7 ; Command / Status 0037 IdeStat equ IdeCmd 0038 IdeHbyt equ PRIDE+8 ; Data (high byte) ; Commands for IDE hard disk drives: 0020 CmdRd equ 20h ; Read Sector 0030 CmdWr equ 30h ; Write Sector ; ; Host read/write routines ; f2c7 readhst: f2c7 cd f9 f3 call tfsetup ; set up for target f2ca cd 1f f3 call wbr ; can we go on? f2cd d2 63 f3 jp nc,errh ; no, error f2d0 3e 20 ld a,CmdRd ; read command f2d2 d3 37 out (IdeCmd),a ; issue it f2d4 cd 1f f3 call wbr ; can we go on? f2d7 d2 63 f3 jp nc,errh f2da cd 54 f4 call erchk ; ensure no error f2dd d2 63 f3 jp nc,errh f2e0 cd 4d f3 call wtdrq ; wait for drq from drive f2e3 d2 63 f3 jp nc,errh f2e6 cd 33 f4 call readin ; read the target f2e9 cd 54 f4 call erchk ; ensure no error f2ec d2 63 f3 jp nc,errh f2ef c9 ret ; return ; f2f0 writehst: f2f0 cd f9 f3 call tfsetup ; set up for target f2f3 cd 1f f3 call wbr ; can we go on? f2f6 d2 63 f3 jp nc,errh ; no, error f2f9 3e 30 ld a,CmdWr ; write command f2fb d3 37 out (IdeCmd),a ; issue it f2fd cd 1f f3 call wbr ; can we go on? f300 d2 63 f3 jp nc,errh f303 cd 54 f4 call erchk ; ensure no error f306 d2 63 f3 jp nc,errh f309 cd 4d f3 call wtdrq ; wait for drq from drive f30c d2 63 f3 jp nc,errh f30f cd 44 f4 call wrtout ; write the target f312 cd 1f f3 call wbr ; ready to go on? f315 d2 63 f3 jp nc,errh f318 cd 54 f4 call erchk ; see if error occurred f31b d2 63 f3 jp nc,errh f31e c9 ret ; return ; Subroutines: wait for hard disk ready (non-busy) resp, DRQ active. f31f 3a 8f f4 wbr: ld a,(ide_status) ;choose bit 1 or bit 2 to test for prev. f322 e6 01 and 1 ; access depending on master or slave drive f324 3c inc a ; selection f325 4f ld c,a f326 11 00 00 ld de,0 f329 06 32 wbsy: ld b,50 ;times out after -5 sec. if disk(s) not f32b 3a 8f f4 ld a,(ide_status) ; spun up (first time access). -1 sec. otherwise f32e a1 and c f32f 28 02 jr z,dlp f331 06 0a ld b,10 f333 10 fe dlp: djnz dlp f335 13 inc de f336 7a ld a,d f337 b3 or e f338 28 11 jr z,to f33a db 37 in a,(IdeStat) ; read status f33c e6 c0 and 11000000b ; mask off busy and rdy bits f33e ee 40 xor 01000000b ; want bsy(7) = 0 and rdy(6) = 1 f340 20 e7 jr nz,wbsy f342 3a 8f f4 ld a,(ide_status) ; from 1st time disk is ready, timeout is reduced f345 b1 or c ; as spin-up is main reason for 5 sec. allowance f346 32 8f f4 ld (ide_status),a f349 37 scf ; carry 1 = ok f34a c9 ret f34b af to: xor a ; carry 0 = timed out f34c c9 ret f34d 11 00 00 wtdrq: ld de,0 f350 06 32 wdrq1: ld b,50 ; approx 5 sec. delay f352 10 fe blp: djnz blp f354 13 inc de f355 7a ld a,d f356 b3 or e f357 28 08 jr z,to2 f359 db 37 in a,(IdeStat) f35b cb 5f bit 3,a ;ready to go? f35d 28 f1 jr z,wdrq1 f35f 37 scf ; carry = 1 is OK f360 c9 ret f361 af to2: xor a ; carry = 0 is timeout f362 c9 ret f363 3a 8d f4 errh: ld a,(retry) ; inc. retry cnt. f366 3c inc a f367 32 8d f4 ld (retry),a f36a fe 0a cp 10 f36c ca 79 f3 jp z,prerm f36f 3a a3 f4 ld a,(readop) ; reading or writing? f372 b7 or a f373 ca c7 f2 jp z,readhst ; try read again f376 c3 f0 f2 jp writehst ; try write again ; f379 21 b3 f3 prerm: ld hl,rdstr ; move in 'read' or 'write' f37c 11 c4 f3 ld de,edmp1 f37f 01 05 00 ld bc,5 f382 3a a3 f4 ld a,(readop) f385 b7 or a f386 28 04 jr z,prerm1 f388 21 b8 f3 ld hl,wrstr f38b 03 inc bc f38c 21 be f3 prerm1: ld hl,edmp ; print error f38f cd e7 f0 call prmsg f392 21 ca f3 ld hl,edmp2 f395 cd e7 f0 call prmsg f398 db 37 in a,(IdeStat) ; show status reg. f39a cd f2 f0 call phex f39d 21 e4 f3 ld hl,erest ; show err reg. f3a0 cd e7 f0 call prmsg f3a3 db 31 in a,(IdeErr) f3a5 cd f2 f0 call phex f3a8 21 f5 f3 ld hl,cr2lf f3ab cd e7 f0 call prmsg f3ae 21 a1 f4 ld hl,erflag f3b1 34 inc (hl) f3b2 c9 ret ; error return ; f3b3 72 65 61 64 rdstr: db 'read',3 f3b7 03 f3b8 77 72 69 74 wrstr: db 'write',3 f3bc 65 03 f3be 0d 0a 49 44 edmp: db cr,lf,'IDE ' f3c2 45 20 f3c4 20 20 20 20 edmp1: db ' ',3 f3c8 20 03 f3ca 20 65 72 72 edmp2: db ' error: Status reg. = 0x',3 f3ce 6f 72 3a 20 f3d2 20 53 74 61 f3d6 74 75 73 20 f3da 72 65 67 2e f3de 20 3d 20 30 f3e2 78 03 f3e4 20 20 45 72 erest: db ' Err. reg. = 0x',3 f3e8 72 2e 20 72 f3ec 65 67 2e 20 f3f0 3d 20 30 78 f3f4 03 f3f5 0d 0a 0a 03 cr2lf: db cr,lf,lf,3 ;************************************************************************ ;Routine: tfsetup ;purpose: initialize IDE task file registers ;Entry: setup data in hstdsk, hsttrk, and hstsec ;Exit: Task file set up ;Used: AF,HL f3f9 tfsetup: f3f9 3e 01 ld a,1 ; 1 sector f3fb d3 32 out (IdeSCnt),a ; set count of 1 f3fd 2a 95 f4 ld hl,(hsttrk) ; get host track f400 7d ld a,l ; get LSB in A f401 32 32 f4 ld (tmploc),a ; put in mem. f404 7c ld a,h ; get MSB in A f405 21 32 f4 ld hl,tmploc ; point to temp. f408 ed 67 rrd ; now tmploc has LSB of cyl. f40a e6 f0 and 0f0h ; mask off MSB upper nibble f40c 0f rrca ; rotate upper nibble down f40d 0f rrca f40e 0f rrca f40f 0f rrca f410 67 ld h,a ; move cyl hi back into HL f411 3a 32 f4 ld a,(tmploc) f414 d3 34 out (IdeCLo),a ; set up low byte of cylinder f416 7c ld a,h ; get cyl. high f417 d3 35 out (IdeCHi),a ; set up high byte of cylinder f419 3a 97 f4 ld a,(hstsec) ; get sector number f41c 3c inc a ; CP/M does 0...n, IDE does 1....n+1 f41d d3 33 out (IdeSNum),a ; set up sector number f41f 3a 95 f4 ld a,(hsttrk) ; get head number f422 e6 0f and 0fh ; mask off head bits f424 f6 a0 or 0a0H ; make into SDH byte (drive 0) f426 21 94 f4 ld hl,hstdsk ; point to drive number f429 cb 56 bit 2,(hl) ; slave drive? f42b 28 02 jr z,tfnxt ; no, skip f42d f6 10 or 10h ; set slave bit f42f d3 36 tfnxt: out (IdeSDH),a ; set up drive and head f431 c9 ret ; and done ; f432 00 tmploc: db 0 ; tmp storage for cylinder low ;************************************************************************* ;Routine: readin ;purpose: read 512-byte sector from IDE drive ;Entry: read sector command issued ;Exit: buffer filled ;Uses: AF, HL, BC f433 readin: f433 06 00 ld b,0 ;set up count in B f435 21 a7 f4 ld hl,hstbuf ;get buffer in HL f438 db 30 rdslp: in a,(IdeDat) f43a 4f ld c,a ;C = low byte f43b db 38 in a,(IdeHbyt) f43d 77 ld (hl),a ;put high byte in RAM f43e 23 inc hl f43f 71 ld (hl),c ;put low byte in RAM f440 23 inc hl f441 10 f5 djnz rdslp ;do 256 times f443 c9 ret ;************************************************************************* ;Routine: wrtout ;purpose: write 512-byte sector to IDE drive ;Entry: write sector command issued ;Exit: buffer emptied ;Uses: AF, HL, B f444 wrtout: f444 06 00 ld b,0 ;set up count in B f446 21 a7 f4 ld hl,hstbuf ;get buffer in HL f449 7e wtslp: ld a,(hl) ; get first byte f44a d3 38 out (IdeHbyt),a ; latch it in upper 8 bits f44c 23 inc hl f44d 7e ld a,(hl) ; get second byte f44e d3 30 out (IdeDat),a ; send all 16 bits to drive f450 23 inc hl f451 10 f6 djnz wtslp ;do 256 times f453 c9 ret ;************************************************************************** ;Routine: erchk ;Purpose: check for error from IDE drive ;Entry: None ;Exit: Error exit back to CP/M if any error found. ;Used: AF f454 erchk: f454 37 scf ; carry set = OK f455 db 37 in a,(IdeStat) ; get status f457 cb 47 bit 0,a ; test error bit f459 c8 ret z ; return if no error f45a cb 6f bit 5,a ; test write error bit f45c 20 02 jr nz,waser ; error bits f45e db 31 in a,(IdeErr) ; read error report register f460 b7 waser: or a ; make carry flag zero = error! f461 c9 ret ; if a = 0, ide busy timed out ; ; PREP. UP FOR RAMdisk I/O ; f462 3a 91 f4 SETUP: LD A,(sektrk) ; GET CURRENT TRACK f465 d3 09 OUT (REG1),A ; SET LSB ADDRESS REGISTER f467 3a 93 f4 LD A,(seksec) ; GET CURRENT SECTOR f46a e6 1f AND 1FH ; TURN OFF WRITE PROTECT f46c d3 0a OUT (REG2),A ; SET MSB ADDRESS REGISTER f46e 2a a5 f4 LD HL,(dmaadr) ; HL POINTS TO DMA ADDR. f471 06 00 LD B,0 ; B IS 128 b. WITHIN SECTR. f473 c9 RET ; ; f474 60 sectran: ld h,b ; don't f475 69 ld l,c ; translate f476 c9 ret ; f477 21 00 00 seld: ld hl,0 ; error indicator f47a 79 ld a,c ; ck. drive OK f47b 32 90 f4 ld (sekdsk),a ; save seek disk f47e fe 03 cp ndisks ; can only be A: B: or C: f480 d0 ret nc ; error return f481 69 ld l,c ; set hl to disk number f482 26 00 ld h,0 f484 29 add hl,hl f485 29 add hl,hl f486 29 add hl,hl f487 29 add hl,hl ; hl = disk# x 16 f488 11 33 f0 ld de,dpbase ; first DPH f48b 19 add hl,de ; hl points to disk DPH f48c c9 ret ; 0003 ndisks equ 3 ; RAMdisk + 2 IDE partitions f48d 00 retry: db 0 ; retry counter f48e 00 tempb: db 0 ; temporary r/w byte f48f ide_status: f48f 00 db 0 ; bit 0 = master (0) or slave (1) ; bit 1 - 0 means master not previously accessed ; bit 2 - 0 means slave not previously accessed ; ; read/write storage ; f490 sekdsk: ds 1 f491 sektrk: ds 2 f493 seksec: ds 1 ; f494 hstdsk: ds 1 f495 hsttrk: ds 2 f497 hstsec: ds 2 ; f499 sekhst: ds 1 f49a hstact: ds 1 f49b hstwrt: ds 1 ; f49c unacnt: ds 1 f49d unadsk: ds 1 f49e unatrk: ds 2 f4a0 unasec: ds 1 ; f4a1 erflag: ds 1 f4a2 rsflag: ds 1 f4a3 readop: ds 1 f4a4 wrtype: ds 1 f4a5 dmaadr: ds 2 f4a7 hstbuf: ds hstsiz ; f6a7 dirbuf: ds 128 ; directory scratch buffer f727 alv0: ds 65 ; disk allocation vectors f768 alv1: ds 1024 fb68 alv2: ds 1024 ff68 csv: ds 0 ; check vector scratch pad ff68 end 0008 BASEP 0020 CmdRd 0030 CmdWr 0035 IdeCHi 0034 IdeCLo 0037 IdeCmd 0030 IdeDat 0031 IdeErr 0038 IdeHbyt 0031 IdePCmp 0032 IdeSCnt 0036 IdeSDH 0033 IdeSNum 0037 IdeStat 0030 PRIDE f185 RDLP 0008 REG0 0009 REG1 000a REG2 000b REG3 f462 SETUP f1ae WRLP 0002 acon 0000 adat f218 alloc f727 alv0 f768 alv1 fb68 alv2 0003 bcon 0001 bdat e206 bdos a600 bias 1000 blksiz f352 blp f090 boot f000 cbios da00 ccp f1d9 chkuna f137 conin f141 conout f12f const 1600 cpml 00fc cpmspt 000d cr f3f5 cr2lf ff68 csv f6a7 dirbuf f333 dlp f4a5 dmaadr f033 dpbase f3be edmp f3c4 edmp1 f3ca edmp2 f454 erchk f3e4 erest f4a1 erflag f363 errh f25f filhst f0bf gocpm f043 hd1 f072 hd1dub f053 hd2 f081 hd2dub f169 hme f018 home f49a hstact f4a7 hstbuf f494 hstdsk f497 hstsec 0200 hstsiz f495 hsttrk f49b hstwrt f48f ide_status 0003 iob 000a lf f14b list f161 lstst f27c match 0040 msize 0080 nbytes 0003 ndisks f258 nomatch f211 noovf f000 orgadr f0f2 phex f10a pn0 f10c pn1 f0ff pnib f379 prerm f38c prerm1 f0e7 prmsg f14b punch f063 rddub f027 rde f155 rdr f438 rdslp f3b3 rdstr f17b read f2c7 readhst f433 readin f4a3 readop f48d retry f194 ride 0004 romt f4a2 rsflag f2a3 rwmove f220 rwoper f176 sdma 0003 secmsk f474 sectran f490 sekdsk f499 sekhst f493 seksec f491 sektrk f2bb sektrkcmp f477 seld f01b seldsk f024 setdma f021 setsec f01e settrk f111 smsg f171 ssec f16c strk f48e tempb f42f tfnxt f3f9 tfsetup f432 tmploc f34b to f361 to2 f49c unacnt f49d unadsk f4a0 unasec f49e unatrk f460 waser f0a0 wboot f003 wboote f31f wbr f329 wbsy f0b0 wbt1 f0ba wbt2 f350 wdrq1 0000 wrall 0001 wrdir f02a wre f1bc wride f1a4 write f2f0 writehst f3b8 wrstr f444 wrtout f4a4 wrtype 0002 wrual f34d wtdrq f449 wtslp