3 * Test program: Expanded Memory Manager functions
4 * (C) 2011-2012 Jonathan Campbell.
5 * Hackipedia DOS library.
7 * This code is licensed under the LGPL.
8 * <insert LGPL legal text here>
19 #include <hw/cpu/cpu.h>
20 #include <hw/dos/dos.h>
21 #include <hw/dos/emm.h>
22 #include <hw/dos/doswin.h>
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];
29 # define x_memcpy(a,b,c) memcpy(a,b,c)
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);
44 size_t message_l = strlen(message),message2_l = strlen(message2);
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);
54 printf("Not running under Windows or OS/2\n");
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();
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",
70 (unsigned long)emm_total_pages << 4UL);
71 printf(" Physical pages: %u (%luKB)\n",
73 (unsigned long)emm_phys_pages << 4UL);
75 while (getch() != 13);
78 /* print out the mapping table, if available */
79 if (emm_phys_map != NULL) {
80 struct emm_phys_page_map *me;
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");
93 printf("Allocating EMM pages (1): ");
94 h1 = emm_alloc_pages(1);
97 printf("OK, handle=%u\n",h1);
98 if (!emm_free_pages(h1)) printf("cannot free\n");
100 else printf("FAILED\n");
102 printf("Allocating EMM pages (16KB): ");
103 h1 = emm_alloc_pages(1);
105 if (h1 >= 0) printf("OK, handle=%u\n",h1);
106 else printf("FAILED\n");
108 printf("Allocating EMM pages (1MB): ");
109 h2 = emm_alloc_pages(0x100000UL >> 14UL);
111 if (h2 >= 0) printf("OK, handle=%u\n",h2);
112 else printf("FAILED\n");
114 printf("Allocating EMM pages (12MB): ");
115 h3 = emm_alloc_pages(0xC00000UL >> 14UL);
117 if (h3 >= 0) printf("OK, handle=%u\n",h3);
118 else printf("FAILED\n");
120 while (getch() != 13);
122 if (h1 >= 0 && !emm_free_pages(h1)) printf("Cannot free\n");
124 if (h2 >= 0 && !emm_free_pages(h2)) printf("Cannot free\n");
126 if (h3 >= 0 && !emm_free_pages(h3)) printf("Cannot free\n");
129 printf("Allocating EMM pages (32KB): ");
130 h1 = emm_alloc_pages(2);
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);
139 #if TARGET_MSDOS == 16
140 char far *ptr = MK_FP(segm,0);
142 char *ptr = (char*)(segm << 4UL);
145 #if TARGET_MSDOS == 16
146 _fmemcpy(ptr,(char far*)message,message_l+1);
147 _fmemcpy((char far*)tmp,ptr,message_l+1);
149 x_memcpy(ptr,message,message_l+1);
150 x_memcpy(tmp,ptr,message_l+1);
152 printf("After writing message there, I read back: '%s'\n",tmp);
154 if (!emm_map_page(h1,0,1)) printf("Cannot remap\n");
156 #if TARGET_MSDOS == 16
157 _fmemcpy(ptr,(char far*)message2,message2_l+1);
158 _fmemcpy((char far*)tmp,ptr,message2_l+1);
160 x_memcpy(ptr,message2,message2_l+1);
161 x_memcpy(tmp,ptr,message2_l+1);
163 printf("After mapping to page 2 and writing there, I read back: '%s'\n",tmp);
165 if (!emm_map_page(h1,0,0)) printf("Cannot remap\n");
167 #if TARGET_MSDOS == 16
168 _fmemcpy((char far*)tmp,ptr,message_l+1);
170 x_memcpy(tmp,ptr,message_l+1);
172 printf("After mapping back to 1, I read back: '%s'\n",tmp);
174 if (emm_map_page(h1,0,2)) printf("Whoops, I was able to map logical pages beyond what I allocated\n");
177 printf("Cannot get segment\n");
179 if (!emm_map_page(h1,0,0xFFFF)) printf("Cannot unmap\n");
182 printf("Cannot map\n");
184 if (!emm_free_pages(h1)) printf("Cannot free\n");
186 else printf("FAILED\n");
188 printf("Allocating EMM pages (32KB): ");
189 h1 = emm_alloc_pages(2);
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);
202 char *ptr1 = (char*)(seg1 << 4UL);
203 char *ptr2 = (char*)(seg2 << 4UL);
206 #if TARGET_MSDOS == 16
207 _fmemcpy(ptr1,(char far*)message,message_l+1);
208 _fmemcpy(ptr2,(char far*)message2,message2_l+1);
210 memcpy(ptr1,message,message_l+1);
211 memcpy(ptr2,message2,message2_l+1);
214 #if TARGET_MSDOS == 16
215 _fmemcpy((char far*)tmp,ptr1,message_l+1);
216 _fmemcpy((char far*)tmp2,ptr2,message2_l+1);
218 memcpy(tmp,ptr1,message_l+1);
219 memcpy(tmp2,ptr2,message2_l+1);
222 printf("After writing message there, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
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");
228 #if TARGET_MSDOS == 16
229 _fmemcpy((char far*)tmp,ptr1,message2_l+1);
230 _fmemcpy((char far*)tmp2,ptr2,message_l+1);
232 memcpy(tmp,ptr1,message2_l+1);
233 memcpy(tmp2,ptr2,message_l+1);
236 printf("After swapping pages, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
239 printf("Cannot get segment\n");
241 if (!emm_map_page(h1,0,0xFFFF) || !emm_map_page(h1,1,0xFFFF)) printf("Cannot unmap\n");
244 printf("Cannot map\n");
246 if (!emm_free_pages(h1)) printf("Cannot free\n");
248 else printf("FAILED\n");
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);
255 printf("OK, handle=%u\n",h1);
256 if (!emm_free_pages(h1)) printf("cannot free\n");
258 else printf("FAILED\n");
260 printf("Allocating EMM pages (96MB): ");
261 h1 = emm_alloc_pages((96UL << 20UL) >> 14UL);
263 printf("OK, handle=%u\n",h1);
264 if (!emm_free_pages(h1)) printf("cannot free\n");
266 else printf("FAILED\n");