TR-DOS

ZXNet echo conference «code.zx»

From Kirill Frolov To All 11 November 1999

Immediately press RESET, All! Well, I figured out how to issue auxiliary commands and what glitches there are. You can live without reading register 1F, through FF readiness is always read. At the same time I learned that the DX command cannot be given to the VGshka. She then goes into meditation, INTRQ does not output... We really need D0 immediate interruption. But as for recording sector readings, it couldn’t be worse. :-( I found this in TR-DOS: 3F4B 3ED0 LD A, 0xD0 3F4D D31F OUT (0x1F), A 3F4F 78 LD A, B 3F50 E601 AND 0x01 3F52 C2E73E JP NZ, 0x3EE7 3F55 DB3F IN A, (0x3F) 3F57 B7 OR A 3F58 2005 JR NZ, 0x3F5F 3F5A DB5F IN A, (0x5F) 3F5C FE0A CP 0x0A 3F5E C8 RET Z It turns out that if there is an error when reading sector 10 on track 0 TR-DOS doesn't care about that. Moreover, _PARTY NUMBER IS NOT CHECKED_! This means that the 10th sector of the very first file on the disk can be read with an error or not read at all! =%-() The conclusion is quite logical - 3d13 Mazda. But no turboloaders there will be no help here, they either ignore errors altogether, since they don’t can read register 1F, or use this buggy program in TR-DOS. But I just wanted to create a read-write programsectors with error detection and without using system variables TR-DOS. I came to the conclusion that this is simply impossible without reading the register 1F. We need to fix TR-DOS, this time... It's a terrible glitch. :-( It will definitely work in iS-DOS on 640kb disks, in MOA CP/M, in TR-DOS itself, when reading MS-DOS 800kb disks... Kirill Frolov. [ZX]

From Ivan Mak To Kirill Frolov 14 November 1999

Greetings, Kirill! <01:50> Kirill Frolov write to Ivan Mak: IM>> However, in both cases TR-DOS is easily replaced with RAM protected from IM>> records. You can fix it any way you want. KF> Well then, tell me how this can be done in Petersburg. Petersburg has a 3FFD port. Bits 0 and 3 enabled Bit 0 switches halves of 27010, like two halves of 27512 If bit 3 is one, instead of 27512 (27010) 64Kb of RAM is connected, which located in 12-15 banks. 12 - EXPANSION 13 - TR-DOS 14 - BASIC128 15 - BASIC48 At zero they are naturally write-protected, but writing is the same as in a regular extension remains. Upon reset, 3FFD is reset to 0 And in the latest firmware for Peters (27010) it was done so that you can the installed "ROM" is reset. Wow! The Protoss are attacking my Zerlings! It's time to get going. Ivan. - Divorce the circuit, big and small.. [ Sprinter-II ] [ Forth-CPU ] [ ZX ]

From Sergey Selev To Kirill Frolov 17 November 1999

I wish you good health, %t1. I wish you good health, Kirill. One day on Thursday, November 11, 1999, Kirill Frolov spoke with All about TR-DOS... KF> I found this in TR-DOS: KF> 3F4B 3ED0 LD A, 0xD0 KF> 3F4D D31F OUT (0x1F), A KF> 3F4F 78 LD A, B KF> 3F50 E601 AND 0x01 KF> 3F52 C2E73E JP NZ, 0x3EE7 KF> 3F55 DB3F IN A, (0x3F) KF> 3F57 B7 OR A KF> 3F58 2005 JR NZ, 0x3F5F KF> 3F5A DB5F IN A, (0x5F) KF> 3F5C FE0A CP 0x0A KF> 3F5E C8 RET Z KF> It turns out that if there is an error when reading sector 10 on KF> track 0 KF> TR-DOS doesn't care about that. Moreover, _PARTY NUMBER NOT KF> CHECKING_ ! KF> And this means that the 10th sector of the very first file is on KF> disk can KF> be read with an error or not read at all! =%-()Who taught you to use this subroutine? I myself have long ago I realized that she is a motherfucker! KF> The conclusion is quite logical - 3d13 Mazda. But none KF> turboloaders KF> won't help here, they either ignore errors altogether, because KF> not KF> can read register 1F, or use this buggy KF> program KF> in TR-DOS. What are you doing!!! Have you driven my Turbo Commander v0.xx??? In it all errors (No disk, Break, Disk error, Read only) are perfectly caught (there costs Turbo Driver)!!! Syst. subject variables can be saved if desired (12 bytes in total). KF> But I just wanted to create a program for KF> read-write KF> sectors with and without error detection KF> system variables KF> TR-DOS. I came to the conclusion that this is simply impossible without ^^^^^^ ^^^^^^^^^^ this is complete nonsense!!! It looks like you don't know how to program at all. KF> read register 1F. I would recommend this: Use the subroutine at address 10048 (#2740). What and how you work out yourself. But if it doesn’t reach you, then I’ll have to kill youshow me how to do it. Variables WILL NOT be spoiled!!! +++*** Bye. Selev Sergey aka Cyber ​​from Cobra Software ***++++

From Aleksandr Kolotuhin To All 20 August 2000

·∙.■■■ Hi, everyone! ■■■.∙· Explain to me, stupid, how to intercept errors: 1. Disk error 2. No disk 3. Disk is protected 4. Disk is full Thank you. Happy All! I came across Aleksandr's message. [SPECCY] [ZENIT] [BEER!] [GIRLZZZZ] [MY GUITAR]

From Kirill Frolov To Aleksandr Kolotuhin 21 August 2000

Press RESET immediately, Aleksandr! 20 Aug 00 02:44, Aleksandr Kolotukhin wrote to All: AK> Explain to me, stupid, how to intercept AK> errors: AK> 1. Disk error AK> 2. No disk AK> 3. The disk is protected AK> 4. Disk is full Error codes: Error handling in TR-DOS is implemented very incorrectly, but it is still possible to distinguish errors if we use two translations variable: 23610 and 23823. ╔════════════════════╤══════════ ═══════════════════╤═════╤═════╗ ║Error message.│Meaning. │23610│23823║ ╟────────────────────┼────────── ───────────────────┼─────┼─────╢ ║O.K. │Normal completion. │ 255 │ 0 ║ ║No file(s) │The required file was not found. │ 255 │ 1 ║ ║File exists │The file already exists. │ 255 │ 2 ║ ║No space │No disk space. │ 255 │ 3 ║ ║Directory full │There is no space in the disk directory. │ 255 │ 4 ║ ║Rec OF │Appeal to non-existent │ 255 │ 5 ║ ║ │file sector. │ │ ║ ║No disc │There is no disc in the drive. │ 26 │ 6 ║ ║Disc error │Disk error. There are 3 options - │ 26 │ 7 ║║Trk XX sec XX │anta: R - try again- │ │ ║ ║Retry, Abort, Ignore? │ │ ║ ║ │of the next sector, A - otka- │ │ ║ ║ │to avoid surgery. │ │ ║ ║Read only │The disc is write protected. Yes │ 26 │ 7 ║ ║Trk XX sec XX │3 options (see above). │ │ ║ ║Retry, Abort, Ignore? │ │ │ ║ ║Stream opened │The stream to be opened is already busy. │ 25 │ 10 ║ ║Not disk file │The closed channel does not belong - │ 255 │ 11 ║ ║ │lies TR-DOS. │ │ ║ ║Array not found │The required variable is not found- │ 255 │ 14 ║ ║ │dena. │ 1 │ 1 ║ ║*BREAK* │BREAK key is pressed. │ 20 │ 20 ║ ║ │ │ 12 │ 12 ║ ║Out of RAM │Not enough RAM│ 3 │ 3 ║ ║Disc error │The disk does not belong to TR-DOS. │ 255 │ 0 ║ ║Read only │Attempting to record on a 40-track-│ 255 │ * ║ ║ │ 80-track disc │ │ ║ ║ │disk drive. │ │ ║ ║*ERROR* │Other errors, mainly │ 11 │ 12 ║ ║ │syntactic. │X │X+1 ║╚════════════════════╧══════════ ═══════════════════╧═════╧═════╝ * - copy of the variable with the drive type, X - any number. If the message Retry, Abort, Ignore? installation error codes are poured when the answer is A. > There is no need to intercept points 1, 3 and 4, just look at the error code immediately > after CALL 3D13. Just don't forget to do LD HL,0 : LD (5D0F),HL. > Point 2 is intercepted in the standard way, through the system > variable ERR_SP (see Larchenko and Rodionov in the book): ; calling the tr-dos function trdos: push hl ld hl, (err_sp) ex (sp), hl push hl ld hl, basic_error ex (sp), hl ld (err_sp), sp call 3d13h basic_error: pop de pop de ld (err_sp), de .... ; checking for an error System variables TR-DOS 5.04T. ╔═════╤═════╤═══════════════════ ═══════════════════════════════╗ ║Address│Length│ Content. ║ ╟─────┼─────┼─────────────────── ───────────────────────────────╢ ║23734│ 1 │Used if there is INTERFACE-1. If equal to ║ ║ │ │244, then the variable area is not transferred, otherwise ║ ║ │ │checking 23832. ║ ║23735│ 11 │Not used. ║> Pay attention VVV > >║23746│ 1 │Contains the RET command. Used to switch - ║ > > ^^^^^ Look there ║ │ │version of ROM to BASIC. ║ ║23747│ 5 │Not used. ║ ║23752│ 1 │Drive type A: ║ ║ │ │ bit 7=0 - 40-track drive. ║ ║ │ │ 1 - 80-track drive. ║ ║ │ │ bit 1=0 - single-sided drive. ║ ║ │ │ 1 - double-sided disk drive. ║ ║ │ │ bit 0=0 - use 80-track drive as║ ║ │ │ 40) track. ║ ║23753│ 1 │Drive type B. ║ ║23754│ 1 │Drive type C. ║ ║23755│ 1 │Disk drive type D. ║ ║23756│ 1 │Current sector when working with a directory. ║ ║23757│ 1 │If not 0, then there will be a delay after positioning-║ ║ │ │ka. VG-93 status register before road check -║ ║ │ │ki. Bit 7 of the VG-93 status register before reading ║ ║ │ │address marker. ║ ║23758│ 1 │Flag for operations with sectors. At 0 - reading sectors,║║ │ │at 255 - recording. ║ ║23759│ 2 │Address of the working memory area for MOVE, COPY, LIST.║ ║ │ │and when processing the record number when outputting to a file ║ ║ │ │direct access data. ║ ║23761│ 1 │Length of the moved file for MOVE. ║ ║23762│ 1 │Array name when writing/loading an array in the form: ║ ║ │ │bits 0 - 4 - array name (from "A"=1 to "Z"=26), ║ ║ │ │bit 5 - if 0, then the array is numeric, ║ ║ │ │bit 6 - if 1, then the array is string, ║ ║ │ │bit 7 is always 1. ║ ║23761│ 2 │Autostart line number when writing a program to ║ ║ │ │basic. ║ ║23763│ 2 │Sector counter of the moved file for MOVE. ║ ║23764│ 1 │Number of the file to be erased for MOVE. ║ ║23765│ 1 │Current sector of the moved file for MOVE. ║ ║23766│ 1 │The current track of the moved file for MOVE. Co- ║ ║ │ │number of defective sectors during formatting and ║ ║ │ │checking the disk. For the string compression routine: ║ ║ │ │if 0, then the command is in the program line at║ ║ │ │basic, otherwise elsewhere. For subroutine ║ ║ │ │file download: if 0, then download address and length ║║ │ │taken from the file descriptor, if 3, then from 23769 and ║ ║ │ │23771 respectively, otherwise the download address is taken║ ║ │ │from 23769, and the length is from the file descriptor. ║ ║23767│ 1 │The current sector of the file to be erased during MOVE. Quantity-║ ║ │ │two tracks when determining the type of drive and format- ║ ║ │ │matting. ║ ║23768│ 1 │The current track of the file to be erased during MOVE. If not ║ │ │0, then the formatted track is not checked. ║ ║23767│ 2 │Saves CH_ADD when processing record number in ║ ║ │ │sequential access file. Variable address ║ ║ │ │string length for the string compression routine. Address║ ║ │ │of the old array when loading the array. Secto address -║ ║ │ │pa for PEEK and POKE. ║ ║23769│ 1 │Relative address of record when processing number ║ ║ │ │records in a sequential access file. ║ ║23770│ 1 │Number of the block of the arbitrary file to be opened - ║ ║ │ │stupid when processing the record number. If equal to 128, ║ ║ │ │, then two sides are formatted, otherwise only one.║ ║23769│ 2 │Counter of freed sectors for MOVE. Address ║ ║ │ │file loading for LOAD, sector number for PEEK and ║ ║ │ │POKE. The keyword address for the compression subroutine is ║║ │ │this line. Length of the file to be written when SAVE. ║ ║23771│ 1 │The number of the loaded sector of the file block is arbitrary - ║ ║ │ │free access when processing the record number. Number ║ ║ │ │the first sector of the moved file for MOVE. ║ ║23772│ 1 │number of the first track of the moved file for MOVE.║ ║23771│ 2 │File length for LOAD. File length to specify in ║ ║ │ │directory with SAVE. Stream number for CAT and LIST. ║ ║23773│ 8 │The name of the file or disk when formatting. ║ ║23781│ │File extension. ║ ║23782│ 2 │File download address. Sector table address for ║ ║ │ │formatting. ║ ║23784│ 2 │File length. Sector table address to check ║ ║ │ │paths. ║ ║23786│ 1 │File volume in sectors. ║ ║23787│ 1 │Number of the first sector of the file. ║ ║23788│ 1 │Number of the first track of the file. ║ ║23789│ 2 │Download address of the old file for COPY. ║ ║23791│ 2 │Length of the old file in bytes for COPY. ║ ║23793│ 1 │Length of the old file in sectors for COPY. ║ ║23794│ 1 │Number of the first sector of the old file for COPY. ║ ║23795│ 1 │Number of the first track of the old file for COPY. ║║23796│ 1 │Number of the current sector for the subroutine ║ ║ │ │sector loading/writing. ║ ║23797│ │Number of the current track for the subroutine ║ ║ │ │sector loading/writing. ║ ║23798│ 2 │Disk drive number for the operation (0 - 3). ║ ║23800│ 1 │Source drive for COPY. If equal to 255, then at║ ║ │ │When outputting to a data file, the buffer is not deleted. ║ ║23801│ 1 │Receiver drive for COPY. Drive number at ║ ║ │ │output of the directory. Sign of file operation: 0 - ║ ║ │ │ - loading, 255 - verification. ║ ║23802│ 1 │Drive head movement time A: (8 - 11). ║ ║23803│ 1 │Same for drive B:. ║ ║23804│ 1 │Same for drive C:. ║ ║23805│ 1 │Same for drive D:. ║ ║23806│ 1 │Controller command for read/for- ║ ║ │ │pis sector. ║ ║23807│ 1 │Sector number for the read/write routine ║ ║ │ │sector. ║ ║23808│ 2 │Sector address for read/write routine ║ ║ │ │sector. ║ ║23810│ 2 │Saves HL for subroutine call subroutine ║║ │ │from BASIC ROM and 15635. ║ ║23812│ 2 │Keeps DE. ║ ║23814│ 1 │Number of file descriptor bytes checked when it is ║ ║ │ │search. ║ ║23815│ 1 │Number of erased files for the erase subroutine - ║ ║ │ │ files. ║ ║23816│ 1 │The first character of the file name for the erase routine is ║ ║ │ │ files. ║ ║23817│ 1 │data file type for OPEN# ("R", "W" or "RND"). ║ ║23819│ 2 │Not used. ║ ║23820│ 1 │Buffer presence flag: 0 - yes, otherwise - no. ║ ║23821│ 1 │Number of the current file when copying the entire disk from║ ║ │ │two disk drives. ║ ║23822│ 1 │State flag of the working memory area. If equal to ║ ║ │ │255, then the work area was used. If equal║ ║ │ │254, then subroutine 963 ignores errors. ║ ║23823│ 1 │TR-DOS error code. When searching for a file with the subroutine ║ ║ │ │15635: 255 - file not found, otherwise - file number. ║ ║23824│ 1 │Operation flag for the load/verify subroutine ║ │ │file cations: 0 - file operation, 255 - download- ║ ║ │ │ka / file sector verification, otherwise - write ║║ │ │sectors of the file. ║ ║23825│ 2 │Command line address. ║ ║23827│ 2 │Saves the contents of ERR_SP for subprograms ║ │ │gate to BASIC. ║ ║23829│ 1 │If 0, then error messages are displayed on the screen - ║ ║ │ │kah, otherwise they will not be displayed. ║ ║23830│ 1 │Copy of the system register. ║ ║23831│ 1 │If equal to 170, then when calling 15612 the screen saver does not ║ ║ │ │is displayed, otherwise the splash screen is displayed and checked ║ ║ │ │byte at address 23296. If it is equal to 170, then the ║ │ │the “boot” file is launched. ║ ║23832│ 1 │Used if there is INTERFACE-1. If not 0, then║ ║ │ │memory blocks 45 bytes long are swapped ║ ║ │ │addresses 23747 and 23859. ║ ║23833│ 1 │Default drive number. ║ ║23834│ 2 │Return address from the completion subroutine. ║ ║23836│ 2 │Saves SP for routines to return to BASIC. ║ ║23838│ 1 │File number when searching for it. ║ ║23839│ 1 │Flag for calling TR-DOS. If 0, then the call was ║ ║ │ │from machine code, otherwise - from BASIC. First sec-║ ║ │ │tor of the file on the destination disk for COPY S. ║║23840│ 1 │First sector of the file on the destination disk for COPY S.║ ║23840│ 3 │Saves the first 3 characters of the command line. ║ ║23841│ 1 │If not 0, then the first copying pass is in progress, otherwise-║ ║ │ │che continuation. ║ ║23843│ 1 │Size of available memory in sectors for MOVE and ║ ║ │ │COPY. ║ ╚═════╧═════╧═══════════════════ ═══════════════════════════════╝ When initializing the system, the following cells are also used: ╔═════╤═════╤═══════════════════ ═══════════════════════════════╗ ║Address│Length│ Content. ║ ╟─────┼─────┼─────────────────── ───────────────────────────────╢ ║23746│ 1 │RET command. Used to call subroutines ║ ║ │ │from BASIC ROM. ║ ║24320│ 2 │Saves HL for command execution subroutine ║ ║ │ │processor in RAM. ║ ║24322│ 14 │Not used. ║ ║24336│ 3 │Subroutine for moving LDIR memory blocks or ║ ║ │ │LDDR. ║ ║24339│ 237 │Time stack. ║ ╚═════╧═════╧═══════════════════ ═══════════════════════════════╝ Also, when initializing TR-DOS system variables, 20 bytes saddresses 23698 are used to place the verification routine availability of INTERFACE-1. > Intercepting messages "What the hell, what the hell, what the hell?" is implemented something like this: ; interception installation install: ld hl, 5cc2h ld (hl), 0c3h ld hl, your_programm ld (5cc3h), hl ... ; calling tr-dos functions trdos: ld (tempstack), sp jp 3d13h ; interception your_program: ex (sp), hl push af ld a, h cp 0dh jr nz, return ld a, l cp 6bh jr z, catch return: pop af ex (sp), hl ret ; caught the NO DISK error or the request No, No, No? catch: ld sp, 0 tempstack equ $-2 ... Everything is based on the fact that before displaying the RAI request, tr-dos clears the screen calling procedure 0d6bh from BASIC.

From Aleksandr Kolotuhin To All 14 July 2004

·∙.■■■ Hi, All! ■■■.∙· And throw at me the procedures for working with a disk drive (reading, writing, head positioning, etc.) without using tr-dos. Or tell me the url with documentation. ·∙.■■■ Happy All! ■■■.∙·

From Kirill Frolov To Aleksandr Kolotuhin 18 July 2004

Press RESET immediately, Aleksandr Kolotukhin! On Wed, 14 Jul 04 18:49:47 +0400, Aleksandr Kolotukhin wrote: AK> Throw at me the procedures for working with the drive (reading, writing, AK> head positioning, etc.) without using tr-dos. AK> Or tell me the url with documentation. TR-DOS as well as Beta-Disk are still required. TR-DOS just for what procedures are used to provide access to Beta-Disk ports inaccessible to programs executing in RAM (I mean that when placed in the TR-DOS ROM, the program should be a little more different). Should have been used in CP/M. Yes, TR-DOS needs version 5.03 or any compatible. Almost anyone. No special no requirements. A code revision is required, as well as bug fixes. List of functions at first, there is no documentation. If used, I require publication version used (i.e. corrected...) here and/or in Fido, in real.speccy or zx.spectrum. ; IY=Drive Parameters Block pointer global fdreset ; reset controller global fdstop ; stop all drives global fready ; check drive ready/not -> CF=0 if ready global fdindex ; return INDEX state -> CF=0 if active global fdchange ; -> CF=1 disk changed global fdpresent ; -> CF=1 drive not present global fdctl ; call it first for new drive! global fdside ; set side A?0:1 global fdtrack ; set heads to track A -> CF=1 on error global fdrdsec ; read sector A \n global fdwrsec ; write sector A | global fdrdadr ; read address mark > CF=1 on error, A=status bits global fdrdtrk ; read track | buffer=(HL++) global fdwrtrk ; write track / ; ; Floppy disk driver for ZX-Spectrum and Beta-Disk interface ; Copyright (C) 1999, Kirill Frolov *Include floppy.inc *Include betadisk.inc rsttime equ 1000 ; controller io registers rgcmd equ 1fh ; write only -- command register rgstat equ 1fh ; read only -- status register rgtrk equ 3fh ; track register rgsec equ 5fh ; sector register rgdata equ 7fh ; data register rgctl equ 0ffh ; write only -- external controller register ; command modifiers cs0 equ 01h ; head moving speed bit 0 cJ0 equ 01h ; interrupt command modifier, see below ca0 equ 01h ; special sector mark, not used cs1 equ 02h ; head moving speed bit 1 cJ1 equ 02h cC equ 02h ; check side (for read/write commands) cV equ 04h ; read and verify head position (for seek, step and reset commands) cE equ 04h ; delay before reading/writing? cJ2 equ 04h ch equ 08h ; load head (for seek, step and reset commands) cS equ 08h ; disk side (for read/write commands, used only if cC=1) cJ3 equ 08h cI equ 10h ; modify or not rgtrk, used only for step commands cm equ 10h ; multisector operation (for read/write sector commands only) ; command interrupt bits ci_noi equ 0 ; stop command execution but don't interrupt host (INTRQ signal) ci_rdy equ cJ0 ; stop command execution when DRDY is active (drive ready) ci_off equ cJ1 ; stop command execution when DRDY is inactive (drive not ready) ci_idx equ cJ2 ; stop command execution when INDEX impulse detected ci_imm equ cJ3 ; stop command execution now and set INTRQ ; commands creset equ 00 ; reset controller, seek track 0 cseek equ 10 ; seek track in rgdata cstep equ 20 ; repeat last cfstep or cbstep cfstep equ 40 ; forward step (from track 0) cbstep equ 60 ; back step (to track 0) crdsec equ 80 ; read sector(s) cwrsec equ 0a0h ; write sector(s) crdadr equ 0c0h ; read address mark (6 bytes) crdtrk equ 0e0h ; read whole track with all address marks, etc... cwrtrk equ 0f0h ; write whole track (format track) cint equ 0d0h ; interrupt command execution ; status bits sbusy equ 01h ; 1=controller busy (command executed) sdrq equ 02h ; 1=data read/write requested sidx equ 02h ; 1=index impulse strk0 equ 04h ; 1=heads at track 0 sover equ 04h ; 1=data overrun scrc equ 08h ; 1=crc failed, sector corrupted sseek equ 10h ; 1=seek failed snosec equ 10h ; 1=sector not found shead equ 20h ; 1=head loaded serase equ 20h ; 1=special sector mark, not used swfail equ 20h ; 1=write failed swprot equ 40h ; 1=write protected disk sdrdy equ 80h ; 1=drive ready (really it's HEAD/MOTOR signal indicator) ; control register bits dd0 equ 01h ; drive number bit 0 dd1 equ 02h ; drive number bit 1 dreset equ 04h ; 0=reset controller ddrdy equ 08h ; 1=floppy drive ready (emulation of real DRDY signal) dside equ 10h ; 1=bottom size(0), 0=upper side(1) dmfm equ 20h ; 1=double density (MFM method), 0=single density (FM) for 8" floppy ; interrupt bits idrq equ 40h ; 1=active only if data read/write requested iintrq equ 80h ; 1=active after execution of all commands trentr equ 3d2fh ; tr-dos entry point troutc equ 2a53h ; out(c),a trintr equ 3fcah ; wait for intrq !set C to rgtrk, rgsec or rgdata only! trread equ 3fd5h ; reading routine address trwrite equ 3fbah ; writing routine address trstat equ 2470h ; read status trssv equ 5d04h ; word trsst equ 5ccdh ; byte trshl equ 5d02h ; word trsjp equ 5cc2h ; byte trsadr equ 5cc3h ; word ; get STATUS REGISTER in A fdstat: ld a, (trsjp) push af ld hl, (trsadr) push hl ld hl, (trssv) push hl ld a, (trsst) push af ld hl, trsjp ld (hl), 0c3h ; JP instruction ld hl, fdstret ld (trsadr), hl ld d, (iy+track) ld hl, trstat push hl ld hl, (trshl) jp trentr ; 2740: in a,(1fh) ; ld (5ccdh),a ; ld e,d ; push de ; ld a,e ; out (7fh),a ; ld a,18h ; call 3d9ah ; ; 3d9a: out (1fh),a ; push hl ; rst 20h ; dw 1f54h ; ; 0020: jp 2f72h ; ; 2f72: ld (5d02h),hl ; ld (5d04h),de ; pop hl ; ld e,(hl) ; inc hl ; ld d,(hl) ; inc hl ; push hl ; ld hl,3d2fh ; push hl ; push de ; ld hl,5cc2h ; push hl ; ld hl,(5d02h) ; ld de,(5d04h) ; ret fdstret: ; pop hl ; 1f54h ; pop hl ; 3d2fh ; pop hl ; rst 20h ... ; pop hl ; push hl ; pop hl ; call 3d9ah ... ; pop hl ; de ld hl, 12 add hl, sp ld sp, hl ; restore stack ld a, (trsst) ; e = rgstat ld e,a pop af ld (trsst), a pop hl ld (trssv), hl pop hl ld (trsadr), hl pop af ld (trsjp), a ld a, e ret ; write command A to COMMAND REGISTER fdcmd: ld c, rgcmd ; jp fdwreg ; write A to register C fdwreg: ld hl, troutc push hl jp trentr ; write command A to COMMAND REGISTER and wait INTRQ fdcserv: call fdcmd ld c, rgtrk ; jp fdwait ; wait for INTRQ !DANGER may never return! fdwait: ld hl, trintr push hl jp trentr ; jump to READ proc. hl=data fdjpread: ld c, rgdata push hl ld hl, trread ex (sp), hl jp trentr ; jump to WRITE proc. hl=data fdjpwrite: ld c, rgdata push hl ld hl, trwrite ex (sp), hl jp trentr ; reset controller fdreset: ld c, rgctl xor a call fdwreg ld bc, rsttime fdres1: dec bc ld a, b or c jr nz, fdres1 call fdctl call fdcserv call fdtrack0 xor a ret ; turn off motor fdstop: ld a, (iy+track) ld c, rgdata call fdwreg ld a, cseek ld c, rgcmd jp fdcserv ; set head to track 0 -> CF=1 on error fdtrack0: ld a, creset+ch or (iy+sspeed) ld c, rgcmd call fdcserv call fdstat ld (iy+track), 0 and strk0 ld a, 0 ret nz ; all ok scf ld (iy+track), 0ffh ; reset failed! ret ; set head to track A -> CF=1 on error fdtrack: or a jr z, fdtrack0 ld b, (iy+track) cp b ret z push af inc b jr nz, fdtrack_1 call fdtrack0 pop bc ret c push bc fdtrack_1: pop af ld b, (iy+track) ld (iy+track), a ld c, rgdata call fdwreg ld a, b ld c, rgtrk call fdwreg ld a, cseek+ch or (iy+sspeed) ld c, rgcmd call fdcserv xor a ret ; check if drive ready (HEAD/MOTOR is active?) and start it -> CF=0 if ready fdready: call fdstat and sdrdy ret nz scf ret ; return index state -> CF=0 - INDEX fdindex: call fdstat and sidx ret nz scf ret ; check if disk changed? CF=1 if changed fdchange: call fdstat push af and sdrdy jr nz, fdch1 call fdstop ; stop drive if it is inactive fdch1: pop af and swprot xor (iy+chflag) ret z xor (iy+chflag) ld (iy+chflag), a scf ret ; check if drive present? CF=1 drive not present fdpresent: call fdtrack0 ret c ld a, 1 call fdtrack call fdstat and strk0 ret z ; all ok, drive present ld (iy+track), 0ffh ; no drive! scf ret ; set side A fdside: and 01h ld (iy+side), a ; jp fdctl ; set control register(s) fdctl: ld a, (iy+drive) and dd0+dd1 ; hack... why? bit bmfm, (iy+dmode) jr z, fdctl1 or dmfm fdctl1: bit 0, (iy+side) jr nz, fdctl2 or dside fdctl2: or ddrdy+dreset ld c, rgctl call fdwreg ld a, (iy+track) ; 0xff... bug? ld c, rgtrk jp fdwreg ; read sector A from current track to (HL++) !DANGER: NO SECTOR SIZE CHECKING! ; return CF=1 if error, A=status bits fdrdsec: push hl ld c, rgsec call fdwreg bit bcside, (iy+dmode) ld a, crdsec jr z, frds1 or cC bit 0, (iy+side) jr z, frds1 or cS frds1: ld c, rgcmd call fdwreg pop hl call fdjpread jp z, fdtout ; timeout! call fdstat and sover+scrc+snosec ret z ; all ok jp fderror ; write sector A to current track from (HL++) !WARNING: NO SECTOR SIZE CHECKING! ; return CF=1 if error, A=error code fdwrsec: bit brdonl, (iy+dmode) jr z, fdwrs0 ld a, efdwprot scf ret fdwrs0: push hl ld c, rgsec call fdwreg bit bcside, (iy+dmode) ld a, crdsec jr z, fwrs1 or cC bit 0, (iy+side) jr z, fwrs1 or cS fwrs1: ld c, rgcmd call fdwreg pop hl call fdjpwrite jr z, fdtout ; timeout! call fdstat and sover+scrc+snosec+swfail+swprot ret z ; all ok jr fderror ; read address mark to (HL++) 6 bytes. ; return CF=1 if error, A=error code fdrdadr: push hl ld a, crdadr ld c, rgcmd call fdwreg pop hl call fdjpread jr z, fdtout ; timeout! call fdstat and sover+scrc ret z ; all ok jr fderror ; read track to (HL++) ~7kb max. ; return CF=1 if error, A=error code fdrdtrk: push hl ld a, crdtrk ld c, rgcmd call fdwreg pop hl call fdjpread jr z, fdtout ; timeout! call fdstat and sover ret z ; all ok jr fderror ; write track from (HL++) ~7kb max. ; return CF=1 if error, A=error code fdwrtrk: bit brdonl, (iy+dmode) jr z, fdwrt0 ld a, efdwprot scf ret fdwrt0: push hl ld a, cwrtrk ld c, rgcmd call fdwreg pop hl call fdjpwrite jr z, fdtout ; timeout! call fdstat and sover+swfail+swprot ret z ; all ok and 0ffh-swprot ld a, efdwprot scf ret z ; error A=status jr fderror ; read/write sector/track/addressmark error fderror: ld c, a and swprot ld a, efdwprot scf ret nz ld a, c and snosec ld a, efdnosec scf ret nz ld a, c and scrc ld a, efdcrc scf ret nz ld a, efdfail ret ; read/write sector/track/addressmark timeout fdtout: ld a, cint+ci_imm ; stop command execution call fdcmd ld a, creset or (iy+sspeed) ; stop drive, move heads to track 0 call fdcmd ld (iy+track), 0ffh ld a, efdtout ; return error status scf ret end

From Kirill Frolov To Kirill Frolov 18 July 2004

Hемедленно нажми на RESET, Kirill Frolov! On Sun, 18 Jul 2004 09:54:52 +0000 (UTC), Kirill Frolov wrote: KF> ; IY=Drive Parameters Block pointer Забыл ещё: ; IY+var -- drive variables (передаётся аргументом ко всем функциям) drive equ 0 ; physical drive 0..3 sspeed equ 1 ; seek speed 0..3 dmode equ 2 ; mode bits track equ 3 ; track 0xff = undefined side equ 4 ; side 0=bottom, 1=top chflag equ 5 ; write protect status(call fdchange) changed equ 6 ; 1=disk changed reservx equ 7 ; reserved dpbsize equ 8 ; size of drive vars. ; mode masks and bits mmfm equ 01h ; 1=mfm (*) bmfm equ 0 mcside equ 02h ; 1=check side (*) bcside equ 1 mwrdel equ 04h ; 1=write delay (for slow drives) bwrdel equ 2 mauto equ 08h ; 1=auto disk change bauto equ 3 mrdonl equ 80h ; 1=readonly (*) -- used in betadisk module brdonl equ 7 ; error codes efdok equ 0 ; no errors efdfail equ 1 ; hardware failure efdwprot equ 2 ; write protect efdnosec equ 3 ; sector not found efdcrc equ 4 ; crc error efdtout equ 5 ; timeout

From Slavik Tretiak To All 10 March 2006

Hello, All remind me how to disable error handling in TR-DOS (i.e. so that it does not respond to BREAK and if there was a reading error, I read until I was blue in the face). We did this in our demo (-=AOS=-), but it was a long time ago and I don’t remember how.