IDE HARD DISK PROGRAMMING REFERENCE
How to adapt Zxiderom for work with my hard disk?
Port addresses with given scheme and GAL:
Data register : #69
Parameter reg.: #79
Sector count r.: #6B
Start sector r.: #7B
Cylinder low : #6D
Cylinder high : #7D
Head reg. : #6F
Command/status: #7F
Example routines for read & write:
;I/O port addresses
DAT EQU #69
PAR EQU #79
SEC EQU #6B
STA EQU #7B
ZYL EQU #6D
ZYH EQU #7D
HEA EQU #6F
COM EQU #7F
;Enter parameters for Read & Write: HL address, BC start sector,
;A sector count, DE cylinder offset
;Out parameters: If zero flag set - OK , else error
REABE CALL REABL ;block read with error test. Entry point.
ERRT ;error testing
EI
RET Z ;return to caller if no error
IN A,(PAR)
BIT 6,A
JR NZ,ECCE
RST 8
DEFB #1E
;Disk error - new error message code, this is an example & requires
changes in ROM.
ECCE RST 8
DEFB #1F ;ECC error...
REABL CALL CALC
LD A,#20 ;read command
OUT (COM),A
CWR CALL WAIDR
SELL INI
INI
INI
INI
INI
INI
INI
INI ;8 bytes in 1 pass
DJNZ SELL
IN A,(COM)
BIT 0,A ;is error ?
RET NZ
DEC E ;decrease sector counter
JR NZ,CWR
RET ;with zero flag set - no error
WRIBE CALL WRIBL ;Block write with error test. Entry point.
JR ERRT
;Write is in reversed MSB/LSB order due to interface!
WRIBL CALL CALC
LD A,#30 ;write command
OUT (COM),A
WRIT CALL WAIDR
SWRL INC HL
OUTD
OUTI
INC HL
INC HL
OUTD
OUTI
INC HL
INC HL
OUTD
OUTI
INC HL
INC HL
OUTD
OUTI
INC HL
DJNZ SWRL
IN A,(COM)
BIT 0,A
RET NZ
DEC E
JR NZ,WRIT
RET
WAIDR LD BC,50000 ;time out counter prepare
WAIDL IN A,(COM)
BIT 3,A ; ready ?
JR NZ,SET64
DEC BC
LD A,B
OR C
JR NZ,WAIDL
POP DE ;drop call.
INC A ; reset zero flag
RET ;time out
SET64 LD BC,#4069 ;set port address (C) & loop counter : 8x#40=512
RET
;Below there will be some drive depending values
HEADS EQU 7 ;this is an example - depends from used drive
SECTOR EQU 17 ;also an example - sectors per track by used drive
CALC OR A ;avoids zero sector count - it transfers 128 sectors!
JR NZ,CONTIN
RST 8
DEFB #19 ; parameter error
CONTIN DI
PUSH HL
PUSH DE
LD E,A
LD H,B
LD L,C
LD D,-1 ; preset counter
LD BC,-HEADS*SECTOR ; here comes the complement of HEAD
and SECTOR product of the used drive
CYLCL INC D
ADD HL,BC
JR C,CYLCL
SBC HL,BC
;D now holds additional cyl. offset
LD H,-1
LD A,L
HEDCL INC H
SUB SECTOR ; here comes sector(per track) param. of used drive
JR NC,HEDCL
ADD A,SECTOR+1 ;here comes sector(per track) plus 1...
LD L,A
LD A,H
OR #A0
LD H,A
ISEX IN A,(COM)
BIT 7,A
JR NZ,ISEX
LD A,E
OUT (SEC),A
LD A,L
OUT (STA),A
LD A,H
OUT (HEA),A
POP HL
LD C,D
LD B,0
ADD HL,BC
LD A,L
OUT (ZYL),A
LD A,H
OUT (ZYH),A
POP HL
RET
;END
With this routines transfer speed is about 100 KB per second by read and
something less by write.
How to adapt Zxiderom for work with my hard disk?
Need to change only 3 locations:
1. Adress(hex): 04D0 - Here enter 16-bit complement of HEADxSECTOR in LSB/MSB order (Intel). Formula is:
65536-(Head x SectorPerTrack).
Example: disk has 15 heads and 7 sectors/track
Then it is 65536-15x7 = 65431 = FF97hex, so enter 97, FF .
2. Adr: 04DD - Here SectorPerTrack , 7 in above example.
3. Adr: 04E1 - Here SectorPerTrack + 1 , 8 in above example.
PP