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