|
|
1.1 root 1: /*
2: MS-DOS Player for Win32 console
3:
4: Author : Takeda.Toshiya
5: Date : 2009.11.09-
6: */
7:
8: #ifndef _MSDOS_H_
9: #define _MSDOS_H_
10:
11: #include <windows.h>
12: #include <winioctl.h>
13: #include <tchar.h>
14: #include <stdlib.h>
15: #include <stdio.h>
16: #include <conio.h>
17: #include <dos.h>
18: #include <fcntl.h>
19: #include <sys/types.h>
20: #include <sys/stat.h>
21: #include <io.h>
22: #include <sys/locking.h>
23: #include <mbctype.h>
24: #include <direct.h>
25: #include <errno.h>
26:
27: // variable scope of 'for' loop for microsoft visual c++ 6.0 and embedded visual c++ 4.0
28: #if (defined(_MSC_VER) && (_MSC_VER == 1200)) || defined(_WIN32_WCE)
29: #define for if(0);else for
30: #endif
31: // disable warnings C4189, C4995 and C4996 for microsoft visual c++ 2005
32: #if defined(_MSC_VER) && (_MSC_VER >= 1400)
33: #pragma warning( disable : 4819 )
34: #pragma warning( disable : 4995 )
35: #pragma warning( disable : 4996 )
36: #endif
37: // compat for mingw32 headers
38: #ifndef COMMON_LVB_UNDERSCORE
39: #define COMMON_LVB_UNDERSCORE 0x8000
40: #endif
41:
42: // type definition
43: #ifndef UINT8
44: typedef unsigned char UINT8;
45: #endif
46: #ifndef UINT16
47: typedef unsigned short UINT16;
48: #endif
49: #ifndef UINT32
50: typedef unsigned int UINT32;
51: #endif
52: #ifndef INT8
53: typedef signed char INT8;
54: #endif
55: #ifndef INT16
56: typedef signed short INT16;
57: #endif
58: #ifndef INT32
59: typedef signed int INT32;
60: #endif
61:
62: #pragma pack(1)
63: typedef union {
64: UINT32 dw;
65: struct {
66: UINT16 l, h;
67: } w;
68: } PAIR32;
69: #pragma pack()
70:
71: /* ----------------------------------------------------------------------------
72: FIFO buffer
73: ---------------------------------------------------------------------------- */
74:
75: #define MAX_FIFO 256
76:
77: class FIFO
78: {
79: private:
80: int buf[MAX_FIFO];
81: int cnt, rpt, wpt, stored[3];
82: public:
83: FIFO() {
84: cnt = rpt = wpt = 0;
85: }
86: void write(int val) {
87: if(cnt < MAX_FIFO) {
88: buf[wpt++] = val;
89: if(wpt >= MAX_FIFO) {
90: wpt = 0;
91: }
92: cnt++;
93: }
94: }
95: int read() {
96: int val = 0;
97: if(cnt) {
98: val = buf[rpt++];
99: if(rpt >= MAX_FIFO) {
100: rpt = 0;
101: }
102: cnt--;
103: }
104: return val;
105: }
106: int count() {
107: return cnt;
108: }
109: void store_buffer() {
110: stored[0] = cnt;
111: stored[1] = rpt;
112: stored[2] = wpt;
113: }
114: void restore_buffer() {
115: cnt = stored[0];
116: rpt = stored[1];
117: wpt = stored[2];
118: }
119: };
120:
121: /* ----------------------------------------------------------------------------
122: MS-DOS virtual machine
123: ---------------------------------------------------------------------------- */
124:
125: #define VECTOR_TOP 0
126: #define VECTOR_SIZE 0x400
127: #define BIOS_TOP (VECTOR_TOP + VECTOR_SIZE)
128: #define BIOS_SIZE 0x100
129: #define WORK_TOP (BIOS_TOP + BIOS_SIZE)
130: #define WORK_SIZE 0x300
131: #define IRET_TOP (WORK_TOP + WORK_SIZE)
132: #define IRET_SIZE 0x100
133: #define DOS_INFO_TOP (IRET_TOP + IRET_SIZE)
134: #define DOS_INFO_BASE (DOS_INFO_TOP + 12)
135: #define DOS_INFO_SIZE 0x100
136: #define DPB_TOP (DOS_INFO_TOP + DOS_INFO_SIZE)
137: #define DPB_SIZE 0x400
138: #define FILE_TABLE_TOP (DPB_TOP + DPB_SIZE)
139: #define FILE_TABLE_SIZE 0x10
140: #define CDS_TOP (FILE_TABLE_TOP + FILE_TABLE_SIZE)
141: #define CDS_SIZE 0x80
142: #define FCB_TABLE_TOP (CDS_TOP + CDS_SIZE)
143: #define FCB_TABLE_SIZE 0x10
144: #define DBCS_TOP (FCB_TABLE_TOP + FCB_TABLE_SIZE)
145: #define DBCS_TABLE (DBCS_TOP + 2)
146: #define DBCS_SIZE 0x10
147: #define MEMORY_TOP (DBCS_TOP + DBCS_SIZE)
148: //#define MEMORY_END 0xffff0
149: #define MEMORY_END 0xf8000
150: #define TVRAM_TOP 0xf8000
151:
152: //#define ENV_SIZE 0x800
153: #define ENV_SIZE 0x2000
154: #define PSP_SIZE 0x100
155:
156: #define MAX_FILES 128
157: #define MAX_PROCESS 16
158:
159: #define DUP_STDIN 29
160: #define DUP_STDOUT 30
161: #define DUP_STDERR 31
162:
163: //#define SUPPORT_AUX_PRN
164:
165: #pragma pack(1)
166: typedef struct {
167: UINT8 mz;
168: UINT16 psp;
169: UINT16 paragraphs;
170: } mcb_t;
171: #pragma pack()
172:
173: #pragma pack(1)
174: typedef struct {
175: UINT16 env_seg;
176: PAIR32 cmd_line;
177: PAIR32 fcb1;
178: PAIR32 fcb2;
179: UINT16 sp;
180: UINT16 ss;
181: UINT16 ip;
182: UINT16 cs;
183: } param_block_t;
184: #pragma pack()
185:
186: #pragma pack(1)
187: typedef struct {
188: UINT8 len;
189: char cmd[127];
190: } cmd_line_t;
191: #pragma pack()
192:
193: #pragma pack(1)
194: typedef struct {
195: UINT8 exit[2];
196: UINT16 first_mcb;
197: UINT8 reserved_1;
198: UINT8 far_call;
199: PAIR32 cpm_entry;
200: PAIR32 int_22h;
201: PAIR32 int_23h;
202: PAIR32 int_24h;
203: UINT16 parent_psp;
204: UINT8 file_table[20];
205: UINT16 env_seg;
206: PAIR32 stack;
207: UINT8 reserved_2[30];
208: UINT8 service[3];
209: UINT8 reserved_3[2];
210: UINT8 ex_fcb[7];
211: UINT8 fcb1[16];
212: UINT8 fcb2[20];
213: UINT8 buffer[128];
214: } psp_t;
215: #pragma pack()
216:
217: #pragma pack(1)
218: typedef struct {
219: UINT16 mz;
220: UINT16 extra_bytes;
221: UINT16 pages;
222: UINT16 relocations;
223: UINT16 header_size;
224: UINT16 min_alloc;
225: UINT16 max_alloc;
226: UINT16 init_ss;
227: UINT16 init_sp;
228: UINT16 check_sum;
229: UINT16 init_ip;
230: UINT16 init_cs;
231: UINT16 relocation_table;
232: UINT16 overlay;
233: } exe_header_t;
234: #pragma pack()
235:
236: #pragma pack(1)
237: typedef struct {
238: UINT8 flag;
239: UINT8 reserved[5];
240: UINT8 attribute;
241: } ext_fcb_t;
242: #pragma pack()
243:
244: #pragma pack(1)
245: typedef struct {
246: UINT8 drive;
247: UINT8 file_name[8 + 3];
248: UINT16 current_block;
249: UINT16 record_size;
250: UINT32 file_size;
251: UINT16 date;
252: UINT16 time;
253: UINT8 reserved[8];
254: UINT8 cur_record;
255: UINT32 rand_record;
256: } fcb_t;
257: #pragma pack()
258:
259: #pragma pack(1)
260: typedef struct {
261: UINT8 drive;
262: UINT8 file_name[8 + 3];
263: UINT8 attribute;
264: UINT8 nt_res;
265: UINT8 create_time_ms;
266: UINT16 creation_time;
267: UINT16 creation_date;
268: UINT16 last_access_date;
269: UINT16 cluster_hi;
270: UINT16 last_write_time;
271: UINT16 last_write_date;
272: UINT16 cluster_lo;
273: UINT32 file_size;
274: } find_fcb_t;
275: #pragma pack()
276:
277: #pragma pack(1)
278: typedef struct {
279: UINT8 reserved[21];
280: UINT8 attrib;
281: UINT16 time;
282: UINT16 date;
283: UINT32 size;
284: char name[13];
285: } find_t;
286: #pragma pack()
287:
288: #pragma pack(1)
289: typedef struct {
290: UINT32 attrib;
291: PAIR32 ctime_lo;
292: PAIR32 ctime_hi;
293: PAIR32 atime_lo;
294: PAIR32 atime_hi;
295: PAIR32 mtime_lo;
296: PAIR32 mtime_hi;
297: UINT32 size_hi;
298: UINT32 size_lo;
299: UINT8 reserved[8];
300: char full_name[260];
301: char short_name[14];
302: } find_lfn_t;
303: #pragma pack()
304:
305: #pragma pack(1)
306: typedef struct {
307: UINT16 info_level;
308: UINT32 serial_number;
309: char volume_label[11];
310: char file_system[8];
311: } drive_info_t;
312: #pragma pack()
313:
314: #pragma pack(1)
315: typedef struct {
316: UINT16 size_of_structure;
317: UINT16 structure_version;
318: UINT32 sectors_per_cluster;
319: UINT32 bytes_per_sector;
320: UINT32 available_clusters_on_drive;
321: UINT32 total_clusters_on_drive;
322: UINT32 available_sectors_on_drive;
323: UINT32 total_sectors_on_drive;
324: UINT32 available_allocation_units;
325: UINT32 total_allocation_units;
326: UINT8 reserved[8];
327: } ext_space_info_t;
328: #pragma pack()
329:
330: #pragma pack(1)
331: typedef struct {
332: UINT8 drive_num;
333: UINT8 unit_num;
334: UINT16 bytes_per_sector;
335: UINT8 highest_sector_num;
336: UINT8 shift_count;
337: UINT16 reserved_sectors;
338: UINT8 fat_num;
339: UINT16 root_entries;
340: UINT16 first_data_sector;
341: UINT16 highest_cluster_num;
342: UINT16 sectors_per_fat;
343: UINT16 first_dir_sector;
344: UINT32 device_driver_header;
345: UINT8 media_type;
346: UINT8 drive_accessed;
347: UINT16 next_dpb_ofs;
348: UINT16 next_dpb_seg;
349: UINT16 first_free_cluster;
350: UINT16 free_clusters;
351: } dpb_t;
352: #pragma pack()
353:
354: #pragma pack(1)
355: typedef struct {
356: char path_name[67];
357: UINT16 drive_attrib;
358: UINT8 physical_drive_number;
359: } cds_t;
360: #pragma pack()
361:
362: #pragma pack(1)
363: typedef struct {
364: UINT8 reserved_1[10];
365: UINT16 first_mcb; // -2
366: PAIR32 first_dpb; // +0
367: PAIR32 first_sft; // +0
368: UINT8 reserved_2[14];
369: PAIR32 cds; // +22
370: PAIR32 fcb_table; // +26
371: UINT8 reserved_3[3];
372: UINT8 last_drive; // +33
373: UINT8 reserved_4[29];
374: UINT16 buffers_x; // +63
375: UINT16 buffers_y; // +65
376: UINT8 boot_drive; // +67
377: UINT8 i386_or_later; // +68
378: UINT16 ext_mem_size; // +69
379: } dos_info_t;
380: #pragma pack()
381:
382: typedef struct {
383: char path[MAX_PATH];
384: int valid;
385: int id;
386: int atty;
387: int mode;
388: UINT16 info;
389: UINT16 psp;
390: } file_handler_t;
391:
392: static const struct {
393: int mode;
394: int in;
395: int out;
396: } file_mode[] = {
397: { _O_RDONLY | _O_BINARY, 1, 0 },
398: { _O_WRONLY | _O_BINARY, 0, 1 },
399: { _O_RDWR | _O_BINARY, 1, 1 },
400: };
401:
402: typedef struct {
403: UINT16 psp;
404: char module_dir[MAX_PATH];
405: PAIR32 dta;
406: UINT8 switchar;
407: UINT8 verify;
408: int max_files;
409: HANDLE find_handle;
410: UINT8 allowable_mask;
411: UINT8 required_mask;
412: char volume_label[MAX_PATH];
413: bool parent_int_10h_feh_called;
414: bool parent_int_10h_ffh_called;
415: } process_t;
416:
417: UINT16 current_psp;
418:
419: int retval = 0;
420: UINT16 error_code = 0;
421:
422: file_handler_t file_handler[MAX_FILES];
423: UINT8 file_buffer[0x100000];
424:
425: process_t process[MAX_PROCESS];
426:
427: void msdos_syscall(unsigned num);
428: int msdos_init(int argc, char *argv[], char *envp[], int standard_env);
429: void msdos_finish();
430:
431: // console
432:
433: #define SCR_BUF_SIZE 1200
434:
435: #define SET_RECT(rect, l, t, r, b) { \
436: rect.Left = l; \
437: rect.Top = t; \
438: rect.Right = r; \
439: rect.Bottom = b; \
440: }
441:
442: HANDLE hStdin;
443: HANDLE hStdout;
444: CHAR_INFO scr_buf[SCR_BUF_SIZE][80];
445: char scr_char[80 * 25];
446: WORD scr_attr[80 * 25];
447: COORD scr_buf_size;
448: COORD scr_buf_pos;
449: int scr_width, scr_height;
450: bool cursor_moved;
451:
452: FIFO *key_buf_char;
453: FIFO *key_buf_scan;
454:
455: int active_code_page;
456: int system_code_page;
457:
458: UINT32 tvram_base_address = TVRAM_TOP;
459: bool int_10h_feh_called = false;
460: bool int_10h_ffh_called = false;
461:
462: /* ----------------------------------------------------------------------------
463: PC/AT hardware emulation
464: ---------------------------------------------------------------------------- */
465:
466: #define SUPPORT_HARDWARE
467:
468: void hardware_init();
469: void hardware_finish();
470: void hardware_run();
471: #ifdef SUPPORT_HARDWARE
472: void hardware_update();
473: #endif
474:
475: // memory
476:
477: #define MAX_MEM 0x1000000
478: UINT8 mem[MAX_MEM];
479:
480: // cmos
481:
482: UINT8 cmos[128];
483: UINT8 cmos_addr;
484:
485: // pic
486:
487: typedef struct {
488: UINT8 imr, isr, irr, prio;
489: UINT8 icw1, icw2, icw3, icw4;
490: UINT8 ocw3;
491: UINT8 icw2_r, icw3_r, icw4_r;
492: } pic_t;
493:
494: pic_t pic[2];
495: int pic_req_chip, pic_req_level;
496: UINT8 pic_req_bit;
497:
498: void pic_init();
499: void pic_write(int c, UINT32 addr, UINT8 data);
500: UINT8 pic_read(int c, UINT32 addr);
501: void pic_req(int c, int level, int signal);
502: int pic_ack();
503: void pic_update();
504:
505: // pit
506:
507: typedef struct {
508: int prev_out;
509: //int gate;
510: INT32 count;
511: UINT16 latch;
512: UINT16 count_reg;
513: UINT8 ctrl_reg;
514: int count_latched;
515: int low_read, high_read;
516: int low_write, high_write;
517: int mode;
518: int delay;
519: int start;
520: int null_count;
521: int status_latched;
522: UINT8 status;
523: // constant clock
524: UINT32 input_clk;
525: UINT32 expired_time;
526: UINT32 prev_time;
527: } pit_t;
528:
529: pit_t pit[3];
530: int pit_active;
531:
532: void pit_init();
533: void pit_write(int ch, UINT8 val);
534: UINT8 pit_read(int ch);
535: void pit_run();
536: void pit_input_clock(int ch, int clock);
537: void pit_start_count(int ch);
538: void pit_stop_count(int ch);
539: void pit_latch_count(int ch);
540: void pit_set_signal(int ch, int signal);
541: int pit_get_next_count(int ch);
542: int pit_get_expired_time(int clock);
543:
544: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.