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