]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/dos/testemm.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / dos / testemm.c
1 /* testemm.c
2  *
3  * Test program: Expanded Memory Manager functions
4  * (C) 2011-2012 Jonathan Campbell.
5  * Hackipedia DOS library.
6  *
7  * This code is licensed under the LGPL.
8  * <insert LGPL legal text here>
9  */
10
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdint.h>
14 #include <assert.h>
15 #include <stdio.h>
16 #include <conio.h>
17 #include <dos.h>
18
19 #include <hw/cpu/cpu.h>
20 #include <hw/dos/dos.h>
21 #include <hw/dos/emm.h>
22 #include <hw/dos/doswin.h>
23
24 static const char *message = "Hello world. How are you?";
25 static const char *message2 = "Pingas. Sup dawg. Hello world. Dork. Hahahajajaja.";
26 static char tmp[128],tmp2[128];
27
28 #if 1
29 # define x_memcpy(a,b,c) memcpy(a,b,c)
30 #else
31 /* what have we come to when friggin' memcpy() causes a GPF?!? */
32 static void x_memcpy(unsigned char *dst,const unsigned char *src,size_t c) {
33         fprintf(stderr,"memcpy %p -> %p (%lu)\n",
34                 dst,src,(unsigned long)c);
35
36         while (c != 0) {
37             *dst++ = *src++;
38             c--;
39         }
40 }
41 #endif
42
43 int main() {
44         size_t message_l = strlen(message),message2_l = strlen(message2);
45
46         probe_dos();
47         printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);
48         if (detect_windows()) {
49                 printf("I am running under Windows.\n");
50                 printf("    Mode: %s\n",windows_mode_str(windows_mode));
51                 printf("    Ver:  %x.%02u\n",windows_version>>8,windows_version&0xFF);
52         }
53         else {
54                 printf("Not running under Windows or OS/2\n");
55         }
56
57         sanity();
58         if (probe_emm()) {
59                 int h1,h2,h3;
60
61                 sanity();
62                 printf("Expanded memory manager present. Status = 0x%02x Page frame @0x%04x v%x.%x\n",emm_status,emm_page_frame_segment,emm_version>>4,emm_version&0x0F);
63                 emm_update_page_count();
64                 sanity();
65                 printf("  Unallocated pages:     %u (%luKB)\n",
66                         emm_unallocated_pages,
67                         (unsigned long)emm_unallocated_pages << 4UL); /* 2^14 = 16384 */
68                 printf("  Total pages:           %u (%luKB)\n",
69                         emm_total_pages,
70                         (unsigned long)emm_total_pages << 4UL);
71                 printf("  Physical pages:        %u (%luKB)\n",
72                         emm_phys_pages,
73                         (unsigned long)emm_phys_pages << 4UL);
74
75                 while (getch() != 13);
76                 sanity();
77
78                 /* print out the mapping table, if available */
79                 if (emm_phys_map != NULL) {
80                         struct emm_phys_page_map *me;
81                         unsigned int i;
82
83                         printf("Physical page to segment table\n");
84                         for (i=0;i < emm_phys_pages;i++) {
85                                 me = emm_phys_map + i;
86                                 printf("  %02x: 0x%04x",me->number,me->segment);
87                                 if ((i%5) == 4) printf("\n");
88                         }
89                         printf("\n");
90                         sanity();
91                 }
92
93                 printf("Allocating EMM pages (1): ");
94                 h1 = emm_alloc_pages(1);
95                 sanity();
96                 if (h1 >= 0) {
97                         printf("OK, handle=%u\n",h1);
98                         if (!emm_free_pages(h1)) printf("cannot free\n");
99                 }
100                 else printf("FAILED\n");
101
102                 printf("Allocating EMM pages (16KB): ");
103                 h1 = emm_alloc_pages(1);
104                 sanity();
105                 if (h1 >= 0) printf("OK, handle=%u\n",h1);
106                 else printf("FAILED\n");
107
108                 printf("Allocating EMM pages (1MB): ");
109                 h2 = emm_alloc_pages(0x100000UL >> 14UL);
110                 sanity();
111                 if (h2 >= 0) printf("OK, handle=%u\n",h2);
112                 else printf("FAILED\n");
113
114                 printf("Allocating EMM pages (12MB): ");
115                 h3 = emm_alloc_pages(0xC00000UL >> 14UL);
116                 sanity();
117                 if (h3 >= 0) printf("OK, handle=%u\n",h3);
118                 else printf("FAILED\n");
119
120                 while (getch() != 13);
121
122                 if (h1 >= 0 && !emm_free_pages(h1)) printf("Cannot free\n");
123                 sanity();
124                 if (h2 >= 0 && !emm_free_pages(h2)) printf("Cannot free\n");
125                 sanity();
126                 if (h3 >= 0 && !emm_free_pages(h3)) printf("Cannot free\n");
127                 sanity();
128
129                 printf("Allocating EMM pages (32KB): ");
130                 h1 = emm_alloc_pages(2);
131                 sanity();
132                 if (h1 >= 0) {
133                         printf("OK, handle=%u\n",h1);
134                         if (emm_map_page(h1,/*physical*/0,/*logical*/0)) {
135                                 unsigned int segm = emm_last_phys_page_segment(0);
136                                 printf("Seg %04x\n",segm);
137                                 sanity();
138                                 if (segm > 0) {
139 #if TARGET_MSDOS == 16
140                                         char far *ptr = MK_FP(segm,0);
141 #else
142                                         char *ptr = (char*)(segm << 4UL);
143 #endif
144
145 #if TARGET_MSDOS == 16
146                                         _fmemcpy(ptr,(char far*)message,message_l+1);
147                                         _fmemcpy((char far*)tmp,ptr,message_l+1);
148 #else
149                                         x_memcpy(ptr,message,message_l+1);
150                                         x_memcpy(tmp,ptr,message_l+1);
151 #endif
152                                         printf("After writing message there, I read back: '%s'\n",tmp);
153
154                                         if (!emm_map_page(h1,0,1)) printf("Cannot remap\n");
155
156 #if TARGET_MSDOS == 16
157                                         _fmemcpy(ptr,(char far*)message2,message2_l+1);
158                                         _fmemcpy((char far*)tmp,ptr,message2_l+1);
159 #else
160                                         x_memcpy(ptr,message2,message2_l+1);
161                                         x_memcpy(tmp,ptr,message2_l+1);
162 #endif
163                                         printf("After mapping to page 2 and writing there, I read back: '%s'\n",tmp);
164
165                                         if (!emm_map_page(h1,0,0)) printf("Cannot remap\n");
166
167 #if TARGET_MSDOS == 16
168                                         _fmemcpy((char far*)tmp,ptr,message_l+1);
169 #else
170                                         x_memcpy(tmp,ptr,message_l+1);
171 #endif
172                                         printf("After mapping back to 1, I read back: '%s'\n",tmp);
173
174                                         if (emm_map_page(h1,0,2)) printf("Whoops, I was able to map logical pages beyond what I allocated\n");
175                                 }
176                                 else {
177                                         printf("Cannot get segment\n");
178                                 }
179                                 if (!emm_map_page(h1,0,0xFFFF)) printf("Cannot unmap\n");
180                         }
181                         else {
182                                 printf("Cannot map\n");
183                         }
184                         if (!emm_free_pages(h1)) printf("Cannot free\n");
185                 }
186                 else printf("FAILED\n");
187
188                 printf("Allocating EMM pages (32KB): ");
189                 h1 = emm_alloc_pages(2);
190                 if (h1 >= 0) {
191                         printf("OK, handle=%u\n",h1);
192                         if (    emm_map_page(h1,/*physical*/0,/*logical*/0) &&
193                                 emm_map_page(h1,/*physical*/1,/*logical*/1)) {
194                                 unsigned int seg1 = emm_last_phys_page_segment(0);
195                                 unsigned int seg2 = emm_last_phys_page_segment(1);
196                                 printf("Seg %04x,%04x\n",seg1,seg2);
197                                 if (seg1 > 0 && seg2 > 0) {
198 #if TARGET_MSDOS == 16
199                                         char far *ptr1 = MK_FP(seg1,0);
200                                         char far *ptr2 = MK_FP(seg2,0);
201 #else
202                                         char *ptr1 = (char*)(seg1 << 4UL);
203                                         char *ptr2 = (char*)(seg2 << 4UL);
204 #endif
205
206 #if TARGET_MSDOS == 16
207                                         _fmemcpy(ptr1,(char far*)message,message_l+1);
208                                         _fmemcpy(ptr2,(char far*)message2,message2_l+1);
209 #else
210                                         memcpy(ptr1,message,message_l+1);
211                                         memcpy(ptr2,message2,message2_l+1);
212 #endif
213
214 #if TARGET_MSDOS == 16
215                                         _fmemcpy((char far*)tmp,ptr1,message_l+1);
216                                         _fmemcpy((char far*)tmp2,ptr2,message2_l+1);
217 #else
218                                         memcpy(tmp,ptr1,message_l+1);
219                                         memcpy(tmp2,ptr2,message2_l+1);
220 #endif
221
222                                         printf("After writing message there, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
223
224                                         /* now swap the pages */
225                                         if (!emm_map_page(h1,1,0)) printf("cannot map log 1 -> phys 0\n");
226                                         if (!emm_map_page(h1,0,1)) printf("cannot map log 0 -> phys 1\n");
227
228 #if TARGET_MSDOS == 16
229                                         _fmemcpy((char far*)tmp,ptr1,message2_l+1);
230                                         _fmemcpy((char far*)tmp2,ptr2,message_l+1);
231 #else
232                                         memcpy(tmp,ptr1,message2_l+1);
233                                         memcpy(tmp2,ptr2,message_l+1);
234 #endif
235
236                                         printf("After swapping pages, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
237                                 }
238                                 else {
239                                         printf("Cannot get segment\n");
240                                 }
241                                 if (!emm_map_page(h1,0,0xFFFF) || !emm_map_page(h1,1,0xFFFF)) printf("Cannot unmap\n");
242                         }
243                         else {
244                                 printf("Cannot map\n");
245                         }
246                         if (!emm_free_pages(h1)) printf("Cannot free\n");
247                 }
248                 else printf("FAILED\n");
249
250                 /* we do this test because Microsoft EMM386.EXE seems to max out at 32MB.
251                  * the host could have 256MB of total memory and it would still report 32MB in EMS */
252                 printf("Allocating EMM pages (48MB): ");
253                 h1 = emm_alloc_pages((48UL << 20UL) >> 14UL);
254                 if (h1 >= 0) {
255                         printf("OK, handle=%u\n",h1);
256                         if (!emm_free_pages(h1)) printf("cannot free\n");
257                 }
258                 else printf("FAILED\n");
259
260                 printf("Allocating EMM pages (96MB): ");
261                 h1 = emm_alloc_pages((96UL << 20UL) >> 14UL);
262                 if (h1 >= 0) {
263                         printf("OK, handle=%u\n",h1);
264                         if (!emm_free_pages(h1)) printf("cannot free\n");
265                 }
266                 else printf("FAILED\n");
267         }
268
269         return 0;
270 }
271