|
|
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>
1.1.1.13 root 17: #include <stddef.h>
1.1 root 18: #include <stdlib.h>
19: #include <stdio.h>
1.1.1.2 root 20: #include <assert.h>
1.1 root 21: #include <conio.h>
1.1.1.2 root 22: #include <math.h>
1.1 root 23: #include <dos.h>
24: #include <fcntl.h>
25: #include <sys/types.h>
26: #include <sys/stat.h>
27: #include <io.h>
28: #include <sys/locking.h>
29: #include <mbctype.h>
30: #include <direct.h>
31: #include <errno.h>
1.1.1.9 root 32: #include <tlhelp32.h>
33: #include <psapi.h>
1.1.1.20 root 34: #include <setupapi.h>
1.1 root 35:
1.1.1.15 root 36: #ifdef _DEBUG
37: #define _CRTDBG_MAP_ALLOC
38: #include <crtdbg.h>
39: #define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__)
40: #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
41: #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
42: #endif
43:
1.1.1.9 root 44: // variable scope of 'for' loop for Microsoft Visual C++ 6.0
45: #if defined(_MSC_VER) && (_MSC_VER == 1200)
1.1 root 46: #define for if(0);else for
47: #endif
1.1.1.9 root 48:
49: // disable warnings for Microsoft Visual C++ 2005 or later
1.1 root 50: #if defined(_MSC_VER) && (_MSC_VER >= 1400)
51: #pragma warning( disable : 4819 )
52: #pragma warning( disable : 4995 )
53: #pragma warning( disable : 4996 )
1.1.1.9 root 54: // for MAME i86/i386
55: #pragma warning( disable : 4018 )
56: #pragma warning( disable : 4065 )
57: #pragma warning( disable : 4146 )
58: #pragma warning( disable : 4244 )
59: #pragma warning( disable : 4267 )
60: #endif
61:
62: // endian
63: #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
64: #if defined(__BYTE_ORDER) && (defined(__LITTLE_ENDIAN) || defined(__BIG_ENDIAN))
65: #if __BYTE_ORDER == __LITTLE_ENDIAN
66: #define __LITTLE_ENDIAN__
67: #elif __BYTE_ORDER == __BIG_ENDIAN
68: #define __BIG_ENDIAN__
69: #endif
70: #elif defined(WORDS_LITTLEENDIAN)
71: #define __LITTLE_ENDIAN__
72: #elif defined(WORDS_BIGENDIAN)
73: #define __BIG_ENDIAN__
74: #endif
75: #endif
76: #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
77: // Microsoft Visual C++
78: #define __LITTLE_ENDIAN__
1.1 root 79: #endif
1.1.1.9 root 80:
1.1 root 81: // compat for mingw32 headers
82: #ifndef COMMON_LVB_UNDERSCORE
83: #define COMMON_LVB_UNDERSCORE 0x8000
84: #endif
85:
86: // type definition
87: #ifndef UINT8
88: typedef unsigned char UINT8;
89: #endif
90: #ifndef UINT16
91: typedef unsigned short UINT16;
92: #endif
93: #ifndef UINT32
94: typedef unsigned int UINT32;
95: #endif
96: #ifndef INT8
97: typedef signed char INT8;
98: #endif
99: #ifndef INT16
100: typedef signed short INT16;
101: #endif
102: #ifndef INT32
103: typedef signed int INT32;
104: #endif
105:
106: #pragma pack(1)
107: typedef union {
108: UINT32 dw;
109: struct {
1.1.1.9 root 110: #ifdef __BIG_ENDIAN__
111: UINT16 h, l;
112: #else
1.1 root 113: UINT16 l, h;
1.1.1.9 root 114: #endif
1.1 root 115: } w;
116: } PAIR32;
117: #pragma pack()
118:
119: /* ----------------------------------------------------------------------------
120: FIFO buffer
121: ---------------------------------------------------------------------------- */
122:
123: class FIFO
124: {
125: private:
1.1.1.20 root 126: int size;
127: int *buf;
1.1 root 128: int cnt, rpt, wpt, stored[3];
129: public:
1.1.1.20 root 130: FIFO(int s) {
131: size = s;
132: buf = (int *)malloc(size * sizeof(int));
1.1 root 133: cnt = rpt = wpt = 0;
134: }
1.1.1.20 root 135: void release()
136: {
137: free(buf);
138: }
1.1 root 139: void write(int val) {
1.1.1.20 root 140: if(cnt < size) {
1.1 root 141: buf[wpt++] = val;
1.1.1.20 root 142: if(wpt >= size) {
1.1 root 143: wpt = 0;
144: }
145: cnt++;
146: }
147: }
148: int read() {
149: int val = 0;
150: if(cnt) {
151: val = buf[rpt++];
1.1.1.20 root 152: if(rpt >= size) {
1.1 root 153: rpt = 0;
154: }
155: cnt--;
156: }
1.1.1.20 root 157: return(val);
1.1 root 158: }
159: int count() {
1.1.1.20 root 160: return(cnt);
161: }
162: int remain() {
163: return(size - cnt);
164: }
165: bool full()
166: {
167: return(cnt == size);
168: }
169: bool empty()
170: {
171: return(cnt == 0);
1.1 root 172: }
173: void store_buffer() {
174: stored[0] = cnt;
175: stored[1] = rpt;
176: stored[2] = wpt;
177: }
178: void restore_buffer() {
179: cnt = stored[0];
180: rpt = stored[1];
181: wpt = stored[2];
182: }
183: };
184:
185: /* ----------------------------------------------------------------------------
1.1.1.14 root 186: MAME i86/i386
187: ---------------------------------------------------------------------------- */
188:
189: #if defined(HAS_I86)
190: #define CPU_MODEL i8086
191: #elif defined(HAS_I186)
192: #define CPU_MODEL i80186
193: #elif defined(HAS_V30)
194: #define CPU_MODEL v30
195: #elif defined(HAS_I286)
196: #define CPU_MODEL i80286
197: #elif defined(HAS_I386)
198: #define CPU_MODEL i386
199: #else
200: // #if defined(HAS_I386SX)
201: // #define CPU_MODEL i386SX
202: // #else
203: #if defined(HAS_I486)
204: #define CPU_MODEL i486
205: #else
206: #if defined(HAS_PENTIUM)
207: #define CPU_MODEL pentium
208: #elif defined(HAS_MEDIAGX)
209: #define CPU_MODEL mediagx
210: #elif defined(HAS_PENTIUM_PRO)
211: #define CPU_MODEL pentium_pro
212: #elif defined(HAS_PENTIUM_MMX)
213: #define CPU_MODEL pentium_mmx
214: #elif defined(HAS_PENTIUM2)
215: #define CPU_MODEL pentium2
216: #elif defined(HAS_PENTIUM3)
217: #define CPU_MODEL pentium3
218: #elif defined(HAS_PENTIUM4)
219: #define CPU_MODEL pentium4
220: #endif
221: #define SUPPORT_RDTSC
222: #endif
223: #define SUPPORT_FPU
224: // #endif
225: #define HAS_I386
226: #endif
227:
228: /* ----------------------------------------------------------------------------
229: PC/AT hardware emulation
230: ---------------------------------------------------------------------------- */
231:
1.1.1.22 root 232: //#define SUPPORT_GRAPHIC_SCREEN
233:
1.1.1.14 root 234: void hardware_init();
235: void hardware_finish();
1.1.1.22 root 236: void hardware_release();
1.1.1.14 root 237: void hardware_run();
238: void hardware_update();
239:
240: // memory
241:
242: #if defined(HAS_I386)
243: #define MAX_MEM 0x2000000 /* 32MB */
244: #elif defined(HAS_I286)
245: #define MAX_MEM 0x1000000 /* 16MB */
246: #else
247: #define MAX_MEM 0x100000 /* 1MB */
248: #endif
249: UINT8 mem[MAX_MEM + 3];
250:
251: // ems
252:
253: #define MAX_EMS_HANDLES 16
254: #define MAX_EMS_PAGES 2048 /* 32MB */
255:
1.1.1.21 root 256: typedef struct {
1.1.1.14 root 257: char name[8];
258: UINT8* buffer;
259: int pages;
260: bool allocated;
1.1.1.21 root 261: } ems_handle_t;
1.1.1.14 root 262:
1.1.1.21 root 263: typedef struct {
1.1.1.14 root 264: UINT16 handle;
265: UINT16 page;
266: bool mapped;
1.1.1.21 root 267: } ems_page_t;
1.1.1.14 root 268:
1.1.1.22 root 269: ems_handle_t ems_handles[MAX_EMS_HANDLES] = {0};
1.1.1.21 root 270: ems_page_t ems_pages[4];
1.1.1.14 root 271: int free_ems_pages;
272:
273: void ems_init();
274: void ems_finish();
1.1.1.22 root 275: void ems_release();
1.1.1.14 root 276: void ems_allocate_pages(int handle, int pages);
277: void ems_reallocate_pages(int handle, int pages);
278: void ems_release_pages(int handle);
279: void ems_map_page(int physical, int handle, int logical);
280: void ems_unmap_page(int physical);
281:
1.1.1.20 root 282: // dma
283:
284: typedef struct {
285: struct {
286: union {
287: UINT16 w;
288: struct {
289: #ifdef __BIG_ENDIAN__
290: UINT8 h, l;
291: #else
292: UINT8 l, h;
293: #endif
294: } b;
295: } areg, creg, bareg, bcreg;
296: UINT8 mode;
297: UINT8 pagereg;
298: UINT32 port;
299: } ch[4];
300:
301: bool low_high;
302: UINT8 cmd;
303: UINT8 req;
304: UINT8 mask;
305: UINT8 tc;
306: UINT16 tmp;
307: } dma_t;
308:
1.1.1.21 root 309: dma_t dma[2];
1.1.1.20 root 310:
311: void dma_init();
312: void dma_reset(int c);
313: void dma_write(int c, UINT32 addr, UINT8 data);
314: UINT8 dma_read(int c, UINT32 addr);
315: void dma_page_write(int c, int ch, UINT8 data);
316: UINT8 dma_page_read(int c, int ch);
317: void dma_run(int c, int ch);
318:
1.1.1.14 root 319: // pic
320:
321: typedef struct {
322: UINT8 imr, isr, irr, prio;
323: UINT8 icw1, icw2, icw3, icw4;
324: UINT8 ocw3;
325: UINT8 icw2_r, icw3_r, icw4_r;
326: } pic_t;
327:
328: pic_t pic[2];
329: int pic_req_chip, pic_req_level;
330: UINT8 pic_req_bit;
331:
332: void pic_init();
333: void pic_write(int c, UINT32 addr, UINT8 data);
334: UINT8 pic_read(int c, UINT32 addr);
335: void pic_req(int c, int level, int signal);
336: int pic_ack();
337: void pic_update();
338:
1.1.1.20 root 339: // pio
340:
341: typedef struct {
342: UINT8 data, stat, ctrl;
343: } pio_t;
344:
1.1.1.21 root 345: pio_t pio[2];
1.1.1.20 root 346:
347: void pio_init();
348: void pio_write(int c, UINT32 addr, UINT8 data);
349: UINT8 pio_read(int c, UINT32 addr);
350:
1.1.1.14 root 351: // pit
352:
353: #define PIT_ALWAYS_RUNNING
354:
355: typedef struct {
356: INT32 count;
357: UINT16 latch;
1.1.1.21 root 358: UINT16 prev_latch, next_latch;
1.1.1.14 root 359: UINT16 count_reg;
360: UINT8 ctrl_reg;
361: int count_latched;
362: int low_read, high_read;
363: int low_write, high_write;
364: int mode;
365: int status_latched;
366: UINT8 status;
367: // constant clock
368: UINT32 expired_time;
369: UINT32 prev_time;
1.1.1.17 root 370: UINT64 accum;
1.1.1.14 root 371: } pit_t;
372:
373: pit_t pit[3];
374: #ifndef PIT_ALWAYS_RUNNING
375: int pit_active;
376: #endif
377:
378: void pit_init();
379: void pit_write(int ch, UINT8 val);
380: UINT8 pit_read(int ch);
381: int pit_run(int ch, UINT32 cur_time);
382: void pit_latch_count(int ch);
383: int pit_get_expired_time(int ch);
384:
385: UINT8 system_port = 0;
386:
1.1.1.20 root 387: // sio
388:
389: #define SIO_BUFFER_SIZE 1024
390:
391: typedef struct {
392: int channel;
393:
394: FIFO *send_buffer;
395: FIFO *recv_buffer;
396:
397: union {
398: UINT16 w;
399: struct {
400: #ifdef __BIG_ENDIAN__
401: UINT8 h, l;
402: #else
403: UINT8 l, h;
404: #endif
405: } b;
406: } divisor;
407: UINT16 prev_divisor;
408: UINT8 line_ctrl, prev_line_ctrl;
409: UINT8 selector;
410:
411: UINT8 modem_ctrl;
1.1.1.21 root 412: bool set_brk, set_rts, set_dtr;
413: bool prev_set_brk;
414: // bool prev_set_rts, prev_set_dtr;
1.1.1.20 root 415:
416: UINT8 line_stat_buf, line_stat_err;
417: UINT8 modem_stat, prev_modem_stat;
418:
419: UINT8 irq_enable;
420: UINT8 irq_identify;
421:
422: UINT8 scratch;
423: } sio_t;
424:
425: typedef struct {
426: HANDLE hThread;
427: CRITICAL_SECTION csSendData;
428: CRITICAL_SECTION csRecvData;
429: CRITICAL_SECTION csLineCtrl;
430: CRITICAL_SECTION csLineStat;
431: CRITICAL_SECTION csModemCtrl;
432: CRITICAL_SECTION csModemStat;
433: } sio_mt_t;
434:
1.1.1.23! root 435: sio_t sio[4] = {0};
! 436: sio_mt_t sio_mt[4];
1.1.1.20 root 437:
438: void sio_init();
439: void sio_finish();
1.1.1.22 root 440: void sio_release();
1.1.1.20 root 441: void sio_write(int c, UINT32 addr, UINT8 data);
442: UINT8 sio_read(int c, UINT32 addr);
443: void sio_update(int c);
444: void sio_update_irq(int c);
445: DWORD WINAPI sio_thread(void *lpx);
446:
1.1.1.14 root 447: // cmos
448:
449: UINT8 cmos[128];
450: UINT8 cmos_addr;
451:
452: void cmos_init();
453: void cmos_write(int addr, UINT8 val);
454: UINT8 cmos_read(int addr);
455:
456: // kbd (a20)
457:
458: UINT8 kbd_data;
459: UINT8 kbd_status;
460: UINT8 kbd_command;
461:
462: void kbd_init();
463: UINT8 kbd_read_data();
464: void kbd_write_data(UINT8 val);
465: UINT8 kbd_read_status();
466: void kbd_write_command(UINT8 val);
467:
468: /* ----------------------------------------------------------------------------
1.1 root 469: MS-DOS virtual machine
470: ---------------------------------------------------------------------------- */
471:
1.1.1.23! root 472: #if defined(HAS_I286) || defined(HAS_I386)
! 473: #define SUPPORT_XMS
! 474: //#define SUPPORT_HMA
! 475: #endif
! 476:
1.1 root 477: #define VECTOR_TOP 0
478: #define VECTOR_SIZE 0x400
479: #define BIOS_TOP (VECTOR_TOP + VECTOR_SIZE)
480: #define BIOS_SIZE 0x100
481: #define WORK_TOP (BIOS_TOP + BIOS_SIZE)
1.1.1.14 root 482: #define WORK_SIZE 0x200
1.1.1.20 root 483: // IO.SYS 0070:0000
484: #define DEVICE_TOP (WORK_TOP + WORK_SIZE)
1.1.1.21 root 485: #define DEVICE_SIZE 0x100 /* 22 + 18 * 12 + 7 */
1.1.1.20 root 486: #define DOS_INFO_TOP (DEVICE_TOP + DEVICE_SIZE)
1.1 root 487: #define DOS_INFO_SIZE 0x100
1.1.1.20 root 488: #define EXT_BIOS_TOP (DOS_INFO_TOP + DOS_INFO_SIZE)
489: #define EXT_BIOS_SIZE 0x400
490: #define DPB_TOP (EXT_BIOS_TOP + EXT_BIOS_SIZE)
1.1 root 491: #define DPB_SIZE 0x400
1.1.1.16 root 492: #define SFT_TOP (DPB_TOP + DPB_SIZE)
493: #define SFT_SIZE 0x4b0 /* 6 + 0x3b * 20 */
494: #define DISK_BUF_TOP (SFT_TOP + SFT_SIZE)
1.1.1.14 root 495: #define DISK_BUF_SIZE 0x20
496: #define CDS_TOP (DISK_BUF_TOP + DISK_BUF_SIZE)
1.1 root 497: #define CDS_SIZE 0x80
498: #define FCB_TABLE_TOP (CDS_TOP + CDS_SIZE)
499: #define FCB_TABLE_SIZE 0x10
1.1.1.17 root 500: #define ERR_TABLE_TOP (FCB_TABLE_TOP + FCB_TABLE_SIZE)
501: #define ERR_TABLE_SIZE 0x10
1.1.1.18 root 502: #define SDA_TOP (ERR_TABLE_TOP + ERR_TABLE_SIZE)
503: #define SDA_SIZE 0xb0
1.1.1.13 root 504: // nls tables
1.1.1.18 root 505: #define UPPERTABLE_TOP (SDA_TOP + SDA_SIZE)
1.1.1.13 root 506: #define UPPERTABLE_SIZE 0x82
1.1.1.18 root 507: #define LOWERTABLE_TOP (UPPERTABLE_TOP + UPPERTABLE_SIZE)
508: #define LOWERTABLE_SIZE 0x82
509: #define FILENAME_UPPERTABLE_TOP (LOWERTABLE_TOP + LOWERTABLE_SIZE)
1.1.1.13 root 510: #define FILENAME_UPPERTABLE_SIZE 0x82
511: #define FILENAME_TERMINATOR_TOP (FILENAME_UPPERTABLE_TOP + FILENAME_UPPERTABLE_SIZE)
512: #define FILENAME_TERMINATOR_SIZE 0x20 /* requirement: 10 + 14(terminate chars) */
513: #define COLLATING_TABLE_TOP (FILENAME_TERMINATOR_TOP + FILENAME_TERMINATOR_SIZE)
514: #define COLLATING_TABLE_SIZE 0x102
515: #define DBCS_TOP (COLLATING_TABLE_TOP + COLLATING_TABLE_SIZE)
1.1 root 516: #define DBCS_TABLE (DBCS_TOP + 2)
517: #define DBCS_SIZE 0x10
1.1.1.13 root 518: #define MSDOS_SYSTEM_DATA_END (DBCS_TOP + DBCS_SIZE)
519: #define MEMORY_TOP ((MSDOS_SYSTEM_DATA_END + 15) & ~15U)
1.1.1.22 root 520: #ifdef SUPPORT_GRAPHIC_SCREEN
521: #define MEMORY_END 0xa0000
522: #define VGA_VRAM_TOP 0xa0000
523: #else
1.1.1.7 root 524: #define MEMORY_END 0xb8000
1.1.1.22 root 525: #endif
1.1.1.7 root 526: #define TEXT_VRAM_TOP 0xb8000
1.1.1.14 root 527: #define EMS_TOP 0xc0000
528: #define EMS_SIZE 0x10000
529: UINT32 UMB_TOP = EMS_TOP; // EMS is disabled
1.1.1.7 root 530: #define UMB_END 0xf8000
531: #define SHADOW_BUF_TOP 0xf8000
1.1.1.14 root 532: #define EMB_TOP 0x10fff0
533: #define EMB_END MAX_MEM
534:
535: UINT32 IRET_TOP = 0;
536: #define IRET_SIZE 0x100
537: UINT32 XMS_TOP = 0;
1.1.1.23! root 538: #define XMS_SIZE 0x20 /* 18 + 6 + 7 */
1.1 root 539:
540: //#define ENV_SIZE 0x800
541: #define ENV_SIZE 0x2000
542: #define PSP_SIZE 0x100
543:
544: #define MAX_FILES 128
545: #define MAX_PROCESS 16
1.1.1.12 root 546: #define MAX_DTAINFO 128
1.1.1.11 root 547: #define LFN_DTA_LADDR 0x10FFF0
1.1.1.12 root 548: #define FIND_MAGIC 0x46696e64
1.1 root 549:
1.1.1.16 root 550: #define DUP_STDIN 27
551: #define DUP_STDOUT 28
552: #define DUP_STDERR 29
553: #define DUP_STDAUX 30
554: #define DUP_STDPRN 31
1.1 root 555:
1.1.1.16 root 556: //#define MAP_AUX_DEVICE_TO_FILE
557: //#define MAP_PRN_DEVICE_TO_FILE
1.1 root 558:
559: #pragma pack(1)
560: typedef struct {
561: UINT8 mz;
562: UINT16 psp;
1.1.1.14 root 563: union {
564: UINT8 reserved[5];
565: UINT16 paragraphs16;
566: UINT32 paragraphs32;
567: };
1.1.1.3 root 568: char prog_name[8];
1.1.1.14 root 569: // use 32bit paragraphs for emb
570: UINT32 paragraphs()
571: {
572: UINT32 offset = &(this->mz) - mem;
573: return (offset >= EMB_TOP) ? paragraphs32 : paragraphs16;
574: }
575: UINT32 size_kb()
576: {
577: return paragraphs() >> 6;
578: }
1.1 root 579: } mcb_t;
580: #pragma pack()
581:
1.1.1.23! root 582: #ifdef SUPPORT_HMA
! 583: #pragma pack(1)
! 584: typedef struct {
! 585: UINT8 ms[2];
! 586: UINT16 owner;
! 587: UINT16 size;
! 588: UINT16 next;
! 589: } hma_mcb_t;
! 590: #pragma pack()
! 591: #endif
! 592:
1.1 root 593: #pragma pack(1)
594: typedef struct {
595: UINT16 env_seg;
596: PAIR32 cmd_line;
597: PAIR32 fcb1;
598: PAIR32 fcb2;
599: UINT16 sp;
600: UINT16 ss;
601: UINT16 ip;
602: UINT16 cs;
603: } param_block_t;
604: #pragma pack()
605:
606: #pragma pack(1)
607: typedef struct {
608: UINT8 len;
609: char cmd[127];
610: } cmd_line_t;
611: #pragma pack()
612:
613: #pragma pack(1)
614: typedef struct {
615: UINT8 exit[2];
616: UINT16 first_mcb;
617: UINT8 reserved_1;
618: UINT8 far_call;
619: PAIR32 cpm_entry;
620: PAIR32 int_22h;
621: PAIR32 int_23h;
622: PAIR32 int_24h;
623: UINT16 parent_psp;
624: UINT8 file_table[20];
625: UINT16 env_seg;
626: PAIR32 stack;
1.1.1.12 root 627: UINT16 file_table_size;
628: PAIR32 file_table_ptr;
629: UINT8 reserved_2[24];
1.1 root 630: UINT8 service[3];
631: UINT8 reserved_3[2];
632: UINT8 ex_fcb[7];
633: UINT8 fcb1[16];
634: UINT8 fcb2[20];
635: UINT8 buffer[128];
636: } psp_t;
637: #pragma pack()
638:
639: #pragma pack(1)
640: typedef struct {
641: UINT16 mz;
642: UINT16 extra_bytes;
643: UINT16 pages;
644: UINT16 relocations;
645: UINT16 header_size;
646: UINT16 min_alloc;
647: UINT16 max_alloc;
648: UINT16 init_ss;
649: UINT16 init_sp;
650: UINT16 check_sum;
651: UINT16 init_ip;
652: UINT16 init_cs;
653: UINT16 relocation_table;
654: UINT16 overlay;
655: } exe_header_t;
656: #pragma pack()
657:
658: #pragma pack(1)
659: typedef struct {
660: UINT8 flag;
661: UINT8 reserved[5];
662: UINT8 attribute;
663: } ext_fcb_t;
664: #pragma pack()
665:
666: #pragma pack(1)
667: typedef struct {
668: UINT8 drive;
669: UINT8 file_name[8 + 3];
670: UINT16 current_block;
671: UINT16 record_size;
672: UINT32 file_size;
673: UINT16 date;
674: UINT16 time;
1.1.1.12 root 675: union {
676: UINT8 reserved[8];
677: HANDLE handle;
678: };
1.1 root 679: UINT8 cur_record;
680: UINT32 rand_record;
681: } fcb_t;
682: #pragma pack()
683:
684: #pragma pack(1)
685: typedef struct {
686: UINT8 drive;
687: UINT8 file_name[8 + 3];
688: UINT8 attribute;
689: UINT8 nt_res;
690: UINT8 create_time_ms;
691: UINT16 creation_time;
692: UINT16 creation_date;
693: UINT16 last_access_date;
694: UINT16 cluster_hi;
695: UINT16 last_write_time;
696: UINT16 last_write_date;
697: UINT16 cluster_lo;
698: UINT32 file_size;
699: } find_fcb_t;
700: #pragma pack()
701:
702: #pragma pack(1)
703: typedef struct {
1.1.1.12 root 704: union {
705: UINT8 reserved[21];
706: struct {
707: UINT32 find_magic;
708: UINT32 dta_index;
709: };
710: };
1.1 root 711: UINT8 attrib;
712: UINT16 time;
713: UINT16 date;
714: UINT32 size;
715: char name[13];
716: } find_t;
717: #pragma pack()
718:
719: #pragma pack(1)
720: typedef struct {
721: UINT32 attrib;
722: PAIR32 ctime_lo;
723: PAIR32 ctime_hi;
724: PAIR32 atime_lo;
725: PAIR32 atime_hi;
726: PAIR32 mtime_lo;
727: PAIR32 mtime_hi;
728: UINT32 size_hi;
729: UINT32 size_lo;
730: UINT8 reserved[8];
731: char full_name[260];
732: char short_name[14];
733: } find_lfn_t;
734: #pragma pack()
735:
736: #pragma pack(1)
737: typedef struct {
738: UINT16 info_level;
739: UINT32 serial_number;
740: char volume_label[11];
741: char file_system[8];
742: } drive_info_t;
743: #pragma pack()
744:
745: #pragma pack(1)
746: typedef struct {
747: UINT16 size_of_structure;
748: UINT16 structure_version;
749: UINT32 sectors_per_cluster;
750: UINT32 bytes_per_sector;
751: UINT32 available_clusters_on_drive;
752: UINT32 total_clusters_on_drive;
753: UINT32 available_sectors_on_drive;
754: UINT32 total_sectors_on_drive;
755: UINT32 available_allocation_units;
756: UINT32 total_allocation_units;
757: UINT8 reserved[8];
758: } ext_space_info_t;
759: #pragma pack()
760:
761: #pragma pack(1)
762: typedef struct {
763: UINT8 drive_num;
764: UINT8 unit_num;
765: UINT16 bytes_per_sector;
766: UINT8 highest_sector_num;
767: UINT8 shift_count;
768: UINT16 reserved_sectors;
769: UINT8 fat_num;
770: UINT16 root_entries;
771: UINT16 first_data_sector;
772: UINT16 highest_cluster_num;
773: UINT16 sectors_per_fat;
774: UINT16 first_dir_sector;
775: UINT32 device_driver_header;
776: UINT8 media_type;
777: UINT8 drive_accessed;
778: UINT16 next_dpb_ofs;
779: UINT16 next_dpb_seg;
780: UINT16 first_free_cluster;
781: UINT16 free_clusters;
1.1.1.12 root 782: // extended
783: UINT16 fat_mirroring;
784: UINT16 info_sector;
785: UINT16 backup_boot_sector;
786: UINT32 first_cluster_sector;
787: UINT32 maximum_cluster_num;
788: UINT32 fat_sectors;
789: UINT32 root_cluster;
790: UINT32 free_search_cluster;
1.1 root 791: } dpb_t;
792: #pragma pack()
793:
794: #pragma pack(1)
795: typedef struct {
796: char path_name[67];
797: UINT16 drive_attrib;
798: UINT8 physical_drive_number;
799: } cds_t;
800: #pragma pack()
801:
802: #pragma pack(1)
803: typedef struct {
1.1.1.18 root 804: UINT8 reserved_1[3]; // -34
805: UINT8 switchar; // -31 current switch character
806: UINT8 malloc_strategy; // -30 current memory allocation strategy
807: UINT8 reserved_2[29]; // -29
808: // ----- from DOSBox -----
809: UINT8 crit_error_flag; // 0x00 Critical Error Flag
810: UINT8 indos_flag; // 0x01 InDOS flag (count of active INT 21 calls)
811: UINT8 drive_crit_error; // 0x02 Drive on which current critical error occurred or FFh
812: UINT8 locus_of_last_error; // 0x03 locus of last error
813: UINT16 extended_error_code; // 0x04 extended error code of last error
814: UINT8 suggested_action; // 0x06 suggested action for last error
815: UINT8 error_class; // 0x07 class of last error
816: PAIR32 last_error_pointer; // 0x08 ES:DI pointer for last error
817: PAIR32 current_dta; // 0x0C current DTA (Disk Transfer Address)
818: UINT16 current_psp; // 0x10 current PSP
819: UINT16 sp_int_23; // 0x12 stores SP across an INT 23
820: UINT16 return_code; // 0x14 return code from last process termination (zerod after reading with AH=4Dh)
821: UINT8 current_drive; // 0x16 current drive
822: UINT8 extended_break_flag; // 0x17 extended break flag
823: UINT8 fill[2]; // 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort
824: } sda_t;
825: #pragma pack()
826:
827: #pragma pack(1)
828: typedef struct {
1.1.1.14 root 829: UINT8 reserved_0[4]; // -38
830: UINT16 magic_word; // -34 from DOSBox
831: UINT8 reserved_1[30]; // -32
1.1 root 832: UINT16 first_mcb; // -2
833: PAIR32 first_dpb; // +0
1.1.1.14 root 834: PAIR32 first_sft; // +4
1.1.1.20 root 835: PAIR32 clock_device; // +8
836: PAIR32 con_device; // +12
1.1.1.14 root 837: UINT16 max_sector_len; // +16
838: PAIR32 disk_buf_info; // +18 from DOSBox
1.1 root 839: PAIR32 cds; // +22
840: PAIR32 fcb_table; // +26
1.1.1.20 root 841: UINT8 reserved_2[3]; // +30
1.1 root 842: UINT8 last_drive; // +33
1.1.1.14 root 843: struct {
1.1.1.20 root 844: PAIR32 next_driver; // +34
1.1.1.14 root 845: UINT16 attributes; // +38
846: UINT16 strategy; // +40
847: UINT16 interrupt; // +42
848: char dev_name[8]; // +44
849: } nul_device;
1.1.1.20 root 850: UINT8 reserved_3[11]; // +52
1.1 root 851: UINT16 buffers_x; // +63
852: UINT16 buffers_y; // +65
853: UINT8 boot_drive; // +67
854: UINT8 i386_or_later; // +68
855: UINT16 ext_mem_size; // +69
1.1.1.14 root 856: PAIR32 disk_buf_heads; // +71 from DOSBox
1.1.1.20 root 857: UINT8 reserved_4[21]; // +75
1.1.1.5 root 858: UINT8 dos_flag; // +96
1.1.1.20 root 859: UINT8 reserved_5[2]; // +97
1.1.1.15 root 860: UINT8 umb_linked; // +99 from DOSBox
1.1.1.20 root 861: UINT8 reserved_6[2]; // +100
1.1.1.15 root 862: UINT16 first_umb_fcb; // +102 from DOSBox
863: UINT16 first_mcb_2; // +104 from DOSBox
1.1.1.21 root 864: UINT8 nul_device_routine[7];
1.1 root 865: } dos_info_t;
866: #pragma pack()
867:
1.1.1.14 root 868: #pragma pack(1)
869: typedef struct {
1.1.1.20 root 870: PAIR32 next_driver;
871: UINT16 attributes;
872: UINT16 strategy;
873: UINT16 interrupt;
874: char dev_name[8];
875: } device_t;
876: #pragma pack()
877:
878: #pragma pack(1)
879: typedef struct {
1.1.1.14 root 880: UINT16 date_format;
881: char currency_symbol[5];
882: char thou_sep[2];
883: char dec_sep[2];
884: char date_sep[2];
885: char time_sep[2];
886: char currency_format;
887: char currency_dec_digits;
888: char time_format;
889: PAIR32 case_map;
890: char list_sep[2];
891: char reserved[10];
892: } country_info_t;
893: #pragma pack()
894:
1.1 root 895: typedef struct {
896: char path[MAX_PATH];
897: int valid;
898: int id;
899: int atty;
900: int mode;
901: UINT16 info;
902: UINT16 psp;
903: } file_handler_t;
904:
905: static const struct {
906: int mode;
907: int in;
908: int out;
909: } file_mode[] = {
1.1.1.11 root 910: { _O_RDONLY | _O_BINARY, 1, 0 },
1.1 root 911: { _O_WRONLY | _O_BINARY, 0, 1 },
912: { _O_RDWR | _O_BINARY, 1, 1 },
913: };
914:
915: typedef struct {
916: UINT16 psp;
917: char module_dir[MAX_PATH];
918: PAIR32 dta;
919: UINT8 switchar;
920: UINT8 verify;
921: int max_files;
922: char volume_label[MAX_PATH];
923: bool parent_int_10h_feh_called;
924: bool parent_int_10h_ffh_called;
1.1.1.12 root 925: UINT16 parent_ds;
1.1.1.14 root 926: struct {
927: UINT16 handle;
928: UINT16 page;
929: bool mapped;
930: } ems_pages[4];
931: bool ems_pages_stored;
1.1.1.22 root 932: bool called_by_int2eh;
1.1 root 933: } process_t;
934:
1.1.1.11 root 935: typedef struct {
936: UINT16 psp;
937: UINT32 dta;
1.1.1.12 root 938: UINT8 allowable_mask;
939: UINT8 required_mask;
1.1.1.11 root 940: HANDLE find_handle;
941: } dtainfo_t;
942:
1.1.1.8 root 943: UINT8 major_version = 7;
944: UINT8 minor_version = 10;
945:
1.1.1.7 root 946: UINT16 first_mcb;
1.1 root 947: UINT16 current_psp;
948:
949: int retval = 0;
950: UINT16 error_code = 0;
951:
952: file_handler_t file_handler[MAX_FILES];
953: UINT8 file_buffer[0x100000];
954:
955: process_t process[MAX_PROCESS];
1.1.1.11 root 956: dtainfo_t dtalist[MAX_DTAINFO];
1.1 root 957:
1.1.1.6 root 958: UINT16 malloc_strategy = 0;
959:
1.1.1.12 root 960: char comspec_path[MAX_PATH] = "C:\\COMMAND.COM";
961:
1.1 root 962: void msdos_syscall(unsigned num);
963: int msdos_init(int argc, char *argv[], char *envp[], int standard_env);
964: void msdos_finish();
965:
966: // console
967:
1.1.1.12 root 968: #define SCR_BUF_WIDTH 256
969: #define SCR_BUF_HEIGHT 128
1.1 root 970:
971: #define SET_RECT(rect, l, t, r, b) { \
972: rect.Left = l; \
973: rect.Top = t; \
974: rect.Right = r; \
975: rect.Bottom = b; \
976: }
977:
1.1.1.19 root 978: DWORD dwConsoleMode = 0;
979:
1.1.1.12 root 980: CHAR_INFO scr_buf[SCR_BUF_WIDTH * SCR_BUF_HEIGHT];
981: char scr_char[SCR_BUF_WIDTH * SCR_BUF_HEIGHT];
982: WORD scr_attr[SCR_BUF_WIDTH * SCR_BUF_HEIGHT];
1.1 root 983: COORD scr_buf_size;
984: COORD scr_buf_pos;
985: int scr_width, scr_height;
1.1.1.12 root 986: int scr_top;
1.1.1.10 root 987: bool restore_console_on_exit = false;
1.1 root 988: bool cursor_moved;
989:
1.1.1.22 root 990: FIFO *key_buf_char = NULL;
991: FIFO *key_buf_scan = NULL;
1.1.1.19 root 992: bool key_changed = false;
1.1.1.4 root 993: UINT32 key_code = 0;
1.1 root 994:
1.1.1.21 root 995: UINT8 ctrl_c_checking = 0x01; // ???
996: bool ctrl_c_pressed = false;
997: bool ctrl_c_detected = false;
998:
1.1 root 999: int active_code_page;
1000: int system_code_page;
1001:
1.1.1.12 root 1002: UINT32 text_vram_top_address;
1003: UINT32 text_vram_end_address;
1004: UINT32 shadow_buffer_top_address;
1005: UINT32 shadow_buffer_end_address;
1006: int vram_pages;
1.1 root 1007: bool int_10h_feh_called = false;
1008: bool int_10h_ffh_called = false;
1009:
1.1.1.19 root 1010: #define MAX_MOUSE_BUTTONS 3
1011:
1.1.1.21 root 1012: typedef struct {
1.1.1.19 root 1013: bool active;
1014: struct {
1015: int x, y;
1016: } position, prev_position, max_position, min_position, mickey;
1017: struct {
1018: bool status;
1019: int pressed_times;
1020: int released_times;
1021: struct {
1022: int x, y;
1023: } pressed_position;
1024: struct {
1025: int x, y;
1026: } released_position;
1027: } buttons[MAX_MOUSE_BUTTONS];
1028: int get_buttons()
1029: {
1030: int val = 0;
1031: for(int i = 0; i < MAX_MOUSE_BUTTONS; i++) {
1032: if(buttons[i].status) {
1033: val |= 1 << i;
1034: }
1035: }
1036: return(val);
1037: }
1038: UINT16 status;
1039: UINT16 status_irq;
1040: UINT16 call_mask;
1041: PAIR32 call_addr;
1042: // dummy
1043: UINT16 sensitivity[3];
1044: UINT16 display_page;
1045: UINT16 language;
1046: UINT16 hot_spot[2];
1.1.1.21 root 1047: } mouse_t;
1048:
1049: mouse_t mouse;
1.1.1.19 root 1050:
1051: UINT16 mouse_push_ax;
1052: UINT16 mouse_push_bx;
1053: UINT16 mouse_push_cx;
1054: UINT16 mouse_push_dx;
1055: UINT16 mouse_push_si;
1056: UINT16 mouse_push_di;
1057:
1.1.1.23! root 1058: // hma
! 1059:
! 1060: #ifdef SUPPORT_HMA
! 1061: bool is_hma_used_by_xms = false;
! 1062: bool is_hma_used_by_int_2fh = false;
! 1063: #endif
! 1064:
! 1065: // xms
! 1066:
! 1067: #ifdef SUPPORT_XMS
! 1068: #define MAX_XMS_HANDLES 16
! 1069: #define MAX_XMS_SIZE_KB 0x8000 // 32MB
! 1070:
! 1071: typedef struct {
! 1072: int seg;
! 1073: int size_kb;
! 1074: int lock;
! 1075: bool allocated;
! 1076: } xms_handle_t;
! 1077:
! 1078: xms_handle_t xms_handles[MAX_XMS_HANDLES + 1];
! 1079: int xms_a20_local_enb_count;
! 1080: UINT16 xms_dx_after_call_08h = 0;
! 1081: #endif
! 1082:
1.1 root 1083: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.