After repairing the computer, I started testing the HDD driver, which
I dashed off under is-dos. Connected a clean HDD with SLAV and installed
driver in is-dos. I haven’t created any partitions on the disk yet, but
In the driver I registered the beginning of the partitions on the zero sector of the HDD SLAVE.
I ran CREATE and created an IS disk with a size of 24576 blocks. For tes─
After testing the work, I decided to copy the system disk one-to-one.
He started the copier and leaned back in his chair. However, what already
After a few seconds the copier fell out with an error, which meant─
It appears that the directory was not found. In the root directory of the disk there was already
two directories with subdirectories. I couldn’t get into some of them─
tee. It is difficult to look for such an error when “here I write correctly, but here
how will it turn out."
You need to think about how to find an error without using shadow debugging -
Still, the DOS ports are open and the shadow guy is clearly sick of it.
For now I decided to just test the reading speed in LBA mode.
I launched the BAD.com program, which reads one sector at a time, and
It is in this mode that the superiority should be especially noticeable
LBA from CHS, because with LBA it is not necessary for every requested
sector, calculate its offset from the beginning of the section and expand
offset to absolute CHS coordinates. Those. a lot of division/multiplication─
They are simply excluded from the program.
I measured the time spent by the CHS driver and the LBA driver on the computer─
a certain amount of information. Here's what I haveit turned out:
LBA 234.03 kb/sec
CHS 227.56 kb/s
I couldn’t believe my eyes and the calculator. Such a meager increase?!
The next day I started looking for driver failures. For
First you need to determine in which sector the failure is occurring. For
So I created a text file with the following content:
SECTOR01......................
...............................
...............................
(total 8 lines of 31 characters + at the end of each line #0D. Total
256 bytes)
SECTOR02.........
...........................
(same thing)
That is file length 64 sectors. I wrote this file to an empty partition
new RHDDSMUC driver and then visually checked where something was
violated. The failure was in a new location each time, depending on
partition size. So with a size of 3200 blocks and the length of the root
directory block 4, the failure was as follows: after sector 51 there was a sector
64, then garbage, then 55,56,57,58,59,60,61,62,63, then garbage.
By sectors here I'm talking about lines in a text file.
Physically, the failure occurred on the 58th block from the beginning of the section,
(29th physical sector of HDD). The section itself started from zero
HDD sector LBA.
Two ideas emerged:
1. when remaking the original driver, I overlooked something and
made a mistake;
2. I had two versions of the original driver. They were different
quite significant. One had the line Complete 100%, and
another, later edition did not contain such a line. But in this
versionsThere were comments and it seemed more logical to me. By─
That's why I took it upon myself to remake it. Perhaps she initially
was not completed or tested.
I decided to start with the second idea. I took the previous version and updated it─
I installed it under LBA mode. Installed it and started testing. Result
turned out to be the same.
This means I probably made a mistake when modifying the driver. To make sure
in the functionality of the original version of the driver, I just took it and compiled it─
sawed the original, installed and tested. The errors remain.
It turns out that there were errors in the original version and it is not clear
how it worked for Oleg Grigoriev, the author of the driver.
The only difference from the original is the full port addressing
#1ffd. In the original version, access to the port went through the command─
special addressing. This trick doesn't work on GMX either.
while the driver was running, the color of the border changed, so I did
full address.
I gathered all my thoughts into a heap and wrote a letter to Grigoriev. Bye
there was no answer.
Here is the driver source. Maybe someone can defeat him:
;RHDDLBA.BLK
;HDD DRIVER FOR SMUC WITH OPEN PORTS
;LBA-28 MODE ONLY
;MASTER/SLAVE HDD SUPPORT
;BASED ON RHDDSMUC BY RUINER AKA #0R
;(C) AMOSOV NIKOLAY AKA AMONIK
;VERSION 0.0
;COMPLETE 100%
;CREATING DATE: 24-09-2006
;LAST EDIT: 09/26/2006
;**********************************************************************
ORG #8000
DEFW INST; mailing addressinstallations
DEFW READ; reading address
DEFW WRIT; post address address
DEFW INIT; initialization address
DEFB #E0; status register
DEFB #04; status register
DEFW#0000; Do not install IM2 at the output
DEFW#0101; TRDOS type and number of read attempts
DEFW #ADDE; Driver Label
;----------------------------------------------------------------
;Disk partition information format:
;In the first word the low part of the sector address is LBA bits 0...15
;In the second word, the high part of the LBA sector address bits 16...27
;bits 29...31 always =1, and bit 28 selects 0=MASTER/1=SLAVE
;Exxx=MASTER/Fxxx=SLAVE
CDEV DEFW #0000; LBA bits 0..15
DEFW #F000; Drive/bits 16..27
;Coordinates of the beginning of the partition for 8 disks
DEVS DEFW #0000; LBA 0..15
DEFW #F000; drive/bits 16..27
DEFW #0000
DEFW #F000
DEFW #0000
DEFW #F000
DEFW #0000
DEFW #F000
DEFW #0000
DEFW #F000
DEFW #0000
DEFW #F000
DEFW #0000
DEFW #F000
DEFW #0000
DEFW #F000
INT DEFB #00; Interrupt status
;----------------------------------------------------------------
;Driver installation and initialization routine
INST
INIT CP #08; No more than 8 discs
RET NC
;Copy the coordinatesselected section to coordinate area
;current disk
ADD A,A
ADD A,A
LD C,A
LD B,0
LD HL,DEVS
ADD HL,BC
LD DE,CDEV
LD C,4; only 4 bytes
LDIR
RET
;----------------------------------------------------------------
;Detecting interrupt status
;Litters on the stack and spoils HL,BC
SETDI LD HL,SETEI; Exit through it
EX (SP),HL
LD (ERROR+#01),SP
PUSH HL
LD HL,SETDIO; Implicit call
PUSH HL
LD IX,INT
XOR A
LD(IX),A
LD A,R; INT check
RET PE
LD A,R
RET PE
INC(IX)
RET
;Opening DOS ports
SETDIO DI
LD A,#04; for IS-DOS CLASSIC
; LD A,#14; for IS-DOS CHIC
LD BC,#1FFD
OUT(C),A
; LD BC,#FFBE; Status register
; IN A,(C); We are waiting for the device to be released,
; RLCA; those. reset BUSY
; JR C,$-#03
;Enable reading prediction mode
; LD A,(CDEV+#03)
; DEC B; Accumulator register
; OUT(C),A; Selected disk
; LD DE,#AAEF
; LD B,#F9; Additional Features Register
; OUT(C),D; Command Options
; LD B,#FF; Command register
; OUT(C),E; Issued a command
;Waiting for releasedevices
WBSY LD BC,#FFBE; Status register
IN A,(C); We are waiting for the device to be released,
RLCA; those. reset BUSY
JR C,$-#03; Still busy
RET
SETEI PUSH AF
XOR A; for IS-DOS CLASSIC
; LD A,#10; for IS-DOS CHIC
LD BC,#1FFD
OUT(C),A; Closing DOS ports
POP AF; Restoring interrupt mode
BIT 0,(IX)
RET NZ
EI
RET
;----------------------------------------------------------------
;Subroutine for reading sector(s)
READ LD C,#7C; Reading
DEFB #3A; command LD A,(NN)
WRIT LD C,#7D; Record
PUSH BC
LD C,#09; Pressure test
RST#10; any key
POP B.C.
JR Z,RW00; Not pressed
CP#16; is this BREAK?
JR NZ,RW00; No
LD C,#07; Cleaning the key buffer
RST #10
LD A,#14; We leave with a message
SCF; BREAK
RET
;At the entrance:
;B number of blocks
;DE first block number
;HL memory address
RW00 PUSH DE; Remember the number
EXX; block and others
POP DE
CALL SETDI; Enabled ports
SRL D; divide the block number
RR E; by two
EX AF,AF'; retained flag C
;Calculate the offset from the beginning of the section using the block numberLD HL,(CDEV);low part of the LBA sector address 0..15
ADD HL,DE; added with block number
EX DE,HL; remembered in DE
LD HL,(CDEV+#02);high part of the sector address
JR NC,$+#03; If there was no overflow of the low part
INC HL; Added to the senior part of the sector address
CALL PCOORDL; Writing to HDD registers
EXX;
EX AF,AF';
;Returned:
;HL memory address
;DE block number
;B number of blocks
;C operation type
;CF offset in the first sector
LD D,B
JR NC,$+#03; If from the middle, then reduce the amount
DEC D; blocks
RLA; We remember the offset.
SRL D; Number of sectors.
RLA; We remember the remainder and
LD E,A; make a copy in E.
BIT 1,E; If from the middle, then
JR Z,$+#03; increasing the quantity
INC D; sectors.
SCF; Implicitly modifying register C
RR C; and get the port address in it
JR C, HDDW; in CF type of operation.
;----------------------------------------------------------------
HDDR EX AF,AF'
LD A,#20; READ SECTORS Team
EX AF,AF'
AND #01; Add a tail.
ADD A,D
CALL WKSEC0; Issuing a command
BIT 1,E; Do you have a head?
JR Z,HDDR01; no
CALL SKIP;Skipping the first half of the sector
LD A,#10; Reading your head
HDDR00 CALL RDHALF+#02;Buffer pump
DEC D
HDDR01 INC D; Are there entire sectors?
DEC D
JR Z,HDDR02; No.
CALL WAIT; We are waiting for readiness
LD A,#20; Reading the whole sector
JR HDDR00
HDDR02 BIT 0,E; Got a tail?
RET Z; No
CALL WAIT; We are waiting for readiness
CALL RDHALF; Reading the tail
;----------------------------------------------------------------
;Skip half a sector at 6.875 clocks per byte
SKIP LD A,#10; Number of repetitions
LD B,#F8; High byte data port address
SKIP0 DEFB #ED,#70; command IN F,(C)
DEFB #ED,#70
DEFB #ED,#70
DEFB #ED,#70
DEFB #ED,#70
DEFB #ED,#70
DEFB #ED,#70
DEFB #ED,#70
DEC A
JR NZ,SKIP0; One more time?
OR A
RET
;----------------------------------------------------------------
HDDW INC D; There is no head, no
DEC D; bodies?
JR Z,HDDW21; Yes.
BIT 1,E; Do you have a head?
JR Z,HDDWFF; No
CALL WKSECR; Read sector
CALL RDHLFH; Reading 1st half into internal buffer
CALL SKIP; Skip 2nd half
HDDWFF LD A,#30; Write a sector
EX AF,AF'
LD A,D;Number of whole sectors
CALL WKSEC0; They gave the command
BIT 1,E; Do you have a head?
JR Z,HDDW00; No.
PUSH HL
CALL WRHLFH; Writing from the buffer
POP HL
LD A,#10; Writing the head
LOOP CALL WRHALF+#02
CALL WBSY; We are waiting for completion
DEC D; Reduced the number of entire sectors
HDDW00 INC D; Do you have a body?
DEC D
JR Z,LOOP1; No.
HDDW10 CALL WBSY; We are waiting for readiness
CALL WDRQ; Waiting for DRQ
LD A,#20; We are writing a whole sector
JR LOOP
LOOP1 BIT 0,E; Got a tail?
RET Z; No.
LD A,#20
EX AF,AF'
LD A,#02
CALL WKSEC0
LD A,#20
CALL SKIP+#02
CALL WAIT
JR HDDW22
HDDW21 CALL WKSECR; Read sector
HDDW22 CALL SKIP; Skip half
CALL RDHLFH; Read to buffer
LD A,#30; Write a sector
CALL WKSEC
CALL WRHALF; We write the tail.
CALL WRHLFH; We write from the buffer.
CALL WBSY; We are waiting for completion.
XOR A
RET
;----------------------------------------------------------------
;Write LBA sector address to HDD registers
;H= drive+LBA 27...24
;L= LBA 23...16
;D= LBA 8...15
;E= LBA 0...7
PCOORD LD BC,#FEBE
OUT (C),H
DEC B
OUT(C),L
DEC B
OUT(C),D
DECB
OUT(C),E
RET
;----------------------------------------------------------------
RDHLFH PUSH HL; Reading half the sector
LD HL,TMPBUF;to internal buffer
CALL RDHALF
POP HL
RET
WKSECR LD A,#20; Single sector read entry point
WKSEC EX AF,AF'; Entry point for working with
LD A,#01; one sector.
WKSEC0 LD B,#FA; Entry point for working with
OUT(C),A; several sectors
LD B,#FF; Reading the register
IN A,(C); state
BIT 6,A; We are waiting for the installation of DRDY.
JR Z,$-#04
EX AF,AF'; Write the command code.
OUT(C),A
WAIT CALL WBSY; We are waiting for readiness.
RRCA; Error checking
RET NC; Exit if ERR=0
LD A,#07; Read/Write Error
ERROR LD SP,#0000; sectors
RET
WDRQ IN A,(C); We are waiting for the DRQ installation.
BIT 3,A
JR Z,$-#04
RET
;----------------------------------------------------------------
;Recording routine at 21.875 clock cycles per byte
WRHLFH LD HL,TMPBUF;buffer address
WRHALF LD A,#10; Number of repetitions
PUSH DE
LD DE,#D8F8
LD (WRHLF1+#01),SP
LDSP,HL
WRHLF0 DEFB #E1,#42,#ED,#61,#43,#ED,#69; POP HL
DEFB #E1,#42,#ED,#61,#43,#ED,#69; LD B,D
DEFB #E1,#42,#ED,#61,#43,#ED,#69; OUT(C),H
DEFB #E1,#42,#ED,#61,#43,#ED,#69; LD B,E
DEFB #E1,#42,#ED,#61,#43,#ED,#69; OUT (C),L
DEFB #E1,#42,#ED,#61,#43,#ED,#69
DEFB #E1,#42,#ED,#61,#43,#ED,#69
DEFB #E1,#42,#ED,#61,#43,#ED,#69
DEC A
JR NZ,WRHLF0
LD H,A
LD L,A
ADD HL,SP
WRHLF1 LD SP,#0000
POP OF
OR A
RET
;------------------------------------------------------
;A read subroutine with a speed of 20,875 clocks per byte
RDHALF LD A,#10
PUSH TO
LD DE,#D8F8
RDHLF0 DEFB #43,#ED,#A2,#42,#ED,#A2; LD B,E:IN:LD B,D:IN
DEFB #43,#ED,#A2,#42,#ED,#A2
DEFB #43,#ED,#A2,#42,#ED,#A2
DEFB #43,#ED,#A2,#42,#ED,#A2
DEFB #43,#ED,#A2,#42,#ED,#A2
DEFB #43,#ED,#A2,#42,#ED,#A2
DEFB #43,#ED,#A2,#42,#ED,#A2
DEFB #43,#ED,#A2,#42,#ED,#A2
DEC A
JR NZ,RDHLF0
POP OF
OR A
RET
;------------------------------------------------------
;Internal buffer on floor of sector
TMPBUF DEFS #0100
Share your thoughts about the article