The Reader - Reader
(C) Ivan Roshchin, Moscow, 1996
TR-DOS:
how to avoid mistakes?
You'd be surprised if you find out
how many programs do not recognize
errors when working with a disk, incorrectly recognize them, as
well as hang or reset when they
occur. Of course, when
writing your own programs
should be avoided,
although it is not so easy. Case
is that correct processing
errors becomes possible only
when working directly with a microcontroller disk interface
and it is available is not for everyone. Despite this, the
reliability programs can be greatly enhanced if used along with
the usual functions of TR-DOS special procedures for the
recognition of error situations.
In this article we will go on
One of the most common
I / O errors - there is no
disk in the drive. There will also be
say a few words about the direct
VG93 programming and the programs that control the shift
disc.
It is known that before
any disk operations associated with reading or writing data to
the disc was installed in the drive and the door
the drive was closed. If this
condition is not met, the program (if it is intelligently
written) normally produces one of the following
Message:
- No disk
- Disk not present
- Disk not ready
Special procedure for determining whether the disc in the
drive would be very useful. To give just one possible
examples of its use: if
your program uses an interpreter system functions
TR-DOS and has no error trapping, when they occur (in
particular, in the absence of a disk) can occur Reset your
computer (which is very undesirable). But if using this
procedure to detect no disk before calling
interpreter can be avoided
unpleasant consequences (of course,
Unless there is some
other errors).
We consider several possible ways to implement such a
Procedure:
1) Trying to read any sector (of course,
not with a call to the interpreter system functions, while
direct programming of the controller). As a matter of
information is not required, reading You can spend, say, a
region of ROM. In case of failure, consider that there is no
disk.
Disadvantages: read the sector does not mean that
Disk absent. It may well
be that the sector was recorded with
mistake or sector with the number generally is not on track
(As in the general case, the disc format can be arbitrary).
Advantages: when working with
drive fixed-format
This method is well suited.
2) Making an attempt to read
first met the title
sector. In case of failure, consider that there is no disk.
Disadvantages: In the general case
disk may be unformatted, with nothing to read does not succeed,
and we get incorrect result.
Advantages: This method is suitable for any formatted disk
and is relatively simple in implementation.
3) Use the status register of the microcontroller.
Before we talk about the pros and cons of this
method, recall that such a status register, and what we can
learn from it.
Status register reflects
correctness of a given command, and
and state the microcontroller when it is executed. Each bit
it indicates a certain
parameter and linked with the performance
specific command. When you use the recovery and positioning the
bits of the system Register following functions:
0 - busy being implemented
team;
1 - an index pulse;
2 - magnetic head is
in the original position;
3 - error in the control code;
4 - positioning error;
5 - magnetic head is
in the operating position;
6 - Protection of records;
7 - indicates a willingness to dis
kovoda to carry out commands.
We are interested in only 1
and 6 bits of status register,
why talk about them.
If you look at a floppy disk,
we will see a large hole in
center, and next to it - a small round hole in the housing disk
and the hole just smaller diameter on the magnetic disk. This
is called the index hole, which serves to orient the magnetic
head on a floppy disk drive. When the openings in the cabinet
and on the disc are the same (as this occurs at each revolution
of the disk), the controller finds that the magnetic head is
beginning of the track. I note that
the probability of accidental coincidence of holes is about 3%.
The value of 1 bit in the register
states determined by the state of the index holes:
situation the value of the 1 st bit
Disk no 1
The disc is,
holes in the body 1
and on the CD
match
The disc is,
holes in the hull 0
and on the CD
do not match
Sixth bit register reflects the state of the system slot
to protect the record:
situation the value of 6-th bit
Disk no 0
The disc is,
slit open 0
The disc is,
the slot is closed a
It is clear that if the 1-th bit is
0 or 6-th bit is 1, the disk is present. But, first, with
a disc, these bits can
take, in general, any
values, and secondly, it is unknown whether the door is closed
the drive. How do we know it state? Recall that if
it is closed and the motor drive rotates, it will rotate and
drive. If the door open, the drive will fail to rotate. But how
to determine a rotating disk or not, we have know - you need to
cyclically check the value of the first bit in the register
states. For each reverse drive, this bit changes
its value to 0 (the hole in the
building does not conform with the hole on the disk) to 1
(opening match), and then - again to 0. If this bit will not
change its value - or There is no disk drive, or door
open.
Now we can easily specify the desired algorithm:
- Read value of register
states. Let s1 - value
1-th bit, s2 - to 6-th
bits.
- Let s3 = 1, if the disk rotates, and 0 if the drive does
not spin.
- Define the situation on the table:
s1 s2 s3 room situation
0 0 0 2
0 0 1 3
0 1 0 2
0 1 1 3
1 0 0 1
1 0 1 3
1 1 0 2
1 1 1 3
Explanation facilities of the situation:
1 - There is no disk in the drive;
2 - disk is, but the door of the disco
water is not closed;
3 - Disk drive there and the door
closed.
Note: with probability
approximately 3% of the situation (2) can
be recognized as a situation
(1).
Well, with only
bring the text of the procedure in assembler:
140.
;***********************************************
; PROCEDURE DEFINES D_READY by inserting LEE
; ROM drive and IS CLOSED DOOR DRIVE.
, The Register A RETURNS NUMBER 1,2 or 3,
, Denotes the number SITUATION:
;
, 1-in drive is not drive;
2-disk is, but the drive door is not
, Closed;
3-disk drive and the door is closed.
;
Note: with a probability of about 3% of the situation (2)
, Can be recognized as a situation (1).
D_READY XOR A; ESTABLISHES THE SAME
LD C, # 3F; cylinder number
CALL TO_WG93; IN CASE TRACK
LD C, # 7F; AND IN CASE OF DATA.
CALL TO_WG93
LD A, # 18; POSITIONING. HEAD WILL NOT
CALL TO_1F; move, but engine on.
CALL READY; WAITING FOR THE IMPLEMENTATION OF ...
CALL STATUS; READ STATUS REGISTER.
LD B, A; and stored in REGISTER B.
; Now read status register in the cycle,
, To determine whether the disk ROTATES.
, # 300 IF TIME WILL CONSIDER THE SAME
And the values, the disc does not spin.
;
; NOTE: NUMBER # 300 Find the empirically
; From the maximum-TIME WORK CYCLE
, (It is little more than one revolution DRIVE TIME,
; ILI3 200ms). If the processor run faster or
; Disc rotates SLOWER, THE NUMBER TO INCREASE.
LD HL, # 300; COUNTER
LOOP_D PUSH HL
PUSH BC
CALL STATUS
POP BC
POP HL
DEC HL
CP B; Compares THINK earlier obtained values
LD A, 1; SHAPING 0-bit registers A
JR NZ, DISK_R; If the disc SPIN
LD A, H
OR L
JR NZ, LOOP_D; continue to read meaning ...
, Forming in the Register A byte with the following content:
;
; Bit 0: 0-DRIVE not cool, 1-SPIN;
; BIT 1: Same as what was in the 6-M Bite status register
; BIT 2: Same as what was in the 1-M Bite status register
;
; In the result in register A receives number from 0 to 7,
, Continue to define the SITUATION ROOM ON THE TABLE.
DISK_R BIT 6, B
JR Z, READY1
SET 1, A
, Is set to 1-th bit.
READY1 BIT 1, B
JR Z, READY2
SET 2, A
; In A to obtain the necessary VALUE
READY2 LD (THIS_B +2), A; Modifying TEAM
, But first DISCONNECT DRIVE:
XOR A; these commands,
CALL TO_1F; In principle,
LD A, # D0; CAN
CALL TO_1F; emissions.
, This command corresponds to LD A, (IX +0) ... LD A, (IX +7):
LD IX, TABL
THIS_B LD A, (IX); RECEIVED THE SITUATION ROOM
EI
RET
; TABLE FOR DETERMINING THE NUMBER OF SITUATION:
TABL DB 2,3,2,3,1,3,2,3
;***************************************
; SUPPORT PROCEDURES:
TO_1F LD C, # 1F
140.
TO_WG93 LD IX, # 2A53
JR TO_DOS
READY LD IX, # 3EF5
TO_DOS PUSH IX
JP # 3D2F
;***************************************
; PROCEDURE STATUS Return the contents of
; Status register.
; LOG: A-TRACK contents of the register,
; B-register contents SECTOR
; To be installed AFTER
, Output from the procedure.
; OUTPUT: A-value read from PORT # 1F.
; INTERRUPTION AFTER No exit!
STATUS DI
LD C, # 7F; A = N CYLINDER
CALL TO_WG93; IN REGISTER DATA
LD (RG_D +1), A; TRACK
LD A, B
LD (RG_S +1), A; SECTOR
; Saves the contents of cells that
; May be corrupted:
LD A, (# 5D0E)
LD (ST1 +1), A
LD A, (# 5D0C)
LD (ST2 +1), A
LD A, (# 5CB6)
LD (ST3 +1), A
LD A, (# 5D1F)
LD (ST4 +1), A
LD A, (# 5C3A)
LD (ST5 +1), A
LD A, (# 5D17)
LD (ST6 +1), A
LD HL, (# 5D1A)
LD (ST7 +1), HL
LD HL, (# 5D1C)
LD (ST8 +1), HL
LD HL, (# 5CF8)
LD (ST9 +1), HL
, Sets the contents of SOME
; CELL to work properly:
LD A, # FF
LD (# 5D0C), A
LD (# 5D1F), A
DEC A
LD (# 5D0E), A
LD A, # F4
LD (# 5CB6), A
LD HL, S_SPEC
LD (# 5D1A), HL
LD HL, 0
ADD HL, SP
LD DE, -12
ADD HL, DE
LD (# 5D1C), HL
LD A, 0, 0 IN REGISTER
LD C, # 3F; TRACK
CALL TO_WG93
LD A, # 0A; # A B REGISTER
LD C, # 5F; SECTOR
CALL TO_WG93
LD D, 1
LD IX, 16179
CALL TO_DOS; DETERMINED # 1F
, Is now being restored CONTENT
; REGISTRIES TRACK AND SECTOR:
RG_D LD A, 0
LD C, # 3F
CALL TO_WG93
RG_S LD A, 0
LD C, # 5F
CALL TO_WG93
; Restores the previously memorized
; Cell content:
ST1 LD A, 0
LD (# 5D0E), A
ST2 LD A, 0
LD (# 5D0C), A
ST3 LD A, 0
LD (# 5CB6), A
ST4 LD A, 0
LD (# 5D1F), A
ST5 LD A, 0
LD (# 5C3A), A
ST6 LD A, 0
LD (# 5D17), A
ST7 LD HL, 0
LD (# 5D1A), HL
ST8 LD HL, 0
LD (# 5D1C), HL
ST9 LD HL, 0
LD (# 5CF8), HL
LD A, B
RET
; This will be transferred to the Office if
; 0-bit registers state equals 1:
S_SPEC POP BC; THE CONTENT OF THE PORT
LD HL, (# 5D1C)
LD DE, 12; RESTORES
ADD HL, DE; INDEX
LD SP, HL; STACK
JR RG_D
2 You may have encountered
control programs change
disk drive (eg,
Jemmini Commander). They checked just above the bits of the
system registry (in principle, it is enough to monitor changes
in only any one of the two bits). Here is a simple algorithm
such Program:
Step 1: Read value Regis
spectrum of states. If the first
vy bit is 1, go
to step 4.
Step 2: N = "The disk is."
Step 3: Read the value Regis
spectrum of states. If the first
vy bit is 0, go
to step 3.
Step 4: N = "No Disc".
Step 5: Read the value Regis
spectrum of states. If the first
vy bit is 1, go
to step 5, otherwise step 2.
Note: The program is workable, provided that the hole on the
disc does not coincide with the hole on the body drive (this
involves the use of 1-bit status register).
Incidentally, such a program
There is one feature associated with the reading of the
register states. To read its value, it is necessary to drive
the engine worked. Therefore, using the following method:
Execute command positioning on a track whose number already
recorded in the register of the track. In this case, the head
will not move, but the engine drive turned on. After the end of
this command is read register states. Immediately after
The engine shuts down
for example, by writing 0 in
Port # FF (or port # 1F). Between two successive readings of
the register states pauses, usually 1 / 50 seconds. The engine
does not have time untwisted, and bulb drive does not light up.
But if you look closely, it is evident that the bulb is still
slightly lights (brightness is inversely proportional to the
length of the pause). So, on some drives (namely - the EU 5323.
01), it was noted that when running programs that control the
change of the disc, the bulb is lit and the engine is running.
Here is the text of a small demonstration program that
controls the replacement drive on the above algorithm. The
program displays the message "DISK PRESENT" and "DISK NOT
PRESENT". Exit - by pressing any keys (when the drive is
present). 140.
CALL 3435; CLS
LD A, 2
CALL 5633
M_1 CALL READ_S
BIT 1, A
JR NZ, M_4
M_2 LD A, 1
LD (N), A
LD DE, TEXT1
LD BC, 23
CALL 8252; "DISK PRESENT"
M_3 XOR A
IN A, (254)
AND 31
CP 1931
RET NZ; If pressing a key, Output
CALL READ_S
BIT 1, A
JR Z, M_3
M_4 XOR A
LD (N), A
LD DE, TEXT2
LD BC, 23
CALL 8252; "DISK NOT PRESENT"
M_5 CALL READ_S
BIT 1, A
JR NZ, M_5
JR M_2
N DB 0; 1-have a drive, 0-NO.
TEXT1 DB 22,0,0,16,7,17,0, "DISK PRESENT"
TEXT2 DB 22,0,0,16,7,17,0, "DISK NOT PRESENT"
;***************************************
; PROCEDURE READ_S read any
; Status register. Before reading
; DONE ON ENGINE
, DRIVE, AND AFTER READING-OFF AND
; PAUSE B3 1 / 50 seconds.
READ_S XOR A; ESTABLISHES THE SAME
LD C, # 3F; cylinder number
CALL TO_WG93; IN CASE TRACK
LD C, # 7F; AND IN CASE OF DATA.
CALL TO_WG93
LD A, # 18; POSITIONING. HEAD WILL NOT
CALL TO_1F; move, but engine on.
CALL READY; AWAITING EXECUTION ...
CALL STATUS; READ STATUS REGISTER.
EI; AUTHORIZES PREVIOUSLY PROHIBITED INTERRUPTION
PUSH AF
XOR A
CALL TO_1F; off the motor
LD A, # D0
CALL TO_1F
HALT 3; DELAY 1 / 50 seconds
POP AF
RET
;***************************************
; SUPPORT PROCEDURES:
TO_1F LD C, # 1F
TO_WG93 LD IX, # 2A53
JR TO_DOS
READY LD IX, # 3EF5
TO_DOS PUSH IX
JP # 3D2F
;***************************************
; PROCEDURE STATUS Return the contents of
; Status register.
; LOG: A-TRACK contents of the register,
; B-register contents SECTOR
; To be installed AFTER
, Output from the procedure.
; OUTPUT: A-value read from PORT # 1F.
; INTERRUPTION AFTER No exit!
STATUS DI
LD C, # 7F; A = N CYLINDER
CALL TO_WG93; IN REGISTER DATA
LD (RG_D +1), A; TRACK
LD A, B
LD (RG_S +1), A; SECTOR
; Saves the contents of cells that
; May be corrupted:
LD A, (# 5D0E)
LD (ST1 +1), A
LD A, (# 5D0C)
LD (ST2 +1), A
LD A, (# 5CB6)
LD (ST3 +1), A
LD A, (# 5D1F)
LD (ST4 +1), A
LD A, (# 5C3A)
LD (ST5 +1), A
LD A, (# 5D17)
LD (ST6 +1), A
LD HL, (# 5D1A)
LD (ST7 +1), HL
LD HL, (# 5D1C)
LD (ST8 +1), HL
LD HL, (# 5CF8)
LD (ST9 +1), HL
, Sets the contents of SOME
; CELL to work properly:
LD A, # FF
LD (# 5D0C), A
LD (# 5D1F), A
DEC A
LD (# 5D0E), A
LD A, # F4
LD (# 5CB6), A
LD HL, S_SPEC
LD (# 5D1A), HL
LD HL, 0
ADD HL, SP
LD DE, -12
ADD HL, DE
LD (# 5D1C), HL
LD A, 0, 0 IN REGISTER
LD C, # 3F; TRACK
CALL TO_WG93
LD A, # 0A; # A B REGISTER
LD C, # 5F; SECTOR
CALL TO_WG93
LD D, 1
LD IX, 16179
CALL TO_DOS; DETERMINED # 1F
, Is now being restored CONTENT
; REGISTRIES TRACK AND SECTOR:
RG_D LD A, 0
LD C, # 3F
CALL TO_WG93
RG_S LD A, 0
LD C, # 5F
CALL TO_WG93
; Restores the previously memorized
; Cell content:
ST1 LD A, 0
LD (# 5D0E), A
ST2 LD A, 0
LD (# 5D0C), A
ST3 LD A, 0
LD (# 5CB6), A
ST4 LD A, 0
LD (# 5D1F), A
ST5 LD A, 0
LD (# 5C3A), A
ST6 LD A, 0
LD (# 5D17), A
ST7 LD HL, 0
LD (# 5D1A), HL
ST8 LD HL, 0
LD (# 5D1C), HL
ST9 LD HL, 0
LD (# 5CF8), HL
LD A, B
RET
; This will be transferred to the Office if
; 0-bit registers state equals 1:
S_SPEC POP BC; THE CONTENT OF THE PORT
LD HL, (# 5D1C)
LD DE, 12; RESTORES
ADD HL, DE; INDEX
LD SP, HL; STACK
JR RG_D
*
2