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