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