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