Release 950901
[wine] / miscemu / dosmem.c
1 /*
2  * DOS memory emulation
3  *
4  * Copyright 1995 Alexandre Julliard
5  */
6
7 #include <signal.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "windows.h"
11 #include "global.h"
12 #include "ldt.h"
13 #include "miscemu.h"
14 #include "module.h"
15
16
17 HANDLE DOSMEM_BiosSeg;  /* BIOS data segment at 0x40:0 */
18
19
20 #pragma pack(1)
21
22 typedef struct
23 {
24     WORD  Com1Addr;                  /* 00: COM1 I/O address */
25     WORD  Com2Addr;                  /* 02: COM2 I/O address */
26     WORD  Com3Addr;                  /* 04: COM3 I/O address */
27     WORD  Com4Addr;                  /* 06: COM4 I/O address */
28     WORD  Lpt1Addr;                  /* 08: LPT1 I/O address */
29     WORD  Lpt2Addr;                  /* 0a: LPT2 I/O address */
30     WORD  Lpt3Addr;                  /* 0c: LPT3 I/O address */
31     WORD  Lpt4Addr;                  /* 0e: LPT4 I/O address */
32     WORD  InstalledHardware;         /* 10: Installed hardware flags */
33     BYTE  POSTstatus;                /* 12: Power-On Self Test status */
34     WORD  MemSize WINE_PACKED;       /* 13: Base memory size in Kb */
35     WORD  unused1 WINE_PACKED;       /* 15: Manufacturing test scratch pad */
36     BYTE  KbdFlags1;                 /* 17: Keyboard flags 1 */
37     BYTE  KbdFlags2;                 /* 18: Keyboard flags 2 */
38     BYTE  unused2;                   /* 19: Keyboard driver workspace */
39     WORD  NextKbdCharPtr;            /* 1a: Next character in kbd buffer */
40     WORD  FirstKbdCharPtr;           /* 1c: First character in kbd buffer */
41     WORD  KbdBuffer[16];             /* 1e: Keyboard buffer */
42     BYTE  DisketteStatus1;           /* 3e: Diskette recalibrate status */
43     BYTE  DisketteStatus2;           /* 3f: Diskette motor status */
44     BYTE  DisketteStatus3;           /* 40: Diskette motor timeout */
45     BYTE  DisketteStatus4;           /* 41: Diskette last operation status */
46     BYTE  DiskStatus[7];             /* 42: Disk status/command bytes */
47     BYTE  VideoMode;                 /* 49: Video mode */
48     WORD  VideoColumns;              /* 4a: Number of columns */
49     WORD  VideoPageSize;             /* 4c: Video page size in bytes */
50     WORD  VideoPageStartAddr;        /* 4e: Video page start address */
51     BYTE  VideoCursorPos[16];        /* 50: Cursor position for 8 pages */
52     WORD  VideoCursorType;           /* 60: Video cursor type */
53     BYTE  VideoCurPage;              /* 62: Video current page */
54     WORD  VideoCtrlAddr WINE_PACKED; /* 63: Video controller address */
55     BYTE  VideoReg1;                 /* 65: Video mode select register */
56     BYTE  VideoReg2;                 /* 66: Video CGA palette register */
57     DWORD ResetEntry WINE_PACKED;    /* 67: Warm reset entry point */
58     BYTE  LastIRQ;                   /* 6b: Last unexpected interrupt */
59     DWORD Ticks;                     /* 6c: Ticks since midnight */
60     BYTE  TicksOverflow;             /* 70: Timer overflow if past midnight */
61     BYTE  CtrlBreakFlag;             /* 71: Ctrl-Break flag */
62     WORD  ResetFlag;                 /* 72: POST Reset flag */
63     BYTE  DiskOpStatus;              /* 74: Last hard-disk operation status */
64     BYTE  NbHardDisks;               /* 75: Number of hard disks */
65     BYTE  DiskCtrlByte;              /* 76: Disk control byte */
66     BYTE  DiskIOPort;                /* 77: Disk I/O port offset */
67     BYTE  LptTimeout[4];             /* 78: Timeouts for parallel ports */
68     BYTE  ComTimeout[4];             /* 7c: Timeouts for serial ports */
69     WORD  KbdBufferStart;            /* 80: Keyboard buffer start */
70     WORD  KbdBufferEnd;              /* 82: Keyboard buffer end */
71 } BIOSDATA;
72
73 #pragma pack(4)
74
75
76 static BIOSDATA *pBiosData = NULL;
77
78
79 /***********************************************************************
80  *           DOSMEM_Init
81  *
82  * Create the dos memory segments, and store them into the KERNEL
83  * exported values. MODULE_Init() must already have been called.
84  */
85 BOOL DOSMEM_Init(void)
86 {
87     HMODULE hModule = GetModuleHandle( "KERNEL" );
88     char *dosmem;
89
90     /* Allocate 7 64k segments for 0000, A000, B000, C000, D000, E000, F000. */
91
92     dosmem = malloc( 0x70000 );
93
94     MODULE_SetEntryPoint( hModule, 183,  /* KERNEL.183: __0000H */
95                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem,
96                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
97     DOSMEM_BiosSeg = GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x400, 0x100,
98                                          hModule, FALSE, FALSE, FALSE, NULL );
99
100     MODULE_SetEntryPoint( hModule, 193,  /* KERNEL.193: __0040H */
101                           DOSMEM_BiosSeg );
102     MODULE_SetEntryPoint( hModule, 174,  /* KERNEL.174: __A000H */
103                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x10000,
104                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
105     MODULE_SetEntryPoint( hModule, 181,  /* KERNEL.181: __B000H */
106                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x20000,
107                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
108     MODULE_SetEntryPoint( hModule, 182,  /* KERNEL.182: __B800H */
109                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x28000,
110                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
111     MODULE_SetEntryPoint( hModule, 195,  /* KERNEL.195: __C000H */
112                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x30000,
113                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
114     MODULE_SetEntryPoint( hModule, 179,  /* KERNEL.179: __D000H */
115                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x40000,
116                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
117     MODULE_SetEntryPoint( hModule, 190,  /* KERNEL.190: __E000H */
118                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x50000,
119                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
120     MODULE_SetEntryPoint( hModule, 173,  /* KERNEL.173: __ROMBIOS */
121                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
122                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
123     MODULE_SetEntryPoint( hModule, 194,  /* KERNEL.194: __F000H */
124                           GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
125                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
126     DOSMEM_FillBiosSegment();
127
128     return TRUE;
129 }
130
131
132 /***********************************************************************
133  *           DOSMEM_Alarm
134  *
135  * Increment the BIOS tick counter.
136  */
137 static void DOSMEM_Alarm(void)
138 {
139     pBiosData->Ticks = INT1A_GetTicksSinceMidnight();
140     printf( "Ticks = %d\n", pBiosData->Ticks );
141 /*
142     signal( SIGALRM, DOSMEM_Alarm );
143     alarm( 1 );
144 */
145 }
146
147
148 /***********************************************************************
149  *           DOSMEM_FillBiosSegment
150  *
151  * Fill the BIOS data segment with dummy values.
152  */
153 void DOSMEM_FillBiosSegment(void)
154 {
155     pBiosData = (BIOSDATA *)GlobalLock( DOSMEM_BiosSeg );
156
157       /* Clear all unused values */
158     memset( pBiosData, 0, sizeof(*pBiosData) );
159
160     /* FIXME: should check the number of configured drives and ports */
161
162     pBiosData->Com1Addr             = 0x3e8;
163     pBiosData->Com2Addr             = 0x2e8;
164     pBiosData->Lpt1Addr             = 0x378;
165     pBiosData->Lpt2Addr             = 0x278;
166     pBiosData->InstalledHardware    = 0x8443;
167     pBiosData->MemSize              = 640;
168     pBiosData->NextKbdCharPtr       = 0x1e;
169     pBiosData->FirstKbdCharPtr      = 0x1e;
170     pBiosData->VideoMode            = 0;
171     pBiosData->VideoColumns         = 80;
172     pBiosData->VideoPageSize        = 80 * 25 * 2;
173     pBiosData->VideoPageStartAddr   = 0xb800;
174     pBiosData->VideoCtrlAddr        = 0x3d4;
175     pBiosData->Ticks                = INT1A_GetTicksSinceMidnight();
176     pBiosData->NbHardDisks          = 2;
177     pBiosData->KbdBufferStart       = 0x1e;
178     pBiosData->KbdBufferEnd         = 0x3e;
179
180 /*
181     signal( SIGALRM, DOSMEM_Alarm );
182     alarm( 1 );
183 */
184 }