aboutsummaryrefslogtreecommitdiff
path: root/inc/dosdrv.h
blob: 0c33c54bb1b6af3eec2d4b656c303cc9965b1a01 (plain)
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
#ifndef DOSDRV_H
#define DOSDRV_H

#include <stdint.h>
#include "bpb.h"
#include "sassert.h"

typedef enum DOS_DD_ERROR
{
	DOS_DD_ERR_WRITE_PROTECT = 0,
	DOS_DD_ERR_UNKNOWN_UNIT = 1,
	DOS_DD_ERR_DRIVE_NOT_READY = 2,
	DOS_DD_ERR_UNKNOWN_COMMAND = 3,
	DOS_DD_ERR_CRC = 4,
	DOS_DD_ERR_BAD_DRS_LEN = 5,
	DOS_DD_ERR_SEEK = 6,
	DOS_DD_ERR_UNKNOWN_MEDIA = 7,
	DOS_DD_ERR_SECTOR_NOT_FOUND = 8,
	DOS_DD_ERR_PRINTER_OUT_OF_PAPER = 9,
	DOS_DD_ERR_WRITE_FAULT = 10,
	DOS_DD_ERR_READ_FAULT = 11,
	DOS_DD_ERR_GENERAL_FAILURE = 12,
	DOS_DD_ERR_MEDIA_UNAVAILABLE = 0xE,
	DOS_DD_ERR_INVALID_DISK_CHANGE = 0xF
} DOS_DD_ERROR;

typedef enum DOS_DD_STATUS {
	DOS_DD_STATUS_DONE  = 1 << 8,
	DOS_DD_STATUS_BUSY  = 1 << 9,
	DOS_DD_STATUS_ERROR = 1 << 15,

	DOS_DD_STATUS_ERROR_DONE = DOS_DD_STATUS_ERROR | DOS_DD_STATUS_DONE
} DOS_DD_STATUS;

typedef enum DOS_DD_MEDIAQUERY_RESULT {
	DOS_DD_MEDIAQUERY_CHANGED = -1,
	DOS_DD_MEDIAQUERY_UNKNOWN = 0,
	DOS_DD_MEDIAQUERY_NOT_CHANGED = 1
} DOS_DD_MEDIAQUERY_RESULT;

typedef _Packed struct DOS_DRS
{
	/** The length of this structure. */
	uint8_t len;
	/** The subunit the operation is for. */
	uint8_t unit;

	uint8_t function;

	uint16_t status;

	uint32_t reserved1;
	uint32_t reserved2;

	union {
		union {
			struct {
				uint8_t reserved;
				/** End of memory available for driver. */
				void __far * avail_addr;
				/** Command line (i.e. the DEVICE= line used to load this driver. ) */
				const char __far * cmdline;
				/** First drive that is going to be allocated for this driver. */
				uint8_t first_drive_number;
			} in;
			struct {
				/** Number of units/drive letters to allocate for this driver. */
				uint8_t number_units;
				/** Break addr: everything after this address is deallocated after init. */
				void __far * break_addr;
				/** Pointer to the BPB array. */
				DOS_BPB * __far * bpbs;
				uint8_t reserved;
				/** Display error message on failure. */
				uint16_t error_msg_flag;
			} out;
		} init;
		union {
			struct {
				/** Media descriptor of the current media. */
				uint8_t cur_media_desc;
			} in;
			struct {
				uint8_t reserved;
				uint8_t result;
				/** Volume ID of previous loaded media. */
				char far * volume_id;
			} out;
		} mediacheck;
		union {
			struct {
				/** Media descriptor of the current media. */
				uint8_t cur_media_desc;
				/** Buffer with sector 0 of the disk, depending on driver flags */
				void __far * sector_zero;
			} in;
			struct {
				uint8_t reserved;
				void __far * sector_zero;
				/** Address for the new BPB. */
				DOS_BPB __far * bpb;
			} out;
		} buildbpb;
		struct {
			uint8_t data;
			/** Input: pointer to buffer. */
			void __far * buffer;
			/** Input/Output: buffer len / actual len */
			uint16_t len;
		} ioctlrw;
		struct {
			/** Input: current media descriptor byte. */
			uint8_t cur_media_desc;
			/** Input: pointer to buffer. */
			void __far * buffer;
			/** Input: Number of sectors to read/write. Output: number sectors actually read/written. */
			uint16_t len;
			/** Input: Begin sector. Or, if 0xFFFF, see start_sector_huge. */
			uint16_t start_sector;
			/** Output: Current Volume ID. */
			char far * volume_id;
			uint32_t start_sector_huge;
		} rw;
		struct {
			uint8_t category;
			uint8_t minor;
			uint32_t reserved;
			void __far * data;
		} ioctl;
	} cmd;
} DOS_DRS;

typedef void (DOS_DD_STRATEGY)(DOS_DRS __far *drs);
typedef void (DOS_DD_INTERRUPT)(DOS_DRS __far *drs);
#pragma aux DOS_DD_STRATEGY __parm __caller [es bx] __modify [] __loadds __far
#pragma aux DOS_DD_INTERRUPT __parm __caller [] __modify [] __loadds __far

typedef enum DOS_DD_FUNCTIONS
{
	DOS_DD_FUNC_INIT = 0,
	DOS_DD_FUNC_MEDIA_CHECK = 1,
	DOS_DD_FUNC_BUILD_BPB = 2,
	DOS_DD_FUNC_IOCTL_READ = 3,
	DOS_DD_FUNC_READ = 4,
	DOS_DD_FUNC_NONDESTRUCTIVE_READ = 5,
	DOS_DD_FUNC_INPUT_STATUS = 6,
	DOS_DD_FUNC_INPUT_FLUSH = 7,
	DOS_DD_FUNC_WRITE = 8,
	DOS_DD_FUNC_WRITE_VERIFY = 9,
	DOS_DD_FUNC_OUTPUT_STATUS = 10,
	DOS_DD_FUNC_OUTPUT_FLUSH = 11,
	DOS_DD_FUNC_IOCTL_WRITE = 12,
	DOS_DD_FUNC_DEVICE_OPEN = 13,
	DOS_DD_FUNC_DEVICE_CLOSE = 14,
	DOS_DD_FUNC_REMOVEABLE_MEDIA = 15,
	DOS_DD_FUNC_OUTPUT_UNTIL_BUSY = 16,
	DOS_DD_FUNC_IOCTL_GENERIC = 19,
	DOS_DD_FUNC_GET_LOGICAL_DEVICE = 23,
	DOS_DD_FUNC_SET_LOGICAL_DEVICE = 24,
	DOS_DD_FUNC_IOCTL_QUERY = 25,
} DOS_DD_COMMAND;


/** Device driver (.sys) header */
typedef _Packed struct DOS_DD_HEADER
{
	void __far *nextDevice;
	uint16_t attributes;
	DOS_DD_STRATEGY *strategyCb;
	DOS_DD_INTERRUPT *interrupCb;
	char name[8];
} DOS_DD_HEADER;

typedef enum DOS_DD_ATTRIBUTES
{
	/** Character-device driver. */
	DOS_DD_CHAR = 1 << 15,
	/** Block-device driver. */
	DOS_DD_BLOCK = 0,

	/** Supports IOCTL Read/Write funcs */
	DOS_DD_SUPPORT_IOCTL_RW = 1 << 14,

	/** Support IOCTL query funcs. */
	DOS_DD_SUPPORT_IOCTL_QUERY = 1 << 7,

	// Character-device specific
	DOS_CHAR_CURRENT_STDIN_DEVICE = 1 << 0,
	DOS_CHAR_CURRENT_STDOUT_DEVICE = 1 << 1,
	DOS_CHAR_CURRENT_NUL_DEVICE = 1 << 2,
	DOS_CHAR_CURRENT_CLOCK_DEVICE = 1 << 3,
	DOS_CHAR_SPECIAL_FAST_CONSOLE_IO = 1 << 4,
	DOS_CHAR_OUTPUT_UNTIL_BUSY = 1 << 13,

	// Block-device specific
	/** The driver support 32-bit sector address. (Can use the _huge fields. ) */
	DOS_BLOCK_SUPPORT_32BIT_ADDRESSES = 1 << 1,

	/** Support Get/Set Logical Drive and generic IOCTL funcs. */
	DOS_BLOCK_SUPPORT_IOCTL_GENERIC = 1 << 6,

	/** Supports Open/Close/Removable media funcs */
	DOS_BLOCK_SUPPORT_REMOVABLE_MEDIA = 1 << 11,

	/** if set, DOS not read the 1st sector of the 1st FAT during build bpb. */
	DOS_BLOCK_FORMAT_NON_IBM = 1 << 13,
} DOS_DD_ATTRIBUTES;

// Generic IOCTLs

typedef enum DOS_IOCTL_CATEGORY
{
	DOS_IOCTL_SERIAL   = 0x1,
	DOS_IOCTL_CONSOLE  = 0x3,
	DOS_IOCTL_PARALLEL = 0x5,
	DOS_IOCTL_DISK     = 0x8,
} DOS_IOCTL_CATEGORY;

typedef enum DOS_IOCTL_MINOR
{
	DOS_IOCTL_CONSOLE_SET_ITERATION_COUNT          = 0x45,
	DOS_IOCTL_CONSOLE_SELECT_CODE_PAGE             = 0x4A,
	DOS_IOCTL_CONSOLE_START_CODE_PAGE_PREPARE      = 0x4C,
	DOS_IOCTL_CONSOLE_END_CODE_PAGE_PREPARE        = 0x4D,
	DOS_IOCTL_CONSOLE_GET_IERATION_COUNT           = 0x65,
	DOS_IOCTL_CONSOLE_QUERY_SELECTED_CODE_PAGE     = 0x6A,
	DOS_IOCTL_CONSOLE_QUERY_CODE_PAGE_PREPARE_LIST = 0x6B,

	DOS_IOCTL_DISK_SET_DEVICE_PARAMETERS           = 0x40,
	DOS_IOCTL_DISK_WRITE_TRACK_ON_LOGICAL_DEVICE   = 0x41,
	DOS_IOCTL_DISK_FORMAT_TRACK_ON_LOGICAL_DEVICE  = 0x42,
	DOS_IOCTL_DISK_SET_MEDIA_ID                    = 0x46,
	DOS_IOCTL_DISK_GET_DEVICE_PARAMETERS           = 0x60,
	DOS_IOCTL_DISK_READ_TRACK_ON_LOGICAL_DEVICE    = 0x61,
	DOS_IOCTL_DISK_VERIFY_TRACK_ON_LOGICAL_DEVICE  = 0x62,
	DOS_IOCTL_DISK_GET_MEDIA_ID                    = 0x66,
	DOS_IOCTL_DISK_SENSE_MEDIA_TYPE                = 0x68,
} DOS_IOCTL_MINOR;


// Block-device / disk data structures

typedef _Packed struct DOS_DEVICEPARAMS
{
	uint8_t specialFunctions;
	uint8_t deviceType;
	uint16_t deviceAttributes;
	uint16_t numberOfCylinders;
	uint8_t mediaType;
	DOS_BPB_DOS3 bpb;
} DOS_DEVICEPARAMS;

enum DOS_DEVICEPARAMS_SPECIAL_FUNCTIONS
{
	/** Use the device BPB for all subsequent Build BPB requests. */
	DOS_DEVICEPARAMS_USE_DEVICE_BPB = (1 << 0),
	/** Ignore all fields except the TRACKLAYOUT structure appended after DEVICEPARAMS */
	DOS_DEVICEPARAMS_TRACKLAYOUT = (1 << 1),
	/** The sectors in the track are all the same size, and sector numbers are in the range [1..N]
	 *  where N is the total number of sectors in the track. */
	DOS_DEVICEPARAMS_REGULARTRACKS = (1 << 2),
};

enum DOS_DEVICEPARAMS_DEVICE_TYPE
{
	DOS_DEVICEPARAMS_320_360K = 0x0,
	DOS_DEVICEPARAMS_1_2_MB = 0x1,
	DOS_DEVICEPARAMS_720K = 0x2,
	DOS_DEVICEPARAMS_8INCH_SD = 0x3,
	DOS_DEVICEPARAMS_8INCH_DD = 0x4,
	DOS_DEVICEPARAMS_HDD = 0x5,
	DOS_DEVICEPARAMS_TAPE = 0x6,
	DOS_DEVICEPARAMS_1_44_MB = 0x7,
	DOS_DEVICEPARAMS_OPTICAL = 0x8,
	DOS_DEVICEPARAMS_2_88_MB = 0x9
};

enum DOS_DEVICEPARAMS_DEVICE_ATTR
{
	DOS_DEVICEPARAMS_REMOVABLE    = 0,
	DOS_DEVICEPARAMS_FIXED        = 1,
	DOS_DEVICEPARAMS_HAS_DOORLOCK = 1 << 1
};

typedef _Packed struct DOS_MEDIA_ID
{
	/** Must be zero. */
	uint16_t infoLevel;
	uint32_t serialNumber;
	char volumeLabel[11];
	char fsType[8];
} DOS_MEDIA_ID;

typedef _Packed struct DOS_RWBLOCK
{
	uint8_t specialFunctions;
	uint16_t head;
	uint16_t cylinder;
	uint16_t firstSector;
	uint16_t sectors;
	void far * buffer;
} DOS_RWBLOCK;

typedef _Packed struct DOS_FVBLOCK
{
	uint8_t specialFunctions;
	uint16_t head;
	uint16_t cylinder;
} DOS_FVBLOCK;

typedef _Packed union DOS_IOCTL_DISK_DATA
{
	DOS_DEVICEPARAMS devparams;
	DOS_MEDIA_ID mid;
	DOS_FVBLOCK fv;
	DOS_RWBLOCK rw;
} DOS_IOCTL_DISK_DATA;

#endif // DOSSYS_H