File: trs_hard.h

package info (click to toggle)
xtrs 4.9d-3
  • links: PTS, VCS
  • area: contrib
  • in suites: sid
  • size: 5,484 kB
  • sloc: ansic: 72,545; makefile: 1,633; sh: 554; csh: 132
file content (209 lines) | stat: -rw-r--r-- 5,421 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* Copyright (c) 2000, Timothy Mann */
/* $Id: trs_hard.h,v 1.6 2009/06/15 23:41:03 mann Exp $ */

/* This software may be copied, modified, and used for any purpose
 * without fee, provided that (1) the above copyright notice is
 * retained, and (2) modified versions are clearly marked as having
 * been modified, with the modifier's name and the date included.  */

/*
 * Definitions for the Radio Shack TRS-80 Model I/III/4/4P
 * hard disk controller.  This is a Western Digital WD1000/WD1010
 * mapped at ports 0xc8-0xcf, plus control registers at 0xc0-0xc1.
 * 
 * Definitions inferred from various drivers and sketchy documents
 * found in odd corners.  Anyone have a real WD10xx data sheet?
 */

extern void trs_hard_init(void);
extern int trs_hard_in(int port);
extern void trs_hard_out(int port, int value);
extern char* trs_disk_dir;

/* Sector size is always 256 for TRSDOS/LDOS/etc. */
/* Other sizes currently not emulated */
#define TRS_HARD_SECSIZE 256
#define TRS_HARD_SECSIZE_CODE 0x0f /* size code for 256 byte sectors?!! */

/* RSHARD assumes 32 sectors/track */
/* Other sizes currently not emulated */
#define TRS_HARD_SEC_PER_TRK 32

/*
 * Tandy-specific registers
 */

/* Write protect switch register (read only): 
 *  abcd--pi
 *  a = drive 0 write protected
 *  b = drive 1 write protected
 *  c = drive 2 write protected
 *  d = drive 3 write protected
 *  p = at least one drive write protected
 *  i = interrupt request
 */
#define TRS_HARD_WP 0xc0
#define TRS_HARD_WPBIT(d) (0x80 >> (d))
#define TRS_HARD_WPSOME 0x02
#define TRS_HARD_INTRQ  0x01 /* not emulated */

/* Control register (read(?)/write): 
 *  ---sdw--
 *  s = software reset
 *  d = device enable
 *  w = wait enable
 */
#define TRS_HARD_CONTROL 0xc1
#define TRS_HARD_SOFTWARE_RESET 0x10
#define TRS_HARD_DEVICE_ENABLE  0x08
#define TRS_HARD_WAIT_ENABLE    0x04

/* ID register (Model II only!)
 */
#define TRS_HARD_ID0 0xc2
#define TRS_HARD_ID1 0xc3

/* CTC channels (Model II only!)
 */
#define TRS_HARD_CTC0 0xc4
#define TRS_HARD_CTC1 0xc5
#define TRS_HARD_CTC2 0xc6
#define TRS_HARD_CTC3 0xc7

/*
 * WD1010 registers
 */

/* Data register (read/write) */
#define TRS_HARD_DATA 0xc8

/* Error register (read only):
 *  bdin-atm
 *  b = block marked bad
 *  e = uncorrectable error in data 
 *  i = uncorrectable error in id (unused?)
 *  n = id not found
 *  - = unused
 *  a = command aborted
 *  t = track 0 not found
 *  m = bad address mark
 */
#define TRS_HARD_ERROR (TRS_HARD_DATA+1)
#define	TRS_HARD_BBDERR   0x80
#define TRS_HARD_DATAERR  0x40
#define TRS_HARD_IDERR    0x20 /* unused? */
#define TRS_HARD_NFERR    0x10
#define TRS_HARD_MCRERR   0x08 /* unused */
#define TRS_HARD_ABRTERR  0x04
#define TRS_HARD_TRK0ERR  0x02
#define TRS_HARD_MARKERR  0x01

/* Write precompensation register (write only) */
/* Value *4 is the starting cylinder for write precomp */
#define TRS_HARD_PRECOMP (TRS_HARD_DATA+1)

/* Sector count register (read/write) */
/* Used only for multiple sector accesses; otherwise ignored. */
/* Autodecrements when used. */
#define TRS_HARD_SECCNT (TRS_HARD_DATA+2)

/* Sector number register (read/write) */
#define TRS_HARD_SECNUM (TRS_HARD_DATA+3)

/* Cylinder low byte register (read/write) */
#define TRS_HARD_CYLLO (TRS_HARD_DATA+4)

/* Cylinder high byte register (read/write) */
#define TRS_HARD_CYLHI (TRS_HARD_DATA+5)

/* Size/drive/head register (read/write):
 *  essddhhh
 *  e = 0 if CRCs used; 1 if ECC used
 *  ss = sector size; 00=256, 01=512, 10=1024, 11=128
 *  dd = drive
 *  hhh = head
 */
#define TRS_HARD_SDH (TRS_HARD_DATA+6)
#define TRS_HARD_ECCMASK    0x80
#define TRS_HARD_ECCSHIFT   7
#define TRS_HARD_SIZEMASK   0x60
#define TRS_HARD_SIZESHIFT  5
#define TRS_HARD_DRIVEMASK  0x18
#define TRS_HARD_DRIVESHIFT 3
#define TRS_HARD_MAXDRIVES  4
#define TRS_HARD_HEADMASK   0x07
#define TRS_HARD_HEADSHIFT  0
#define TRS_HARD_MAXHEADS   8

/* Status register (read only): 
 *  brwsdcie
 *  b = busy
 *  r = drive ready
 *  w = write error
 *  s = seek complete
 *  d = data request
 *  c = corrected ecc (reserved)
 *  i = command in progress (=software reset required)
 *  e = error
 */
#define TRS_HARD_STATUS (TRS_HARD_DATA+7)
#define TRS_HARD_BUSY     0x80
#define TRS_HARD_READY    0x40
#define TRS_HARD_WRERR    0x20
#define TRS_HARD_SEEKDONE 0x10
#define TRS_HARD_DRQ	  0x08
#define TRS_HARD_ECC	  0x04
#define TRS_HARD_CIP	  0x02
#define TRS_HARD_ERR	  0x01

/* Command register (write only) */
#define TRS_HARD_COMMAND (TRS_HARD_DATA+7)

/*
 * WD1010 commands
 */

#define TRS_HARD_CMDMASK 0xf0

/* Restore: 
 *  0001rrrr
 *  rrrr = step rate; 0000=35us, else rrrr*0.5ms
 */
#define TRS_HARD_RESTORE 0x10

/* Read sector:
 *  0010dm00
 *  d = 0 for interrupt on DRQ, 1 for interrupt at end (DMA style)
 *      TRS-80 always uses programmed I/O, INTRQ not connected, I believe.
 *  m = multiple sector flag (not emulated!)
 */
#define TRS_HARD_READ  0x20
#define TRS_HARD_DMA   0x08
#define TRS_HARD_MULTI 0x04

/* Write sector:
 *  00110m00
 *  m = multiple sector flag (not emulated!) 
 */
#define TRS_HARD_WRITE 0x30

/* Verify sector (or "Scan ID"):
 *  01000000
 */
#define TRS_HARD_VERIFY 0x40

/* Format track:
 *  01010000
 */
#define TRS_HARD_FORMAT 0x50

/* Init (??):
 *  01100000
 */
#define TRS_HARD_INIT 0x60

/* Seek to specified sector/head/cylinder:
 *  0111rrrr
 *  rrrr = step rate; 0000=35us, else rrrr*0.5ms
 */
#define TRS_HARD_SEEK 0x70