File: common\memory.c

    1 #include <string.h>
    2 #include <limits.h>
    3 #include <malloc.h>
    4 
    5 #if (!defined(XFRACT) && !defined(WINFRACT))
    6 #include <io.h>
    7 #endif
    8 
    9 #ifndef USE_VARARGS
   10 #include <stdarg.h>
11 #else 12 #include <varargs.h>
13 #endif 14 15 #include <ctype.h> 16 17 #include "port.h" 18 #include "prototyp.h" 19 20 21 /* Memory allocation routines. */ 22 23 #if 1 24 /* For extra seg memory: */ 25 #define EXTRA_RESERVE 4096L /* amount of extra mem we will leave avail. */ 26 /* For far memory: */ 27 #define FAR_RESERVE 8192L /* amount of far mem we will leave avail. */ 28 /* For expanded memory: */ 29 #define EXPWRITELEN 16384L /* max # bytes transferred to/from expanded mem at once */ 30 /* For extended memory: */ 31 #define XMMWRITELEN 8192L /* max # bytes transferred to/from extended mem at once */ 32 /* For disk memory: */ 33 #define DISKWRITELEN 2048L /* max # bytes transferred to/from disk mem at once */ 34 35 BYTE far *charbuf = NULL; 36 int numEXThandles; 37 long ext_xfer_size; 38 U16 start_avail_extra = 0; 39 #endif 40 41 #define MAXHANDLES 256 /* arbitrary #, suitably big */ 42 char memfile[] = "handle.$$$"; 43 int numTOTALhandles; 44 45 #if (!defined(XFRACT) && !defined(WINFRACT)) 46 char memstr[6][9] = {"nowhere", "extraseg", "far", "expanded", 47 "extended", "disk"}; 48 #endif 49 50 #if (defined(XFRACT) || defined(WINFRACT))
51 char memstr[3][9] = {{"nowhere"}, {"far"}, {"disk"}};
52 #endif 53 54 struct nowhere { 55 enum stored_at_values stored_at; /* first 2 entries must be the same */ 56 long size; /* for each of these data structures */ 57 }; 58 59 struct farmem { 60 enum stored_at_values stored_at; 61 long size; 62 BYTE far *farmemory; 63 }; 64 65 struct disk { 66 enum stored_at_values stored_at; 67 long size; 68 FILE *file; 69 }; 70 71 #if (!defined(XFRACT) && !defined(WINFRACT)) 72 struct extra { 73 enum stored_at_values stored_at; 74 long size; 75 BYTE far *extramemory; 76 }; 77 78 struct expanded { 79 enum stored_at_values stored_at; 80 long size; 81 int oldexppage; 82 int mempages; 83 int emmhandle; 84 BYTE far *expmemory; 85 }; 86 87 struct extended { 88 enum stored_at_values stored_at; 89 long size; 90 int mempages; 91 int xmmhandle; 92 }; 93 #endif 94 95 union mem { 96 struct nowhere Nowhere; 97 struct farmem Farmem; 98 struct disk Disk; 99 #if (!defined(XFRACT) && !defined(WINFRACT)) 100 struct extra Extra; 101 struct expanded Expanded; 102 struct extended Extended; 103 #endif 104 }; 105 106 union mem far handletable[MAXHANDLES]; 107 108 /* Routines in this module */ 109 #ifndef XFRACT 110 U32 GetDiskSpace(void); 111 static void _fastcall near exp_seek(U16 handle, int page); /* expanded mem seek */ 112 #endif 113 static int _fastcall near CheckDiskSpace(long howmuch); 114 static int check_for_mem(int stored_at, long howmuch); 115 static U16 next_handle(void); 116 static int CheckBounds (long start, long length, U16 handle); 117 static void WhichDiskError(int); 118 static void DisplayError(int stored_at, long howmuch); 119 120 /* Routines in this module, visible to outside routines */ 121 122 void DisplayMemory (void); 123 void DisplayHandle (U16 handle); 124 int MemoryType (U16 handle); 125 void InitMemory (void); 126 void ExitCheck (void); 127 U16 MemoryAlloc(U16 size, long count, int stored_at); 128 void MemoryRelease(U16 handle); 129 int MoveToMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle); 130 int MoveFromMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle); 131 int SetMemory(int value,U16 size,long count,long offset,U16 handle); 132 133 /* Memory handling support routines */ 134 135 #ifndef XFRACT 136 U32 GetDiskSpace(void) 137 { 138 /* Returns the number of bytes available on the current disk drive. */ 139 U32 available = 0; 140 union REGS regs; 141 142 regs.h.ah = 0x36; /* Function 36, Get Disk Free Space */ 143 regs.h.dl = 0; /* Check the default drive */ 144 intdos(&regs, &regs); 145 if (regs.x.ax != 0xFFFF) /* Drive is valid */ 146 available = (U32)regs.x.ax * regs.x.bx * regs.x.cx; 147 return (available); 148 } 149 #endif 150 151 static int _fastcall near CheckDiskSpace(long howmuch) 152 { 153 int EnoughSpace = FALSE; 154 #ifndef XFRACT 155 U32 available; 156 157 available = GetDiskSpace(); 158 if (available > (U32)howmuch) 159 EnoughSpace = TRUE; 160 #endif 161 #ifdef XFRACT
162 /* This will need to be fixed for XFRACT ????? */ 163 EnoughSpace = TRUE;
164 #endif 165 return(EnoughSpace); 166 } 167 168 static void WhichDiskError(int I_O) 169 { /* Set I_O == 1 after a file create, I_O == 2 after a file set value */ 170 /* Set I_O == 3 after a file write, I_O == 4 after a file read */ 171 #if (!defined(XFRACT) && !defined(WINFRACT)) 172 char buf[MSGLEN]; 173 char nmsg[MSGLEN]; 174 static FCODE fmsg1[] = {"Disk file creation error"}; 175 static FCODE fmsg2[] = {"Disk file set error"}; 176 static FCODE fmsg3[] = {"Disk file write error"}; 177 static FCODE fmsg4[] = {"Disk file read error"}; 178 179 /* The following and the associated sprintf eat up 432 bytes of near memory. 180 Only marginally useful for debugging purposes. 181 static FCODE fmsg1[] = {"Create file error %d: %s"}; 182 static FCODE fmsg2[] = {"Set file error %d: %s"}; 183 static FCODE fmsg3[] = {"Write file error %d: %s"}; 184 static FCODE fmsg4[] = {"Read file error %d: %s"}; 185 */ 186 switch (I_O) { 187 default: 188 case 1: 189 far_strcpy(nmsg,fmsg1); 190 break; 191 case 2: 192 far_strcpy(nmsg,fmsg2); 193 break; 194 case 3: 195 far_strcpy(nmsg,fmsg3); 196 break; 197 case 4: 198 far_strcpy(nmsg,fmsg4); 199 break; 200 } 201 sprintf(buf,nmsg); 202 /* 203 sprintf(buf,nmsg,errno,strerror(errno)); 204 */ 205 if (debugflag == 10000) 206 if(stopmsg(6,(char far *)buf) == -1) 207 goodbye(); /* bailout if ESC */ 208 #endif 209 } 210 211 #if (!defined(XFRACT) && !defined(WINFRACT)) 212 static void _fastcall near exp_seek(U16 handle, int page) /* expanded mem seek */ 213 { 214 static U16 lasthandle = 0; 215 if (page != handletable[handle].Expanded.oldexppage || page == 0 || 216 lasthandle != handle) { 217 /* time to get a new page? */ 218 handletable[handle].Expanded.oldexppage = page; 219 lasthandle = handle; 220 emmgetpage(page, handletable[handle].Expanded.emmhandle); 221 } 222 } 223 #endif 224 225 int MemoryType (U16 handle) 226 { 227 return (handletable[handle].Nowhere.stored_at); 228 } 229 230 static void DisplayError(int stored_at, long howmuch) 231 { 232 /* This routine is used to display an error message when the requested */ 233 /* memory type cannot be allocated due to insufficient memory, AND there */ 234 /* is also insufficient disk space to use as memory. */ 235 236 char buf[MSGLEN*2]; 237 char nmsg[MSGLEN*2]; 238 static FCODE fmsg[] = {"Allocating %ld Bytes of %s memory failed.\nAlternate disk space is also insufficient. Goodbye"}; 239 far_strcpy(nmsg,fmsg); 240 sprintf(buf,nmsg,howmuch,memstr[stored_at]); 241 stopmsg(0,(char far *)buf); 242 } 243 244 static int check_for_mem(int stored_at, long howmuch) 245 { 246 /* This function returns an adjusted stored_at value. */ 247 /* This is where the memory requested can be allocated. */ 248 249 #if (!defined(XFRACT) && !defined(WINFRACT)) 250 long usedmem, totalmem; 251 long longtmp; 252 int counter; 253 #endif 254 long maxmem; 255 BYTE far *temp; 256 int use_this_type; 257 258 use_this_type = NOWHERE; 259 maxmem = (long)USHRT_MAX; /* limit EXTRA and FARMEM to 64K */ 260 /* limit EXPANDED and EXTENDED to 64K blocks */ 261 262 if (debugflag == 420) 263 stored_at = DISK; 264 if (debugflag == 422) 265 stored_at = EXTENDED; 266 267 switch (stored_at) 268 { 269 #if (!defined(XFRACT) && !defined(WINFRACT)) 270 case EXTRA: /* check_for_mem */ 271 usedmem = 0L; 272 for(counter = 0; counter < MAXHANDLES; counter++) 273 if (handletable[counter].Nowhere.stored_at == EXTRA) 274 usedmem += handletable[counter].Extra.size; 275 if ((maxmem - usedmem) > howmuch) { 276 use_this_type = EXTRA; 277 break; 278 } 279 /* failed, fall through and try far memory */ 280 #endif 281 282 case FARMEM: /* check_for_mem */ 283 if (maxmem > howmuch) { 284 temp = (BYTE far *)farmemalloc(howmuch + FAR_RESERVE); 285 if (temp != NULL) { /* minimum free space + requested amount */ 286 farmemfree(temp); 287 use_this_type = FARMEM; 288 break; 289 } 290 } 291 292 #if (!defined(XFRACT) && !defined(WINFRACT)) 293 /* Failed, fall through and try expanded memory */ 294 case EXPANDED: /* check_for_mem */ 295 totalmem = (howmuch + 16383) >> 14; /* # of 16 KB blocks */ 296 if ((totalmem < (long)USHRT_MAX) && (emmquery() != NULL)) { 297 maxmem = emmgetfree(); /* reuse maxmem, so may not be good below */ 298 if (maxmem > totalmem) { 299 use_this_type = EXPANDED; 300 break; 301 } 302 } 303 /* Failed, fall through and try extended memory */ 304 305 case EXTENDED: /* check_for_mem */ 306 longtmp = (howmuch + 1023) >> 10; /* # of 1 KB blocks */ 307 if (longtmp <= 0) 308 longtmp = 1; 309 if (xmmquery() != 0) 310 if ((longtmp < (long)USHRT_MAX) && ((long)xmmfree() > longtmp)) { 311 use_this_type = EXTENDED; 312 break; 313 } 314 /* failed, fall through and try disk memory */ 315 #endif 316 317 case DISK: /* check_for_mem */ 318 default: /* just in case a nonsense number gets used */ 319 if (CheckDiskSpace(howmuch)) { 320 use_this_type = DISK; 321 break; 322 } 323 /* failed, fall through, no memory available */ 324 325 case NOWHERE: /* check_for_mem */ 326 use_this_type = NOWHERE; 327 break; 328 329 } /* end of switch */ 330 331 return(use_this_type); 332 } 333 334 static U16 next_handle() 335 { 336 U16 counter = 1; /* don't use handle 0 */ 337 338 while(handletable[counter].Nowhere.stored_at != NOWHERE && 339 counter < MAXHANDLES) 340 counter++; 341 return (counter); 342 } 343 344 static int CheckBounds (long start, long length, U16 handle) 345 { 346 if(handletable[handle].Nowhere.size - start - length < 0) 347 { 348 static FCODE msg[] = {"Memory reference out of bounds."}; 349 stopmsg(20,msg); 350 DisplayHandle(handle); 351 return (1); 352 } 353 if(length > (long)USHRT_MAX) 354 { 355 static FCODE msg[] = {"Tried to move > 65,535 bytes."}; 356 stopmsg(20,msg); 357 DisplayHandle(handle); 358 return (1); 359 } 360 if(handletable[handle].Nowhere.stored_at == DISK && 361 (stackavail() <= DISKWRITELEN) ) 362 { 363 static FCODE msg[] = {"Stack space insufficient for disk memory."}; 364 stopmsg(20,msg); 365 DisplayHandle(handle); 366 return (1); 367 } 368 if(length <= 0) 369 { 370 static FCODE msg[] = {"Zero or negative length."}; 371 stopmsg(20,msg); 372 DisplayHandle(handle); 373 return (1); 374 } 375 if(start < 0) 376 { 377 static FCODE msg[] = {"Negative offset."}; 378 stopmsg(20,msg); 379 DisplayHandle(handle); 380 return (1); 381 } 382 return (0); 383 } 384 385 void DisplayMemory (void) 386 { 387 #if (!defined(XFRACT) && !defined(WINFRACT)) 388 long tmpfar; 389 U32 tmpdisk; 390 char buf[MSGLEN]; 391 char nmsg[MSGLEN]; 392 /* #ifdef XFRACT static FCODE fmsg[] = {"far=%ld, disk=%lu"}; */ 393 static FCODE fmsg[] = {"extra=%ld, far=%ld, expanded=%ld,\nextended=%ld, disk=%lu"}; 394 long tmpextra, tmpexp, tmpext; 395 396 tmpextra = USHRT_MAX - start_avail_extra; 397 if (emmquery() != NULL) 398 tmpexp = (long)emmgetfree() * 16L * 1024L; 399 else 400 tmpexp = 0; 401 if (xmmquery() != 0) 402 tmpext = (long)xmmfree() * 1024L; 403 else 404 tmpext = 0; 405 tmpdisk = GetDiskSpace(); /* fix this for XFRACT ????? */ 406 407 tmpfar = fr_farfree(); 408 far_strcpy(nmsg,fmsg); 409 sprintf(buf,nmsg,tmpextra,tmpfar,tmpexp,tmpext,tmpdisk); 410 stopmsg(20,(char far *)buf); 411 #endif 412 } 413 414 void DisplayHandle (U16 handle) 415 { 416 char buf[MSGLEN]; 417 char nmsg[MSGLEN]; 418 static FCODE fmsg[] = {"Handle %u, type %s, size %li"}; 419 420 far_strcpy(nmsg,fmsg); 421 sprintf(buf,nmsg,handle,memstr[handletable[handle].Nowhere.stored_at], 422 handletable[handle].Nowhere.size); 423 if(stopmsg(6,(char far *)buf) == -1) 424 goodbye(); /* bailout if ESC, it's messy, but should work */ 425 } 426 427 void InitMemory (void) 428 { 429 int counter; 430 #if (!defined(XFRACT) && !defined(WINFRACT)) 431 long longtmp; 432 #endif 433 434 numTOTALhandles = 0; 435 for (counter = 0; counter < MAXHANDLES; counter++) { 436 handletable[counter].Nowhere.stored_at = NOWHERE; 437 handletable[counter].Nowhere.size = 0; 438 } 439 #if (!defined(XFRACT) && !defined(WINFRACT)) 440 numEXThandles = 0; 441 longtmp = fr_farfree(); 442 ext_xfer_size = XMMWRITELEN; /* 8192 */ 443 if (longtmp < (long)XMMWRITELEN * 8) 444 ext_xfer_size = XMMWRITELEN / 2; /* 4096 */ 445 if (longtmp < (long)XMMWRITELEN) 446 ext_xfer_size = XMMWRITELEN / 8; /* 1024, won't work, try anyway */ 447 #endif 448 } 449 450 void ExitCheck (void) 451 { 452 U16 i; 453 if(/*charbuf != NULL ||*/ numEXThandles != 0 || numTOTALhandles != 0) { 454 static FCODE msg[] = {"Error - not all memory released, I'll get it."}; 455 stopmsg(0,msg); 456 for (i = 1; i < MAXHANDLES; i++) 457 if (handletable[i].Nowhere.stored_at != NOWHERE) { 458 char buf[MSGLEN]; 459 char nmsg[MSGLEN]; 460 static FCODE fmsg[] = {"Memory type %s still allocated. Handle = %i."}; 461 far_strcpy(nmsg,fmsg); 462 sprintf(buf,nmsg,memstr[handletable[i].Nowhere.stored_at],i); 463 stopmsg(0,(char far *)buf); 464 MemoryRelease(i); 465 } 466 } 467 } 468 469 /* * * * * */ 470 /* Memory handling routines */ 471 472 U16 MemoryAlloc(U16 size, long count, int stored_at) 473 { 474 /* Returns handle number if successful, 0 or NULL if failure */ 475 U16 handle = 0; 476 int success, use_this_type; 477 long toallocate; 478 479 #if (!defined(XFRACT) && !defined(WINFRACT)) 480 BYTE far *temp; 481 long longtmp; 482 int mempages = 0; 483 struct XMM_Move MoveStruct; 484 #endif 485 486 success = FALSE; 487 toallocate = count * size; 488 if (toallocate <= 0) /* we failed, can't allocate > 2,147,483,647 */ 489 return((U16)success); /* or it wraps around to negative */ 490 491 /* check structure for requested memory type (add em up) to see if 492 sufficient amount is available to grant request */ 493 494 use_this_type = check_for_mem(stored_at, toallocate); 495 if (use_this_type == NOWHERE) { 496 DisplayError(stored_at, toallocate); 497 goodbye(); 498 } 499 500 /* get next available handle */ 501 502 handle = next_handle(); 503 504 if (handle >= MAXHANDLES || handle <= 0) { 505 DisplayHandle(handle); 506 return((U16)success); 507 /* Oops, do something about this! ????? */ 508 } 509 510 /* attempt to allocate requested memory type */ 511 switch (use_this_type) 512 { 513 default: 514 case NOWHERE: /* MemoryAlloc */ 515 use_this_type = NOWHERE; /* in case nonsense value is passed */ 516 break; 517 518 #if (!defined(XFRACT) && !defined(WINFRACT)) 519 case EXTRA: /* MemoryAlloc */ 520 handletable[handle].Extra.size = toallocate; 521 handletable[handle].Extra.stored_at = EXTRA; 522 handletable[handle].Extra.extramemory = (BYTE far *)MK_FP(extraseg,start_avail_extra); 523 start_avail_extra += (U16)toallocate; 524 numTOTALhandles++; 525 success = TRUE; 526 break; 527 #endif 528 529 case FARMEM: /* MemoryAlloc */ 530 /* Availability of far memory checked in check_for_mem() */ 531 handletable[handle].Farmem.farmemory = (BYTE far *)farmemalloc(toallocate); 532 handletable[handle].Farmem.size = toallocate; 533 handletable[handle].Farmem.stored_at = FARMEM; 534 numTOTALhandles++; 535 success = TRUE; 536 break; 537 538 #if (!defined(XFRACT) && !defined(WINFRACT)) 539 case EXPANDED: /* MemoryAlloc */ 540 mempages = (int)((toallocate + 16383) >> 14); 541 if (emmquery() != NULL) { 542 handletable[handle].Expanded.mempages = mempages; 543 handletable[handle].Expanded.expmemory = emmquery(); 544 if ((handletable[handle].Expanded.emmhandle = emmallocate(mempages)) != 0) { 545 handletable[handle].Expanded.oldexppage = 0; 546 handletable[handle].Expanded.size = toallocate; 547 handletable[handle].Expanded.stored_at = EXPANDED; 548 numTOTALhandles++; 549 success = TRUE; 550 break; 551 } 552 } 553 554 case EXTENDED: /* MemoryAlloc */ 555 /* This is ugly! Need far memory to use extended memory. */ 556 if (charbuf == NULL) { /* first time through, allocate buffer */ 557 temp = (BYTE far *)farmemalloc((long)ext_xfer_size + FAR_RESERVE); 558 if (temp != NULL) /* minimum free space + requested amount */ 559 { 560 farmemfree(temp); 561 charbuf = (BYTE far *)farmemalloc((long)ext_xfer_size); 562 } 563 else 564 goto dodisk; 565 } 566 if (toallocate < ext_xfer_size) 567 longtmp = (ext_xfer_size + 1023) >> 10; 568 else 569 longtmp = (toallocate + 1023) >> 10; 570 if (xmmquery() != 0 571 && (handletable[handle].Extended.xmmhandle = xmmallocate((U16)(longtmp))) != 0) 572 { 573 longtmp /= (ext_xfer_size >> 10); 574 handletable[handle].Extended.mempages = (int)longtmp; 575 far_memset(charbuf, 0, (int)ext_xfer_size); /* zero the buffer */ 576 MoveStruct.SourceHandle = 0; /* Source is in conventional memory */ 577 MoveStruct.SourceOffset = (U32)charbuf; 578 MoveStruct.DestHandle = handletable[handle].Extended.xmmhandle; 579 MoveStruct.DestOffset = 0; 580 MoveStruct.Length = (long)ext_xfer_size; 581 while (--longtmp >= 0) { 582 if ((success = xmmmoveextended(&MoveStruct)) == 0) break; 583 MoveStruct.DestOffset += ext_xfer_size; 584 } 585 if (success) { 586 /* put in structure */ 587 success = TRUE; 588 handletable[handle].Extended.size = toallocate; 589 handletable[handle].Extended.stored_at = EXTENDED; 590 numTOTALhandles++; 591 numEXThandles++; 592 break; 593 } 594 xmmdeallocate(handletable[handle].Extended.xmmhandle); /* Clear the memory */ 595 handletable[handle].Extended.xmmhandle = 0; /* Signal same */ 596 } 597 /* need to fall through and use disk memory, or will crash fractint */ 598 dodisk: 599 #endif 600 case DISK: /* MemoryAlloc */ 601 memfile[9] = (char)(handle % 10 + (int)'0'); 602 memfile[8] = (char)((handle % 100) / 10 + (int)'0'); 603 memfile[7] = (char)((handle % 1000) / 100 + (int)'0'); 604 if (disktarga) 605 handletable[handle].Disk.file = dir_fopen(workdir,light_name, "a+b"); 606 else 607 handletable[handle].Disk.file = dir_fopen(tempdir,memfile, "w+b"); 608 rewind(handletable[handle].Disk.file); 609 if (fseek(handletable[handle].Disk.file,toallocate,SEEK_SET) != 0) 610 handletable[handle].Disk.file = NULL; 611 if (handletable[handle].Disk.file == NULL) { 612 handletable[handle].Disk.stored_at = NOWHERE; 613 use_this_type = NOWHERE; 614 WhichDiskError(1); 615 DisplayMemory(); 616 buzzer(3); 617 break; 618 } 619 numTOTALhandles++; 620 success = TRUE; 621 fclose(handletable[handle].Disk.file); /* so clusters aren't lost if we crash while running */ 622 if (disktarga) 623 handletable[handle].Disk.file = dir_fopen(workdir,light_name, "r+b"); 624 else 625 handletable[handle].Disk.file = dir_fopen(tempdir,memfile,"r+b"); /* reopen */ 626 rewind(handletable[handle].Disk.file); 627 handletable[handle].Disk.size = toallocate; 628 handletable[handle].Disk.stored_at = DISK; 629 use_this_type = DISK; 630 break; 631 } /* end of switch */ 632 633 if (stored_at != use_this_type && debugflag == 10000) { 634 char buf[MSGLEN]; 635 char nmsg[MSGLEN]; 636 static FCODE fmsg[] = {"Asked for %s, allocated %lu bytes of %s, handle = %u."}; 637 far_strcpy(nmsg,fmsg); 638 sprintf(buf,nmsg,memstr[stored_at],toallocate,memstr[use_this_type],handle); 639 stopmsg(20,(char far *)buf); 640 DisplayMemory(); 641 } 642 643 if (success) 644 return (handle); 645 else /* return 0 if failure */ 646 return 0; 647 } 648 649 void MemoryRelease(U16 handle) 650 { 651 switch(handletable[handle].Nowhere.stored_at) 652 { 653 case NOWHERE: /* MemoryRelease */ 654 break; 655 656 #if (!defined(XFRACT) && !defined(WINFRACT)) 657 case EXTRA: /* MemoryRelease */ 658 /* Deallocate in the reverse order of allocation. */ 659 start_avail_extra -= (U16)handletable[handle].Extra.size; 660 handletable[handle].Extra.size = 0; 661 handletable[handle].Extra.stored_at = NOWHERE; 662 handletable[handle].Extra.extramemory = NULL; 663 numTOTALhandles--; 664 break; 665 #endif 666 667 case FARMEM: /* MemoryRelease */ 668 farmemfree(handletable[handle].Farmem.farmemory); 669 handletable[handle].Farmem.farmemory = NULL; 670 handletable[handle].Farmem.size = 0; 671 handletable[handle].Farmem.stored_at = NOWHERE; 672 numTOTALhandles--; 673 break; 674 675 #if (!defined(XFRACT) && !defined(WINFRACT)) 676 case EXPANDED: /* MemoryRelease */ 677 emmdeallocate(handletable[handle].Expanded.emmhandle); 678 handletable[handle].Expanded.emmhandle = 0; 679 handletable[handle].Expanded.size = 0; 680 handletable[handle].Expanded.stored_at = NOWHERE; 681 numTOTALhandles--; 682 break; 683 684 case EXTENDED: /* MemoryRelease */ 685 /* far memory allocated for this must be released */ 686 numEXThandles--; 687 xmmdeallocate(handletable[handle].Extended.xmmhandle); 688 if (numEXThandles == 0) { 689 farmemfree(charbuf); 690 charbuf = NULL; 691 } 692 handletable[handle].Extended.xmmhandle = 0; 693 handletable[handle].Extended.size = 0; 694 handletable[handle].Extended.stored_at = NOWHERE; 695 numTOTALhandles--; 696 break; 697 #endif 698 699 case DISK: /* MemoryRelease */ 700 memfile[9] = (char)(handle % 10 + (int)'0'); 701 memfile[8] = (char)((handle % 100) / 10 + (int)'0'); 702 memfile[7] = (char)((handle % 1000) / 100 + (int)'0'); 703 fclose(handletable[handle].Disk.file); 704 dir_remove(tempdir,memfile); 705 handletable[handle].Disk.file = NULL; 706 handletable[handle].Disk.size = 0; 707 handletable[handle].Disk.stored_at = NOWHERE; 708 numTOTALhandles--; 709 break; 710 } /* end of switch */ 711 } 712 713 int MoveToMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle) 714 { /* buffer is a pointer to local memory */ 715 /* Always start moving from the beginning of buffer */ 716 /* offset is the number of units from the start of the allocated "Memory" */ 717 /* to start moving the contents of buffer to */ 718 /* size is the size of the unit, count is the number of units to move */ 719 /* Returns TRUE if successful, FALSE if failure */ 720 #if (!defined(XFRACT) && !defined(WINFRACT)) 721 int currpage; 722 long tmplength; 723 struct XMM_Move MoveStruct; 724 #endif 725 BYTE diskbuf[DISKWRITELEN]; 726 long start; /* offset to first location to move to */ 727 long tomove; /* number of bytes to move */ 728 U16 numwritten, i; 729 int success; 730 731 success = FALSE; 732 start = (long)offset * size; 733 tomove = (long)count * size; 734 if (debugflag == 10000) 735 if (CheckBounds(start, tomove, handle)) 736 return(success); /* out of bounds, don't do it */ 737 738 switch(handletable[handle].Nowhere.stored_at) 739 { 740 case NOWHERE: /* MoveToMemory */ 741 DisplayHandle(handle); 742 break; 743 744 #if (!defined(XFRACT) && !defined(WINFRACT)) 745 case EXTRA: /* MoveToMemory */ 746 far_memcpy(handletable[handle].Extra.extramemory+start, buffer, (U16)tomove); 747 success = TRUE; /* No way to gauge success or failure */ 748 break; 749 #endif 750 751 case FARMEM: /* MoveToMemory */ 752 for(i=0;i<size;i++) { 753 far_memcpy(handletable[handle].Farmem.farmemory+start, buffer, (U16)count); 754 start += count; 755 buffer += count; 756 } 757 success = TRUE; /* No way to gauge success or failure */ 758 break; 759 760 #if (!defined(XFRACT) && !defined(WINFRACT)) 761 case EXPANDED: /* MoveToMemory */ 762 currpage = (int)(start / EXPWRITELEN); 763 exp_seek(handle, currpage); 764 /* Not on a page boundary, move data up to next page boundary */ 765 tmplength = (currpage + 1) * EXPWRITELEN - start; 766 start -= (currpage * EXPWRITELEN); 767 if (tmplength > tomove) 768 tmplength = tomove; 769 far_memcpy(handletable[handle].Expanded.expmemory+start, buffer, (U16)tmplength); 770 buffer += tmplength; 771 tomove -= tmplength; 772 /* At a page boundary, move until less than a page left */ 773 while (tomove >= EXPWRITELEN) 774 { 775 currpage++; 776 exp_seek(handle, currpage); 777 far_memcpy(handletable[handle].Expanded.expmemory, buffer, (U16)EXPWRITELEN); 778 buffer += EXPWRITELEN; 779 tomove -= EXPWRITELEN; 780 } 781 /* Less than a page left, move it */ 782 if (tomove > 0) /* still some left */ 783 { 784 currpage++; 785 exp_seek(handle, currpage); 786 far_memcpy(handletable[handle].Expanded.expmemory, buffer, (U16)tomove); 787 } 788 exp_seek(handle, 0); /* flush the last page out of the page frame */ 789 success = TRUE; /* No way to gauge success or failure */ 790 break; 791 792 case EXTENDED: /* MoveToMemory */ 793 MoveStruct.Length = ext_xfer_size; 794 MoveStruct.SourceHandle = 0; /* Source is conventional memory */ 795 MoveStruct.SourceOffset = (U32)charbuf; 796 MoveStruct.DestHandle = handletable[handle].Extended.xmmhandle; 797 MoveStruct.DestOffset = (U32)start; 798 while (tomove > ext_xfer_size) 799 { 800 far_memcpy(charbuf,buffer,(int)ext_xfer_size); 801 xmmmoveextended(&MoveStruct); 802 start += ext_xfer_size; 803 tomove -= ext_xfer_size; 804 buffer += ext_xfer_size; 805 MoveStruct.DestOffset = (U32)(start); 806 } 807 far_memcpy(charbuf,buffer,(U16)tomove); 808 MoveStruct.Length = (tomove % 2) ? tomove + 1 : tomove; /* must be even */ 809 success = xmmmoveextended(&MoveStruct); 810 break; 811 #endif 812 813 case DISK: /* MoveToMemory */ 814 rewind(handletable[handle].Disk.file); 815 fseek(handletable[handle].Disk.file,start,SEEK_SET); 816 while (tomove > DISKWRITELEN) 817 { 818 far_memcpy(diskbuf,buffer,(U16)DISKWRITELEN); 819 numwritten = (U16)write1(diskbuf,(U16)DISKWRITELEN,1,handletable[handle].Disk.file); 820 if (numwritten != 1) { 821 WhichDiskError(3); 822 goto diskerror; 823 } 824 tomove -= DISKWRITELEN; 825 buffer += DISKWRITELEN; 826 } 827 far_memcpy(diskbuf,buffer,(U16)tomove); 828 numwritten = (U16)write1(diskbuf,(U16)tomove,1,handletable[handle].Disk.file); 829 if (numwritten != 1) { 830 WhichDiskError(3); 831 break; 832 } 833 success = TRUE; 834 diskerror: 835 break; 836 } /* end of switch */ 837 if (!success && debugflag == 10000) 838 DisplayHandle(handle); 839 return (success); 840 } 841 842 int MoveFromMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle) 843 { /* buffer points is the location to move the data to */ 844 /* offset is the number of units from the beginning of buffer to start moving */ 845 /* size is the size of the unit, count is the number of units to move */ 846 /* Returns TRUE if successful, FALSE if failure */ 847 #if (!defined(XFRACT) && !defined(WINFRACT)) 848 int currpage; 849 long tmplength; 850 struct XMM_Move MoveStruct; 851 #endif 852 BYTE diskbuf[DISKWRITELEN]; 853 long start; /* first location to move */ 854 long tomove; /* number of bytes to move */ 855 U16 numread, i; 856 int success; 857 858 success = FALSE; 859 start = (long)offset * size; 860 tomove = (long)count * size; 861 if (debugflag == 10000) 862 if (CheckBounds(start, tomove, handle)) 863 return(success); /* out of bounds, don't do it */ 864 865 switch(handletable[handle].Nowhere.stored_at) 866 { 867 case NOWHERE: /* MoveFromMemory */ 868 DisplayHandle(handle); 869 break; 870 871 #if (!defined(XFRACT) && !defined(WINFRACT)) 872 case EXTRA: /* MoveFromMemory */ 873 far_memcpy(buffer, handletable[handle].Extra.extramemory+start, (U16)tomove); 874 success = TRUE; /* No way to gauge success or failure */ 875 break; 876 #endif 877 878 case FARMEM: /* MoveFromMemory */ 879 for(i=0;i<size;i++) { 880 far_memcpy(buffer, handletable[handle].Farmem.farmemory+start, (U16)count); 881 start += count; 882 buffer += count; 883 } 884 success = TRUE; /* No way to gauge success or failure */ 885 break; 886 887 #if (!defined(XFRACT) && !defined(WINFRACT)) 888 case EXPANDED: /* MoveFromMemory */ 889 currpage = (int)(start / EXPWRITELEN); 890 exp_seek(handle, currpage); 891 /* Not on a page boundary, move data up to next page boundary */ 892 tmplength = (currpage + 1) * EXPWRITELEN - start; 893 start -= (currpage * EXPWRITELEN); 894 if (tmplength > tomove) 895 tmplength = tomove; 896 far_memcpy(buffer, handletable[handle].Expanded.expmemory+start, (U16)tmplength); 897 buffer += tmplength; 898 tomove -= tmplength; 899 /* At a page boundary, move until less than a page left */ 900 while (tomove >= EXPWRITELEN) 901 { 902 currpage++; 903 exp_seek(handle, currpage); 904 far_memcpy(buffer, handletable[handle].Expanded.expmemory, (U16)EXPWRITELEN); 905 buffer += EXPWRITELEN; 906 tomove -= EXPWRITELEN; 907 } 908 /* Less than a page left, move it */ 909 if (tomove > 0) /* still some left */ 910 { 911 currpage++; 912 exp_seek(handle, currpage); 913 far_memcpy(buffer, handletable[handle].Expanded.expmemory, (U16)tomove); 914 } 915 exp_seek(handle, 0); /* flush the last page out of the page frame */ 916 success = TRUE; /* No way to gauge success or failure */ 917 break; 918 919 case EXTENDED: /* MoveFromMemory */ 920 MoveStruct.Length = ext_xfer_size; 921 MoveStruct.SourceHandle = handletable[handle].Extended.xmmhandle; 922 MoveStruct.SourceOffset = (U32)start; 923 MoveStruct.DestHandle = 0; /* Destination is conventional memory */ 924 MoveStruct.DestOffset = (U32)charbuf; 925 while (tomove > ext_xfer_size) 926 { 927 xmmmoveextended(&MoveStruct); 928 far_memcpy(buffer,charbuf,(int)ext_xfer_size); 929 buffer += ext_xfer_size; 930 tomove -= ext_xfer_size; 931 start += ext_xfer_size; 932 MoveStruct.SourceOffset = (U32)start; 933 } 934 MoveStruct.Length = (tomove % 2) ? tomove + 1 : tomove; /* must be even */ 935 success = xmmmoveextended(&MoveStruct); 936 far_memcpy(buffer,charbuf,(U16)tomove); 937 break; 938 #endif 939 940 case DISK: /* MoveFromMemory */ 941 rewind(handletable[handle].Disk.file); 942 fseek(handletable[handle].Disk.file,start,SEEK_SET); 943 while (tomove > DISKWRITELEN) 944 { 945 numread = (U16)fread(diskbuf,(U16)DISKWRITELEN,1,handletable[handle].Disk.file); 946 if (numread != 1 && !feof(handletable[handle].Disk.file)) { 947 WhichDiskError(4); 948 goto diskerror; 949 } 950 far_memcpy(buffer,diskbuf,(U16)DISKWRITELEN); 951 tomove -= DISKWRITELEN; 952 buffer += DISKWRITELEN; 953 } 954 numread = (U16)fread(diskbuf,(U16)tomove,1,handletable[handle].Disk.file); 955 if (numread != 1 && !feof(handletable[handle].Disk.file)) { 956 WhichDiskError(4); 957 break; 958 } 959 far_memcpy(buffer,diskbuf,(U16)tomove); 960 success = TRUE; 961 diskerror: 962 break; 963 } /* end of switch */ 964 if (!success && debugflag == 10000) 965 DisplayHandle(handle); 966 return (success); 967 } 968 969 int SetMemory(int value,U16 size,long count,long offset,U16 handle) 970 { /* value is the value to set memory to */ 971 /* offset is the number of units from the start of allocated memory */ 972 /* size is the size of the unit, count is the number of units to set */ 973 /* Returns TRUE if successful, FALSE if failure */ 974 #if (!defined(XFRACT) && !defined(WINFRACT)) 975 int currpage; 976 long tmplength; 977 struct XMM_Move MoveStruct; 978 #endif 979 BYTE diskbuf[DISKWRITELEN]; 980 long start; /* first location to set */ 981 long tomove; /* number of bytes to set */ 982 U16 numwritten, i; 983 int success; 984 985 success = FALSE; 986 start = (long)offset * size; 987 tomove = (long)count * size; 988 if (debugflag == 10000) 989 if (CheckBounds(start, tomove, handle)) 990 return(success); /* out of bounds, don't do it */ 991 992 switch(handletable[handle].Nowhere.stored_at) 993 { 994 case NOWHERE: /* SetMemory */ 995 DisplayHandle(handle); 996 break; 997 998 #if (!defined(XFRACT) && !defined(WINFRACT)) 999 case EXTRA: /* SetMemory */ 1000 far_memset(handletable[handle].Extra.extramemory+start, value, (U16)tomove); 1001 success = TRUE; /* No way to gauge success or failure */ 1002 break; 1003 #endif 1004 1005 case FARMEM: /* SetMemory */ 1006 for(i=0;i<size;i++) { 1007 far_memset(handletable[handle].Farmem.farmemory+start, value, (U16)count); 1008 start += count; 1009 } 1010 success = TRUE; /* No way to gauge success or failure */ 1011 break; 1012 1013 #if (!defined(XFRACT) && !defined(WINFRACT)) 1014 case EXPANDED: /* SetMemory */ 1015 currpage = (int)(start / EXPWRITELEN); 1016 exp_seek(handle, currpage); 1017 /* Not on a page boundary, move data up to next page boundary */ 1018 tmplength = (currpage + 1) * EXPWRITELEN - start; 1019 start -= (currpage * EXPWRITELEN); 1020 if (tmplength > tomove) 1021 tmplength = tomove; 1022 far_memset(handletable[handle].Expanded.expmemory+start, value, (U16)tmplength); 1023 tomove -= tmplength; 1024 /* At a page boundary, move until less than a page left */ 1025 while (tomove >= EXPWRITELEN) 1026 { 1027 currpage++; 1028 exp_seek(handle, currpage); 1029 far_memcpy(handletable[handle].Expanded.expmemory, &value, (U16)EXPWRITELEN); 1030 tomove -= EXPWRITELEN; 1031 } 1032 /* Less than a page left, move it */ 1033 if (tomove > 0) /* still some left */ 1034 { 1035 currpage++; 1036 exp_seek(handle, currpage); 1037 far_memcpy(handletable[handle].Expanded.expmemory, &value, (U16)tomove); 1038 } 1039 exp_seek(handle, 0); /* flush the last page out of the page frame */ 1040 success = TRUE; /* No way to gauge success or failure */ 1041 break; 1042 1043 case EXTENDED: /* SetMemory */ 1044 MoveStruct.Length = ext_xfer_size; 1045 MoveStruct.SourceHandle = 0; /* Source is conventional memory */ 1046 MoveStruct.SourceOffset = (U32)charbuf; 1047 MoveStruct.DestHandle = handletable[handle].Extended.xmmhandle; 1048 MoveStruct.DestOffset = (U32)start; 1049 far_memset(charbuf, value, (int)ext_xfer_size); 1050 while (tomove > ext_xfer_size) 1051 { 1052 xmmmoveextended(&MoveStruct); 1053 start += ext_xfer_size; 1054 tomove -= ext_xfer_size; 1055 MoveStruct.DestOffset = (U32)(start); 1056 } 1057 MoveStruct.Length = (tomove % 2) ? tomove + 1 : tomove; /* must be even */ 1058 success = xmmmoveextended(&MoveStruct); 1059 break; 1060 #endif 1061 1062 case DISK: /* SetMemory */ 1063 far_memset(diskbuf, value, (U16)DISKWRITELEN); 1064 rewind(handletable[handle].Disk.file); 1065 fseek(handletable[handle].Disk.file,start,SEEK_SET); 1066 while (tomove > DISKWRITELEN) 1067 { 1068 numwritten = (U16)write1(diskbuf,(U16)DISKWRITELEN,1,handletable[handle].Disk.file); 1069 if (numwritten != 1) { 1070 WhichDiskError(2); 1071 goto diskerror; 1072 } 1073 tomove -= DISKWRITELEN; 1074 } 1075 numwritten = (U16)write1(diskbuf,(U16)tomove,1,handletable[handle].Disk.file); 1076 if (numwritten != 1) { 1077 WhichDiskError(2); 1078 break; 1079 } 1080 success = TRUE; 1081 diskerror: 1082 break; 1083 } /* end of switch */ 1084 if (!success && debugflag == 10000) 1085 DisplayHandle(handle); 1086 return (success); 1087 } 1088 1089