3 * Test program: Expanded Memory Manager functions
\r
4 * (C) 2011-2012 Jonathan Campbell.
\r
5 * Hackipedia DOS library.
\r
7 * This code is licensed under the LGPL.
\r
8 * <insert LGPL legal text here>
\r
19 //#include "src/lib/doslib/cpu.h"
\r
20 #include "src/lib/doslib/dos.h"
\r
21 #include "src/lib/doslib/emm.h"
\r
22 //#include <hw/dos/doswin.h>
\r
24 static const char *message = "Hello world. How are you?";
\r
25 static const char *message2 = "Pingas. Sup dawg. Hello world. Dork. Hahahajajaja.";
\r
26 static char tmp[128],tmp2[128];
\r
27 extern int probe_emm0();
\r
30 # define x_memcpy(a,b,c) memcpy(a,b,c)
\r
32 /* what have we come to when friggin' memcpy() causes a GPF?!? */
\r
33 static void x_memcpy(unsigned char *dst,const unsigned char *src,size_t c) {
\r
34 fprintf(stderr,"memcpy %p -> %p (%lu)\n",
\r
35 dst,src,(unsigned long)c);
\r
45 size_t message_l = strlen(message),message2_l = strlen(message2);
\r
48 printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);
\r
49 /*if (detect_windows()) {
\r
50 printf("I am running under Windows.\n");
\r
51 printf(" Mode: %s\n",windows_mode_str(windows_mode));
\r
52 printf(" Ver: %x.%02u\n",windows_version>>8,windows_version&0xFF);
\r
55 printf("Not running under Windows or OS/2\n");
\r
63 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);
\r
64 emm_update_page_count();
\r
66 printf(" Unallocated pages: %u (%luKB)\n",
\r
67 emm_unallocated_pages,
\r
68 (unsigned long)emm_unallocated_pages << 4UL); /* 2^14 = 16384 */
\r
69 printf(" Total pages: %u (%luKB)\n",
\r
71 (unsigned long)emm_total_pages << 4UL);
\r
72 printf(" Physical pages: %u (%luKB)\n",
\r
74 (unsigned long)emm_phys_pages << 4UL);
\r
76 while (getch() != 13);
\r
79 /* print out the mapping table, if available */
\r
80 if (emm_phys_map != NULL) {
\r
81 struct emm_phys_page_map *me;
\r
84 printf("Physical page to segment table\n");
\r
85 for (i=0;i < emm_phys_pages;i++) {
\r
86 me = emm_phys_map + i;
\r
87 printf(" %02x: 0x%04x",me->number,me->segment);
\r
88 if ((i%5) == 4) printf("\n");
\r
94 printf("Allocating EMM pages (1): ");
\r
95 h1 = emm_alloc_pages(1);
\r
98 printf("OK, handle=%u\n",h1);
\r
99 if (!emm_free_pages(h1)) printf("cannot free\n");
\r
101 else printf("FAILED\n");
\r
103 printf("Allocating EMM pages (%luKB): ", (dword)emm_unallocated_pages << 4UL);
\r
104 h1 = emm_alloc_pages(emm_unallocated_pages);
\r
106 if (h1 >= 0) printf("OK, handle=%u\n",h1);
\r
107 else printf("FAILED\n");
\r
109 // printf("Allocating EMM pages (1.6MB): ");
\r
110 //h2 = emm_alloc_pages(0x19999AUL >> 14UL);
\r
111 /*h2 = emm_alloc_pages(1);
\r
113 if (h2 >= 0) printf("OK, handle=%u\n",h2);
\r
114 else printf("FAILED\n");
\r
116 //printf("Allocating EMM pages (12MB): ");
\r
117 //h3 = emm_alloc_pages(0xC00000UL >> 14UL);
\r
118 h3 = emm_alloc_pages(1);
\r
120 if (h3 >= 0) printf("OK, handle=%u\n",h3);
\r
121 else printf("FAILED\n");*/
\r
123 while (getch() != 13);
\r
125 if (h1 >= 0 && !emm_free_pages(h1)) printf("Cannot free\n");
\r
127 /*if (h2 >= 0 && !emm_free_pages(h2)) printf("Cannot free\n");
\r
129 if (h3 >= 0 && !emm_free_pages(h3)) printf("Cannot free\n");
\r
132 printf("Allocating EMM pages (32KB): ");
\r
133 h1 = emm_alloc_pages(2);
\r
136 printf("OK, handle=%u\n",h1);
\r
137 if (emm_map_page(h1,/*physical*/0,/*logical*/0)) {
\r
138 unsigned int segm = emm_last_phys_page_segment(0);
\r
139 printf("Seg %04x\n",segm);
\r
142 #if TARGET_MSDOS == 16
\r
143 char far *ptr = MK_FP(segm,0);
\r
145 char *ptr = (char*)(segm << 4UL);
\r
148 #if TARGET_MSDOS == 16
\r
149 _fmemcpy(ptr,(char far*)message,message_l+1);
\r
150 _fmemcpy((char far*)tmp,ptr,message_l+1);
\r
152 x_memcpy(ptr,message,message_l+1);
\r
153 x_memcpy(tmp,ptr,message_l+1);
\r
155 printf("After writing message there, I read back: '%s'\n",tmp);
\r
157 if (!emm_map_page(h1,0,1)) printf("Cannot remap\n");
\r
159 #if TARGET_MSDOS == 16
\r
160 _fmemcpy(ptr,(char far*)message2,message2_l+1);
\r
161 _fmemcpy((char far*)tmp,ptr,message2_l+1);
\r
163 x_memcpy(ptr,message2,message2_l+1);
\r
164 x_memcpy(tmp,ptr,message2_l+1);
\r
166 printf("After mapping to page 2 and writing there, I read back: '%s'\n",tmp);
\r
168 if (!emm_map_page(h1,0,0)) printf("Cannot remap\n");
\r
170 #if TARGET_MSDOS == 16
\r
171 _fmemcpy((char far*)tmp,ptr,message_l+1);
\r
173 x_memcpy(tmp,ptr,message_l+1);
\r
175 printf("After mapping back to 1, I read back: '%s'\n",tmp);
\r
177 if (emm_map_page(h1,0,2)) printf("Whoops, I was able to map logical pages beyond what I allocated\n");
\r
180 printf("Cannot get segment\n");
\r
182 if (!emm_map_page(h1,0,0xFFFF)) printf("Cannot unmap\n");
\r
185 printf("Cannot map\n");
\r
187 if (!emm_free_pages(h1)) printf("Cannot free\n");
\r
189 else printf("FAILED\n");
\r
191 printf("Allocating EMM pages (32KB): ");
\r
192 h1 = emm_alloc_pages(2);
\r
194 printf("OK, handle=%u\n",h1);
\r
195 if ( emm_map_page(h1,/*physical*/0,/*logical*/0) &&
\r
196 emm_map_page(h1,/*physical*/1,/*logical*/1)) {
\r
197 unsigned int seg1 = emm_last_phys_page_segment(0);
\r
198 unsigned int seg2 = emm_last_phys_page_segment(1);
\r
199 printf("Seg %04x,%04x\n",seg1,seg2);
\r
200 if (seg1 > 0 && seg2 > 0) {
\r
201 #if TARGET_MSDOS == 16
\r
202 char far *ptr1 = MK_FP(seg1,0);
\r
203 char far *ptr2 = MK_FP(seg2,0);
\r
205 char *ptr1 = (char*)(seg1 << 4UL);
\r
206 char *ptr2 = (char*)(seg2 << 4UL);
\r
209 #if TARGET_MSDOS == 16
\r
210 _fmemcpy(ptr1,(char far*)message,message_l+1);
\r
211 _fmemcpy(ptr2,(char far*)message2,message2_l+1);
\r
213 memcpy(ptr1,message,message_l+1);
\r
214 memcpy(ptr2,message2,message2_l+1);
\r
217 #if TARGET_MSDOS == 16
\r
218 _fmemcpy((char far*)tmp,ptr1,message_l+1);
\r
219 _fmemcpy((char far*)tmp2,ptr2,message2_l+1);
\r
221 memcpy(tmp,ptr1,message_l+1);
\r
222 memcpy(tmp2,ptr2,message2_l+1);
\r
225 printf("After writing message there, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
\r
227 /* now swap the pages */
\r
228 if (!emm_map_page(h1,1,0)) printf("cannot map log 1 -> phys 0\n");
\r
229 if (!emm_map_page(h1,0,1)) printf("cannot map log 0 -> phys 1\n");
\r
231 #if TARGET_MSDOS == 16
\r
232 _fmemcpy((char far*)tmp,ptr1,message2_l+1);
\r
233 _fmemcpy((char far*)tmp2,ptr2,message_l+1);
\r
235 memcpy(tmp,ptr1,message2_l+1);
\r
236 memcpy(tmp2,ptr2,message_l+1);
\r
239 printf("After swapping pages, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
\r
242 printf("Cannot get segment\n");
\r
244 if (!emm_map_page(h1,0,0xFFFF) || !emm_map_page(h1,1,0xFFFF)) printf("Cannot unmap\n");
\r
247 printf("Cannot map\n");
\r
249 if (!emm_free_pages(h1)) printf("Cannot free\n");
\r
251 else printf("FAILED\n");
\r
255 /* we do this test because Microsoft EMM386.EXE seems to max out at 32MB.
\r
256 * the host could have 256MB of total memory and it would still report 32MB in EMS */
\r
257 printf("we do this test because Microsoft EMM386.EXE seems to max out at 32MB.\n the host could have 256MB of total memory and it would still report 32MB in EMS");
\r
258 printf("Allocating EMM pages (48MB): ");
\r
259 h1 = emm_alloc_pages((48UL << 20UL) >> 14UL);
\r
261 printf("OK, handle=%u\n",h1);
\r
262 if (!emm_free_pages(h1)) printf("cannot free\n");
\r
264 else printf("FAILED\n");
\r
266 printf("Allocating EMM pages (96MB): ");
\r
267 h1 = emm_alloc_pages((96UL << 20UL) >> 14UL);
\r
269 printf("OK, handle=%u\n",h1);
\r
270 if (!emm_free_pages(h1)) printf("cannot free\n");
\r
272 else printf("FAILED\n");
\r