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