From 1904482def2e58fb628c175c0554cfe21209b7b3 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Wed, 29 Jul 2015 08:50:17 -0500 Subject: [PATCH] wwww WHAT!? modified: 16.hed new file: 16/exmmtest/16_ca.c new file: 16/exmmtest/16_ca.h new file: 16/exmmtest/16_head.c new file: 16/exmmtest/16_head.h new file: 16/exmmtest/16_mm.c new file: 16/exmmtest/16_mm.h new file: 16/exmmtest/EX.DSK new file: 16/exmmtest/EX.PRJ new file: 16/exmmtest/EXMMTEST.EXE modified: 16/exmmtest/exmmtest.c deleted: DEBUG.16 deleted: MMDUMP.16 deleted: PROFILE.16 --- 16.hed | Bin 25921 -> 30585 bytes 16/exmmtest/16_ca.c | 2232 ++++++++++++++++++++++++++++++++++++++ 16/exmmtest/16_ca.h | 116 ++ 16/exmmtest/16_head.c | 285 +++++ 16/exmmtest/16_head.h | 176 +++ 16/exmmtest/16_mm.c | 1590 +++++++++++++++++++++++++++ 16/exmmtest/16_mm.h | 192 ++++ 16/exmmtest/EX.DSK | Bin 0 -> 1298 bytes 16/exmmtest/EX.PRJ | Bin 0 -> 6727 bytes 16/exmmtest/EXMMTEST.EXE | Bin 0 -> 11318 bytes 16/exmmtest/exmmtest.c | 15 +- DEBUG.16 | 16 - MMDUMP.16 | Bin 396 -> 0 bytes PROFILE.16 | 0 14 files changed, 4600 insertions(+), 22 deletions(-) create mode 100644 16/exmmtest/16_ca.c create mode 100644 16/exmmtest/16_ca.h create mode 100644 16/exmmtest/16_head.c create mode 100644 16/exmmtest/16_head.h create mode 100644 16/exmmtest/16_mm.c create mode 100644 16/exmmtest/16_mm.h create mode 100644 16/exmmtest/EX.DSK create mode 100644 16/exmmtest/EX.PRJ create mode 100644 16/exmmtest/EXMMTEST.EXE delete mode 100644 DEBUG.16 delete mode 100644 MMDUMP.16 delete mode 100644 PROFILE.16 diff --git a/16.hed b/16.hed index 1f61dec08967fc7654feb718b4bb9ae789b14972..6814787e9899c385b679ad06b6fc02d0ef866272 100644 GIT binary patch literal 30585 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 is a pointer to a node +} huffnode; + + +/*typedef struct +{ + unsigned RLEWtag; + long headeroffsets[100]; + byte tileinfo[]; +} mapfiletype;*/ + + +/* +============================================================================= + + GLOBAL VARIABLES + +============================================================================= +*/ + +/*byte _seg *tinf; +int mapon; + +unsigned _seg *mapsegs[3]; +maptype _seg *mapheaderseg[NUMMAPS]; +byte _seg *audiosegs[NUMSNDCHUNKS]; +void _seg *grsegs[NUMCHUNKS]; + +byte far grneeded[NUMCHUNKS]; +byte ca_levelbit,ca_levelnum;*/ + +int profilehandle,debughandle; + +void (*drawcachebox) (char *title, unsigned numcache); +void (*updatecachebox) (void); +void (*finishcachebox) (void); + +/* +============================================================================= + + LOCAL VARIABLES + +============================================================================= +*/ + +/*extern long far CGAhead; +extern long far EGAhead; +extern byte CGAdict; +extern byte EGAdict; +extern byte far maphead; +extern byte mapdict; +extern byte far audiohead; +extern byte audiodict; + + +long _seg *grstarts; // array of offsets in egagraph, -1 for sparse +long _seg *audiostarts; // array of offsets in audio / audiot + +#ifdef GRHEADERLINKED +huffnode *grhuffman; +#else +huffnode grhuffman[255]; +#endif + +#ifdef AUDIOHEADERLINKED +huffnode *audiohuffman; +#else +huffnode audiohuffman[255]; +#endif + + +int grhandle; // handle to EGAGRAPH +int maphandle; // handle to MAPTEMP / GAMEMAPS +int audiohandle; // handle to AUDIOT / AUDIO + +long chunkcomplen,chunkexplen; + +SDMode oldsoundmode; + + + +void CAL_DialogDraw (char *title,unsigned numcache); +void CAL_DialogUpdate (void); +void CAL_DialogFinish (void);*/ +//void CAL_CarmackExpand (unsigned far *source, unsigned far *dest,unsigned length); + + +/*++++#ifdef THREEBYTEGRSTARTS +#define FILEPOSSIZE 3 +//#define GRFILEPOS(c) (*(long far *)(((byte far *)grstarts)+(c)*3)&0xffffff) +long GRFILEPOS(int c) +{ + long value; + int offset; + + offset = c*3; + + value = *(long far *)(((byte far *)grstarts)+offset); + + value &= 0x00ffffffl; + + if (value == 0xffffffl) + value = -1; + + return value; +}; +#else +#define FILEPOSSIZE 4 +#define GRFILEPOS(c) (grstarts[c]) +#endif*/ + +/* +============================================================================= + + LOW LEVEL ROUTINES + +============================================================================= +*/ + +/* +============================ += += CA_OpenDebug / CA_CloseDebug += += Opens a binary file with the handle "debughandle" += +============================ +*/ +void CA_OpenDebug(void) +{ + unlink("debug.16"); + debughandle = open("debug.16", O_CREAT | O_WRONLY | O_TEXT); +} + +void CA_CloseDebug(void) +{ + close(debughandle); +} + + + +/* +============================ += += CAL_GetGrChunkLength += += Gets the length of an explicit length chunk (not tiles) += The file pointer is positioned so the compressed data can be read in next. += +============================ +*/ +/*++++ +void CAL_GetGrChunkLength (int chunk) +{ + lseek(grhandle,GRFILEPOS(chunk),SEEK_SET); + read(grhandle,&chunkexplen,sizeof(chunkexplen)); + chunkcomplen = GRFILEPOS(chunk+1)-GRFILEPOS(chunk)-4; +}*/ + + +/* +========================== += += CA_FarRead += += Read from a file to a far pointer += +========================== +*/ + +boolean CA_FarRead(int handle, byte huge *dest, dword length, mminfo_t *mm) +{ + boolean flag; + /*dword fat=0; + word segm=0; + //if(mm->EMSVer<0x40) + if(length>0xfffflu) + { + printf("File is a fat bakapee\n"); + segm=(length%0xfffflu)-1; + fat=segm*0xfffflu; + length-=fat; +// printf("CA_FarRead doesn't support 64K reads yet!\n"); + } + + if(!fat&&!segm) + {*/ + __asm + { + push ds + mov bx,[handle] + mov cx,[WORD PTR length] + mov dx,[WORD PTR dest] + mov ds,[WORD PTR dest+2] + mov ah,0x3f // READ w/handle + int 21h + pop ds + jnc good + mov errno,ax + mov flag,0 + jmp End +good: + cmp ax,[WORD PTR length] + je done +// errno = EINVFMT; // user manager knows this is bad read + mov flag,0 + jmp End +done: + mov flag,1 +End: + } + return flag; + //}else return 0;//todo: EXPAND!!! +} + + +/* +========================== += += CA_SegWrite += += Write from a file to a far pointer += +========================== +*/ + +boolean CA_FarWrite(int handle, byte huge *source, dword length, mminfo_t *mm) +{ + boolean flag; + /*dword fat=0; + word segm=0; + //if(mm->EMSVer<0x40) + if(length>0xfffflu) + { + printf("File is a fat bakapee\n"); + segm=(length%0xfffflu)-1; + fat=segm*0xfffflu; + length-=fat; +// printf("CA_FarRead doesn't support 64K reads yet!\n"); + } + + if(!fat&&!segm) + {*/ + __asm + { + push ds + mov bx,[handle] + mov cx,[WORD PTR length] + mov dx,[WORD PTR source] + mov ds,[WORD PTR source+2] + mov ah,0x40 // WRITE w/handle + int 21h + pop ds + jnc good + mov errno,ax + mov flag,0 + jmp End +good: + cmp ax,[WORD PTR length] + je done + //errno = ENOMEM; // user manager knows this is bad write + mov flag,0 + jmp End +done: + mov flag,1 +End: + } + return flag; + //}else return 0; +} + + +/* +========================== += += CA_ReadFile += += Reads a file into an allready allocated buffer += +========================== +*/ + +boolean CA_ReadFile(char *filename, memptr *ptr, mminfo_t *mm) +{ + int handle; + dword size; + //long size; + + if((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1) + return false; + + size = filelength(handle); + if(!CA_FarRead(handle,*ptr,size, mm)) + { + close(handle); + return false; + } + close(handle); + return true; +} + + + +/* +========================== += += CA_LoadFile += += Allocate space for and load a file += +========================== +*/ + +boolean CA_LoadFile(char *filename, memptr *ptr, mminfo_t *mm, mminfotype *mmi) +{ + int handle; + dword size; + //long size; + + if((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1) + return false; + + size = filelength (handle); + MM_GetPtr(ptr,size, mm, mmi); + if(!CA_FarRead(handle,*ptr,size, mm)) + { + close(handle); + return false; + } + close(handle); + return true; +} + +/* +============================================================================ + + COMPRESSION routines, see JHUFF.C for more + +============================================================================ +*/ + + + +/* +=============== += += CAL_OptimizeNodes += += Goes through a huffman table and changes the 256-511 node numbers to the += actular address of the node. Must be called before CAL_HuffExpand += +=============== +*/ + +void CAL_OptimizeNodes(huffnode *table) +{ + huffnode *node; + int i; + + node = table; + + for (i=0;i<255;i++) + { + if (node->bit0 >= 256) + node->bit0 = (unsigned)(table+(node->bit0-256)); + if (node->bit1 >= 256) + node->bit1 = (unsigned)(table+(node->bit1-256)); + node++; + } +} + + + +/* +====================== += += CAL_HuffExpand += += Length is the length of the EXPANDED data += +====================== +*/ + +/*++++void CAL_HuffExpand (byte huge *source, byte huge *dest, + long length,huffnode *hufftable) +{ +// unsigned bit,byte,node,code; + unsigned sourceseg,sourceoff,destseg,destoff,endoff; + huffnode *headptr; +// huffnode *nodeon; + + headptr = hufftable+254; // head node is allways node 254 + + source++; // normalize + source--; + dest++; + dest--; + + sourceseg = FP_SEG(source); + sourceoff = FP_OFF(source); + destseg = FP_SEG(dest); + destoff = FP_OFF(dest); + endoff = destoff+length; + +// +// ds:si source +// es:di dest +// ss:bx node pointer +// + + if (length <0xfff0) + { + +//-------------------------- +// expand less than 64k of data +//-------------------------- + + __asm + { + mov bx,[headptr] + + mov si,[sourceoff] + mov di,[destoff] + mov es,[destseg] + mov ds,[sourceseg] + mov ax,[endoff] + + mov ch,[si] // load first byte + inc si + mov cl,1 + +expandshort: + test ch,cl // bit set? + jnz bit1short + mov dx,[ss:bx] // take bit0 path from node + shl cl,1 // advance to next bit position + jc newbyteshort + jnc sourceupshort + +bit1short: +asm mov dx,[ss:bx+2] // take bit1 path +asm shl cl,1 // advance to next bit position +asm jnc sourceupshort + +newbyteshort: +asm mov ch,[si] // load next byte +asm inc si +asm mov cl,1 // back to first bit + +sourceupshort: +asm or dh,dh // if dx<256 its a byte, else move node +asm jz storebyteshort +asm mov bx,dx // next node = (huffnode *)code +asm jmp expandshort + +storebyteshort: +asm mov [es:di],dl +asm inc di // write a decopmpressed byte out +asm mov bx,[headptr] // back to the head node for next bit + +asm cmp di,ax // done? +asm jne expandshort + } + } + else + { + +//-------------------------- +// expand more than 64k of data +//-------------------------- + + length--; + + __asm + { +asm mov bx,[headptr] +asm mov cl,1 + +asm mov si,[sourceoff] +asm mov di,[destoff] +asm mov es,[destseg] +asm mov ds,[sourceseg] + +asm lodsb // load first byte + +expand: +asm test al,cl // bit set? +asm jnz bit1 +asm mov dx,[ss:bx] // take bit0 path from node +asm jmp gotcode +bit1: +asm mov dx,[ss:bx+2] // take bit1 path + +gotcode: +asm shl cl,1 // advance to next bit position +asm jnc sourceup +asm lodsb +asm cmp si,0x10 // normalize ds:si +asm jb sinorm +asm mov cx,ds +asm inc cx +asm mov ds,cx +asm xor si,si +sinorm: +asm mov cl,1 // back to first bit + +sourceup: +asm or dh,dh // if dx<256 its a byte, else move node +asm jz storebyte +asm mov bx,dx // next node = (huffnode *)code +asm jmp expand + +storebyte: +asm mov [es:di],dl +asm inc di // write a decopmpressed byte out +asm mov bx,[headptr] // back to the head node for next bit + +asm cmp di,0x10 // normalize es:di +asm jb dinorm +asm mov dx,es +asm inc dx +asm mov es,dx +asm xor di,di +dinorm: + +asm sub [WORD PTR ss:length],1 +asm jnc expand +asm dec [WORD PTR ss:length+2] +asm jns expand // when length = ffff ffff, done + } + } + + __asm + { + mov ax,ss + mov ds,ax + } + +}*/ + + +/* +====================== += += CAL_CarmackExpand += += Length is the length of the EXPANDED data += +====================== +*/ +/*++++ +#define NEARTAG 0xa7 +#define FARTAG 0xa8 + +void CAL_CarmackExpand (unsigned far *source, unsigned far *dest, unsigned length) +{ + unsigned ch,chhigh,count,offset; + unsigned far *copyptr, far *inptr, far *outptr; + + length/=2; + + inptr = source; + outptr = dest; + + while (length) + { + ch = *inptr++; + chhigh = ch>>8; + if (chhigh == NEARTAG) + { + count = ch&0xff; + if (!count) + { // have to insert a word containing the tag byte + ch |= *((unsigned char far *)inptr)++; + *outptr++ = ch; + length--; + } + else + { + offset = *((unsigned char far *)inptr)++; + copyptr = outptr - offset; + length -= count; + while (count--) + *outptr++ = *copyptr++; + } + } + else if (chhigh == FARTAG) + { + count = ch&0xff; + if (!count) + { // have to insert a word containing the tag byte + ch |= *((unsigned char far *)inptr)++; + *outptr++ = ch; + length --; + } + else + { + offset = *inptr++; + copyptr = dest + offset; + length -= count; + while (count--) + *outptr++ = *copyptr++; + } + } + else + { + *outptr++ = ch; + length --; + } + } +} +*/ + + +/* +====================== += += CA_RLEWcompress += +====================== +*/ +/*++++ +long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest, + unsigned rlewtag) +{ + long complength; + unsigned value,count,i; + unsigned huge *start,huge *end; + + start = dest; + + end = source + (length+1)/2; + +// +// compress it +// + do + { + count = 1; + value = *source++; + while (*source == value && source3 || value == rlewtag) + { + // + // send a tag / count / value string + // + *dest++ = rlewtag; + *dest++ = count; + *dest++ = value; + } + else + { + // + // send word without compressing + // + for (i=1;i<=count;i++) + *dest++ = value; + } + + } while (source0 + MM_GetPtr(&(memptr)pictable,NUMPICS*sizeof(pictabletype)); + CAL_GetGrChunkLength(STRUCTPIC); // position file pointer + MM_GetPtr(&compseg,chunkcomplen); + CA_FarRead (grhandle,compseg,chunkcomplen); + CAL_HuffExpand (compseg, (byte huge *)pictable,NUMPICS*sizeof(pictabletype),grhuffman); + MM_FreePtr(&compseg); +#endif + +#if NUMPICM>0 + MM_GetPtr(&(memptr)picmtable,NUMPICM*sizeof(pictabletype)); + CAL_GetGrChunkLength(STRUCTPICM); // position file pointer + MM_GetPtr(&compseg,chunkcomplen); + CA_FarRead (grhandle,compseg,chunkcomplen); + CAL_HuffExpand (compseg, (byte huge *)picmtable,NUMPICS*sizeof(pictabletype),grhuffman); + MM_FreePtr(&compseg); +#endif + +#if NUMSPRITES>0 + MM_GetPtr(&(memptr)spritetable,NUMSPRITES*sizeof(spritetabletype)); + CAL_GetGrChunkLength(STRUCTSPRITE); // position file pointer + MM_GetPtr(&compseg,chunkcomplen); + CA_FarRead (grhandle,compseg,chunkcomplen); + CAL_HuffExpand (compseg, (byte huge *)spritetable,NUMSPRITES*sizeof(spritetabletype),grhuffman); + MM_FreePtr(&compseg); +#endif + +}*/ + +//========================================================================== + + +/* +====================== += += CAL_SetupMapFile += +====================== +*/ + +/*void CAL_SetupMapFile (void) +{ + int handle; + long length; + +// +// load maphead.ext (offsets and tileinfo for map file) +// +#ifndef MAPHEADERLINKED + if ((handle = open("MAPHEAD."EXT, + O_RDONLY | O_BINARY, S_IREAD)) == -1) + Quit ("Can't open MAPHEAD."EXT"!"); + length = filelength(handle); + MM_GetPtr (&(memptr)tinf,length); + CA_FarRead(handle, tinf, length); + close(handle); +#else + + tinf = (byte _seg *)FP_SEG(&maphead); + +#endif + +// +// open the data file +// +#ifdef MAPHEADERLINKED + if ((maphandle = open("GAMEMAPS."EXT, + O_RDONLY | O_BINARY, S_IREAD)) == -1) + Quit ("Can't open GAMEMAPS."EXT"!"); +#else + if ((maphandle = open("MAPTEMP."EXT, + O_RDONLY | O_BINARY, S_IREAD)) == -1) + Quit ("Can't open MAPTEMP."EXT"!"); +#endif +}*/ + +//========================================================================== + + +/* +====================== += += CAL_SetupAudioFile += +====================== +*/ + +/*void CAL_SetupAudioFile (void) +{ + int handle; + long length; + +// +// load maphead.ext (offsets and tileinfo for map file) +// +#ifndef AUDIOHEADERLINKED + if ((handle = open("AUDIOHED."EXT, + O_RDONLY | O_BINARY, S_IREAD)) == -1) + Quit ("Can't open AUDIOHED."EXT"!"); + length = filelength(handle); + MM_GetPtr (&(memptr)audiostarts,length); + CA_FarRead(handle, (byte far *)audiostarts, length); + close(handle); +#else + audiohuffman = (huffnode *)&audiodict; + CAL_OptimizeNodes (audiohuffman); + audiostarts = (long _seg *)FP_SEG(&audiohead); +#endif + +// +// open the data file +// +#ifndef AUDIOHEADERLINKED + if ((audiohandle = open("AUDIOT."EXT, + O_RDONLY | O_BINARY, S_IREAD)) == -1) + Quit ("Can't open AUDIOT."EXT"!"); +#else + if ((audiohandle = open("AUDIO."EXT, + O_RDONLY | O_BINARY, S_IREAD)) == -1) + Quit ("Can't open AUDIO."EXT"!"); +#endif +}*/ + +//========================================================================== + + +/* +====================== += += CA_Startup += += Open all files and load in headers += +====================== +*/ + +void CA_Startup(void) +{ +#ifdef PROFILE + unlink("profile.16"); + profilehandle = open("profile.16", O_CREAT | O_WRONLY | O_TEXT); +#endif +/*++++ +// MDM begin - (GAMERS EDGE) +// + if(!FindFile("AUDIO."EXT,NULL,2)) + Quit("CA_Startup(): Can't find audio files."); +// +// MDM end + +#ifndef NOAUDIO + CAL_SetupAudioFile(); +#endif + +// MDM begin - (GAMERS EDGE) +// + if (!FindFile("GAMEMAPS."EXT,NULL,1)) + Quit("CA_Startup(): Can't find level files."); +// +// MDM end + +#ifndef NOMAPS + CAL_SetupMapFile (); +#endif + +// MDM begin - (GAMERS EDGE) +// + if (!FindFile("EGAGRAPH."EXT,NULL,2)) + Quit("CA_Startup(): Can't find graphics files."); +// +// MDM end + +#ifndef NOGRAPHICS + CAL_SetupGrFile (); +#endif + + mapon = -1; + ca_levelbit = 1; + ca_levelnum = 0; + + drawcachebox = CAL_DialogDraw; + updatecachebox = CAL_DialogUpdate; + finishcachebox = CAL_DialogFinish;*/ +} + +//========================================================================== + + +/* +====================== += += CA_Shutdown += += Closes all files += +====================== +*/ + +void CA_Shutdown(void) +{ +#ifdef PROFILE + close(profilehandle); +#endif +/*++++ + close(maphandle); + close(grhandle); + close(audiohandle);*/ +} + +//=========================================================================== + +/* +====================== += += CA_CacheAudioChunk += +====================== +*/ +/*++++ +void CA_CacheAudioChunk (int chunk) +{ + long pos,compressed; +#ifdef AUDIOHEADERLINKED + long expanded; + memptr bigbufferseg; + byte far *source; +#endif + + if (audiosegs[chunk]) + { + MM_SetPurge (&(memptr)audiosegs[chunk],0); + return; // allready in memory + } + +// MDM begin - (GAMERS EDGE) +// + if (!FindFile("AUDIO."EXT,NULL,2)) + Quit("CA_CacheAudioChunk(): Can't find audio files."); +// +// MDM end + +// +// load the chunk into a buffer, either the miscbuffer if it fits, or allocate +// a larger buffer +// + pos = audiostarts[chunk]; + compressed = audiostarts[chunk+1]-pos; + + lseek(audiohandle,pos,SEEK_SET); + +#ifndef AUDIOHEADERLINKED + + MM_GetPtr (&(memptr)audiosegs[chunk],compressed); + if (mmerror) + return; + + CA_FarRead(audiohandle,audiosegs[chunk],compressed); + +#else + + if (compressed<=BUFFERSIZE) + { + CA_FarRead(audiohandle,bufferseg,compressed); + source = bufferseg; + } + else + { + MM_GetPtr(&bigbufferseg,compressed); + if (mmerror) + return; + MM_SetLock (&bigbufferseg,true); + CA_FarRead(audiohandle,bigbufferseg,compressed); + source = bigbufferseg; + } + + expanded = *(long far *)source; + source += 4; // skip over length + MM_GetPtr (&(memptr)audiosegs[chunk],expanded); + if (mmerror) + goto done; + CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman); + +done: + if (compressed>BUFFERSIZE) + MM_FreePtr(&bigbufferseg); +#endif +}*/ + +//=========================================================================== + +/* +====================== += += CA_LoadAllSounds += += Purges all sounds, then loads all new ones (mode switch) += +====================== +*/ +/*++++ +void CA_LoadAllSounds (void) +{ + unsigned start,i; + + switch (oldsoundmode) + { + case sdm_Off: + goto cachein; + case sdm_PC: + start = STARTPCSOUNDS; + break; + case sdm_AdLib: + start = STARTADLIBSOUNDS; + break; + } + + for (i=0;iwidth*spr->height; + MM_GetPtr (&grsegs[chunk],smallplane*2+MAXSHIFTS*6); + if (mmerror) + return; + dest = (spritetype _seg *)grsegs[chunk]; + dest->sourceoffset[0] = MAXSHIFTS*6; // start data after 3 unsigned tables + dest->planesize[0] = smallplane; + dest->width[0] = spr->width; + +// +// expand the unshifted shape +// + CAL_HuffExpand (compressed, &dest->data[0],smallplane*2,grhuffman); + +#endif + + +#if GRMODE == EGAGR + +// +// calculate sizes +// + spr = &spritetable[chunk-STARTSPRITES]; + smallplane = spr->width*spr->height; + bigplane = (spr->width+1)*spr->height; + + shiftstarts[0] = MAXSHIFTS*6; // start data after 3 unsigned tables + shiftstarts[1] = shiftstarts[0] + smallplane*5; // 5 planes in a sprite + shiftstarts[2] = shiftstarts[1] + bigplane*5; + shiftstarts[3] = shiftstarts[2] + bigplane*5; + shiftstarts[4] = shiftstarts[3] + bigplane*5; // nothing ever put here + + expanded = shiftstarts[spr->shifts]; + MM_GetPtr (&grsegs[chunk],expanded); + if (mmerror) + return; + dest = (spritetype _seg *)grsegs[chunk]; + +// +// expand the unshifted shape +// + CAL_HuffExpand (compressed, &dest->data[0],smallplane*5,grhuffman); + +// +// make the shifts! +// + switch (spr->shifts) + { + case 1: + for (i=0;i<4;i++) + { + dest->sourceoffset[i] = shiftstarts[0]; + dest->planesize[i] = smallplane; + dest->width[i] = spr->width; + } + break; + + case 2: + for (i=0;i<2;i++) + { + dest->sourceoffset[i] = shiftstarts[0]; + dest->planesize[i] = smallplane; + dest->width[i] = spr->width; + } + for (i=2;i<4;i++) + { + dest->sourceoffset[i] = shiftstarts[1]; + dest->planesize[i] = bigplane; + dest->width[i] = spr->width+1; + } + CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0], + dest->sourceoffset[2],spr->width,spr->height,4,true); + break; + + case 4: + dest->sourceoffset[0] = shiftstarts[0]; + dest->planesize[0] = smallplane; + dest->width[0] = spr->width; + + dest->sourceoffset[1] = shiftstarts[1]; + dest->planesize[1] = bigplane; + dest->width[1] = spr->width+1; + CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0], + dest->sourceoffset[1],spr->width,spr->height,2,true); + + dest->sourceoffset[2] = shiftstarts[2]; + dest->planesize[2] = bigplane; + dest->width[2] = spr->width+1; + CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0], + dest->sourceoffset[2],spr->width,spr->height,4,true); + + dest->sourceoffset[3] = shiftstarts[3]; + dest->planesize[3] = bigplane; + dest->width[3] = spr->width+1; + CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0], + dest->sourceoffset[3],spr->width,spr->height,6,true); + + break; + + default: + Quit ("CAL_CacheSprite: Bad shifts number!"); + } + +#endif +}*/ + +//=========================================================================== + + +/* +====================== += += CAL_ExpandGrChunk += += Does whatever is needed with a pointer to a compressed chunk += +====================== +*/ +/*++++ +void CAL_ExpandGrChunk (int chunk, byte far *source) +{ + long expanded; + + + if (chunk >= STARTTILE8 && chunk < STARTEXTERNS) + { + // + // expanded sizes of tile8/16/32 are implicit + // + +#if GRMODE == EGAGR +#define BLOCK 32 +#define MASKBLOCK 40 +#endif + +#if GRMODE == CGAGR +#define BLOCK 16 +#define MASKBLOCK 32 +#endif + + if (chunk=STARTSPRITES && chunk< STARTTILE8) + CAL_CacheSprite(chunk,source); + else + { + MM_GetPtr (&grsegs[chunk],expanded); + if (mmerror) + return; + CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman); + } +} +*/ + +/* +====================== += += CAL_ReadGrChunk += += Gets a chunk off disk, optimizing reads to general buffer += +====================== +*/ +/*++++ +void CAL_ReadGrChunk (int chunk) +{ + long pos,compressed; + memptr bigbufferseg; + byte far *source; + int next; + +// +// load the chunk into a buffer, either the miscbuffer if it fits, or allocate +// a larger buffer +// + pos = GRFILEPOS(chunk); + if (pos<0) // $FFFFFFFF start is a sparse tile + return; + + next = chunk +1; + while (GRFILEPOS(next) == -1) // skip past any sparse tiles + next++; + + compressed = GRFILEPOS(next)-pos; + + lseek(grhandle,pos,SEEK_SET); + + if (compressed<=BUFFERSIZE) + { + CA_FarRead(grhandle,bufferseg,compressed); + source = bufferseg; + } + else + { + MM_GetPtr(&bigbufferseg,compressed); + if (mmerror) + return; + MM_SetLock (&bigbufferseg,true); + CA_FarRead(grhandle,bigbufferseg,compressed); + source = bigbufferseg; + } + + CAL_ExpandGrChunk (chunk,source); + + if (compressed>BUFFERSIZE) + MM_FreePtr(&bigbufferseg); +} +*/ +/* +====================== += += CA_CacheGrChunk += += Makes sure a given chunk is in memory, loadiing it if needed += +====================== +*/ +/*++++ +void CA_CacheGrChunk (int chunk) +{ + long pos,compressed; + memptr bigbufferseg; + byte far *source; + int next; + + grneeded[chunk] |= ca_levelbit; // make sure it doesn't get removed + if (grsegs[chunk]) + { + MM_SetPurge (&grsegs[chunk],0); + return; // allready in memory + } + +// MDM begin - (GAMERS EDGE) +// + if (!FindFile("EGAGRAPH."EXT,NULL,2)) + Quit("CA_CacheGrChunk(): Can't find graphics files."); +// +// MDM end + +// +// load the chunk into a buffer, either the miscbuffer if it fits, or allocate +// a larger buffer +// + pos = GRFILEPOS(chunk); + if (pos<0) // $FFFFFFFF start is a sparse tile + return; + + next = chunk +1; + while (GRFILEPOS(next) == -1) // skip past any sparse tiles + next++; + + compressed = GRFILEPOS(next)-pos; + + lseek(grhandle,pos,SEEK_SET); + + if (compressed<=BUFFERSIZE) + { + CA_FarRead(grhandle,bufferseg,compressed); + source = bufferseg; + } + else + { + MM_GetPtr(&bigbufferseg,compressed); + MM_SetLock (&bigbufferseg,true); + CA_FarRead(grhandle,bigbufferseg,compressed); + source = bigbufferseg; + } + + CAL_ExpandGrChunk (chunk,source); + + if (compressed>BUFFERSIZE) + MM_FreePtr(&bigbufferseg); +} +*/ + + +//========================================================================== + +/* +====================== += += CA_CacheMap += +====================== +*/ +/*++++ +void CA_CacheMap (int mapnum) +{ + long pos,compressed; + int plane; + memptr *dest,bigbufferseg; + unsigned size; + unsigned far *source; +#ifdef MAPHEADERLINKED + memptr buffer2seg; + long expanded; +#endif + + +// MDM begin - (GAMERS EDGE) +// + if (!FindFile("GAMEMAPS."EXT,NULL,1)) + Quit("CA_CacheMap(): Can't find level files."); +// +// MDM end + + +// +// free up memory from last map +// + if (mapon>-1 && mapheaderseg[mapon]) + MM_SetPurge (&(memptr)mapheaderseg[mapon],3); + for (plane=0;planeheaderoffsets[mapnum]; + if (pos<0) // $FFFFFFFF start is a sparse map + Quit ("CA_CacheMap: Tried to load a non existent map!"); + + MM_GetPtr(&(memptr)mapheaderseg[mapnum],sizeof(maptype)); + lseek(maphandle,pos,SEEK_SET); + CA_FarRead (maphandle,(memptr)mapheaderseg[mapnum],sizeof(maptype)); + } + else + MM_SetPurge (&(memptr)mapheaderseg[mapnum],0); + +// +// load the planes in +// If a plane's pointer still exists it will be overwritten (levels are +// allways reloaded, never cached) +// + + size = mapheaderseg[mapnum]->width * mapheaderseg[mapnum]->height * 2; + + for (plane = 0; planeplanestart[plane]; + compressed = mapheaderseg[mapnum]->planelength[plane]; + + if (!compressed) + continue; // the plane is not used in this game + + dest = &(memptr)mapsegs[plane]; + MM_GetPtr(dest,size); + + lseek(maphandle,pos,SEEK_SET); + if (compressed<=BUFFERSIZE) + source = bufferseg; + else + { + MM_GetPtr(&bigbufferseg,compressed); + MM_SetLock (&bigbufferseg,true); + source = bigbufferseg; + } + + CA_FarRead(maphandle,(byte far *)source,compressed); +#ifdef MAPHEADERLINKED + // + // unhuffman, then unRLEW + // The huffman'd chunk has a two byte expanded length first + // The resulting RLEW chunk also does, even though it's not really + // needed + // + expanded = *source; + source++; + MM_GetPtr (&buffer2seg,expanded); + CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded); + CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size, + ((mapfiletype _seg *)tinf)->RLEWtag); + MM_FreePtr (&buffer2seg); + +#else + // + // unRLEW, skipping expanded length + // + CA_RLEWexpand (source+1, *dest,size, + ((mapfiletype _seg *)tinf)->RLEWtag); +#endif + + if (compressed>BUFFERSIZE) + MM_FreePtr(&bigbufferseg); + } +}*/ + +//=========================================================================== + +/* +====================== += += CA_UpLevel += += Goes up a bit level in the needed lists and clears it out. += Everything is made purgable += +====================== +*/ +/*++++ +void CA_UpLevel (void) +{ + if (ca_levelnum==7) + Quit ("CA_UpLevel: Up past level 7!"); + + ca_levelbit<<=1; + ca_levelnum++; +}*/ + +//=========================================================================== + +/* +====================== += += CA_DownLevel += += Goes down a bit level in the needed lists and recaches += everything from the lower level += +====================== +*/ +/*++ +void CA_DownLevel (void) +{ + if (!ca_levelnum) + Quit ("CA_DownLevel: Down past level 0!"); + ca_levelbit>>=1; + ca_levelnum--; + CA_CacheMarks(NULL); +}*/ + +//=========================================================================== + +/* +====================== += += CA_ClearMarks += += Clears out all the marks at the current level += +====================== +*/ +/* +void CA_ClearMarks (void) +{ + int i; + + for (i=0;i>16; + if (xh - lastx > BARSTEP) + { + for (x=lastx;x<=xh;x++) +#if GRMODE == EGAGR + VWB_Vlin (thy,thy+13,x,14); +#endif +#if GRMODE == CGAGR + VWB_Vlin (thy,thy+13,x,SECONDCOLOR); +#endif + lastx = xh; + VW_UpdateScreen(); + } +}*/ + +/* +====================== += += CAL_DialogFinish += +====================== +*/ +/* +void CAL_DialogFinish (void) +{ + unsigned x,xh; + + xh = thx + NUMBARS; + for (x=lastx;x<=xh;x++) +#if GRMODE == EGAGR + VWB_Vlin (thy,thy+13,x,14); +#endif +#if GRMODE == CGAGR + VWB_Vlin (thy,thy+13,x,SECONDCOLOR); +#endif + VW_UpdateScreen(); + +}*/ + +//=========================================================================== + +/* +====================== += += CA_CacheMarks += +====================== +*//* +#define MAXEMPTYREAD 1024 + +void CA_CacheMarks (char *title) +{ + boolean dialog; + int i,next,numcache; + long pos,endpos,nextpos,nextendpos,compressed; + long bufferstart,bufferend; // file position of general buffer + byte far *source; + memptr bigbufferseg; + + dialog = (title!=NULL); + + numcache = 0; +// +// go through and make everything not needed purgable +// + for (i=0;i= endpos) + { + // data is allready in buffer + source = (byte _seg *)bufferseg+(pos-bufferstart); + } + else + { + // load buffer with a new block from disk + // try to get as many of the needed blocks in as possible + while ( next < NUMCHUNKS ) + { + while (next < NUMCHUNKS && + !(grneeded[next]&ca_levelbit && !grsegs[next])) + next++; + if (next == NUMCHUNKS) + continue; + + nextpos = GRFILEPOS(next); + while (GRFILEPOS(++next) == -1) // skip past any sparse tiles + ; + nextendpos = GRFILEPOS(next); + if (nextpos - endpos <= MAXEMPTYREAD + && nextendpos-pos <= BUFFERSIZE) + endpos = nextendpos; + else + next = NUMCHUNKS; // read pos to posend + } + + lseek(grhandle,pos,SEEK_SET); + CA_FarRead(grhandle,bufferseg,endpos-pos); + bufferstart = pos; + bufferend = endpos; + source = bufferseg; + } + } + else + { + // big chunk, allocate temporary buffer + MM_GetPtr(&bigbufferseg,compressed); + if (mmerror) + return; + MM_SetLock (&bigbufferseg,true); + lseek(grhandle,pos,SEEK_SET); + CA_FarRead(grhandle,bigbufferseg,compressed); + source = bigbufferseg; + } + + CAL_ExpandGrChunk (i,source); + if (mmerror) + return; + + if (compressed>BUFFERSIZE) + MM_FreePtr(&bigbufferseg); + + } + +// +// finish up any thermometer remnants +// + if (dialog && finishcachebox) + finishcachebox(); +}*/ diff --git a/16/exmmtest/16_ca.h b/16/exmmtest/16_ca.h new file mode 100644 index 00000000..9fbbd2d8 --- /dev/null +++ b/16/exmmtest/16_ca.h @@ -0,0 +1,116 @@ +/* Catacomb Apocalypse Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// ID_CA.H +#ifndef __16_CA__ +#define __16_CA__ + +#ifndef __16_MM__ +#include "16_head.h" +#include "16_mm.h" +#endif + +//=========================================================================== + +//#define NOMAPS +//#define NOGRAPHICS +//#define NOAUDIO + +//#define MAPHEADERLINKED +//#define GRHEADERLINKED +//#define AUDIOHEADERLINKED + +//#define NUMMAPS 39 +//#define MAPPLANES 3 +#define PROFILE + +//=========================================================================== + +/*typedef struct +{ + long planestart[3]; + unsigned planelength[3]; + unsigned width,height; + char name[16]; +} maptype;*/ + +//=========================================================================== + +/*extern byte _seg *tinf; +extern int mapon; + +extern unsigned _seg *mapsegs[3]; +extern maptype _seg *mapheaderseg[NUMMAPS]; +extern byte _seg *audiosegs[NUMSNDCHUNKS]; +extern void _seg *grsegs[NUMCHUNKS]; + +extern byte far grneeded[NUMCHUNKS]; +extern byte ca_levelbit,ca_levelnum; + +extern char *titleptr[8];*/ + +extern int profilehandle,debughandle; + +// +// hooks for custom cache dialogs +// +extern void (*drawcachebox) (char *title, unsigned numcache); +extern void (*updatecachebox) (void); +extern void (*finishcachebox) (void); + +//=========================================================================== + +// just for the score box reshifting + +//void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,unsigned width, unsigned height, unsigned pixshift, boolean domask); + +//=========================================================================== + +void CA_OpenDebug (void); +void CA_CloseDebug (void); +boolean CA_FarRead (int handle, byte huge *dest, dword length, mminfo_t *mm); +boolean CA_FarWrite (int handle, byte huge *source, dword length, mminfo_t *mm); + +boolean CA_ReadFile (char *filename, memptr *ptr, mminfo_t *mm); +boolean CA_LoadFile (char *filename, memptr *ptr, mminfo_t *mm, mminfotype *mmi); + +//long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,unsigned rlewtag); + +//void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,unsigned rlewtag); + +void CA_Startup (void); +void CA_Shutdown (void); + +//void CA_CacheAudioChunk (int chunk); +//void CA_LoadAllSounds (void); + +/*void CA_UpLevel (void); +void CA_DownLevel (void); + +void CA_SetAllPurge (void); + +void CA_ClearMarks (void); +void CA_ClearAllMarks (void); + +#define CA_MarkGrChunk(chunk) grneeded[chunk]|=ca_levelbit + +void CA_CacheGrChunk (int chunk); +void CA_CacheMap (int mapnum); + +void CA_CacheMarks (char *title);*/ +#endif diff --git a/16/exmmtest/16_head.c b/16/exmmtest/16_head.c new file mode 100644 index 00000000..b80ee542 --- /dev/null +++ b/16/exmmtest/16_head.c @@ -0,0 +1,285 @@ +/* Project 16 Source Code~ + * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669 + * + * This file is part of Project 16. + * + * Project 16 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Project 16 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "16_head.h" + +/* Function: Wait ********************************************************** +* +* Parameters: wait - time in microseconds +* +* Description: pauses for a specified number of microseconds. +* +*/ +void wait(clock_t wait){ + clock_t goal; + + if(!wait) return; + + goal = wait + clock(); + while((goal > clock()) && !kbhit()) ; +} /* End of wait */ + +void* AllocateLargestFreeBlock(size_t* Size) +{ + size_t s0, s1; + void* p; + + s0 = ~(size_t)0 ^ (~(size_t)0 >> 1); + + while (s0 && (p = malloc(s0)) == NULL) + s0 >>= 1; + + if (p) + free(p); + + s1 = s0 >> 1; + + while (s1) + { + if ((p = malloc(s0 + s1)) != NULL) + { + s0 += s1; + free(p); + } + s1 >>= 1; + } + + while (s0 && (p = malloc(s0)) == NULL) + s0 ^= s0 & -s0; + + *Size = s0; + return p; +} + +size_t GetFreeSize(void) +{ + size_t total = 0; + void* pFirst = NULL; + void* pLast = NULL; + + for (;;) + { + size_t largest; + void* p = AllocateLargestFreeBlock(&largest); + + if (largest < sizeof(void*)) + { + if (p != NULL) + free(p); + break; + } + + *(void**)p = NULL; + + total += largest; + + if (pFirst == NULL) + pFirst = p; + + if (pLast != NULL) + *(void**)pLast = p; + + pLast = p; + } + + while (pFirst != NULL) + { + void* p = *(void**)pFirst; + free(pFirst); + pFirst = p; + } + + return total; +} + +void far* AllocateLargestFarFreeBlock(size_t far* Size) +{ + size_t s0, s1; + void far* p; + + s0 = ~(size_t)0 ^ (~(size_t)0 >> 1); + while (s0 && (p = _fmalloc(s0)) == NULL) + s0 >>= 1; + + if (p) + _ffree(p); + + s1 = s0 >> 1; + while (s1) + { + if ((p = _fmalloc(s0 + s1)) != NULL) + { + s0 += s1; + _ffree(p); + } + s1 >>= 1; + } + while (s0 && (p = _fmalloc(s0)) == NULL) + s0 ^= s0 & -s0; + + *Size = s0; + return p; +} + +size_t GetFarFreeSize(void) +{ + size_t total = 0; + void far* pFirst = NULL; + void far* pLast = NULL; + for(;;) + { + size_t largest; + void far* p = AllocateLargestFarFreeBlock(&largest); + if (largest < sizeof(void far*)) + { + if (p != NULL) + _ffree(p); + break; + } + *(void far* far*)p = NULL; + total += largest; + if (pFirst == NULL) + pFirst = p; + + if (pLast != NULL) + *(void far* far*)pLast = p; + pLast = p; + } + + while (pFirst != NULL) + { + void far* p = *(void far* far*)pFirst; + _ffree(pFirst); + pFirst = p; + } + return total; +} + +long int +filesize(FILE *fp) +{ + long int save_pos, size_of_file; + + save_pos = ftell(fp); + fseek(fp, 0L, SEEK_END); + size_of_file = ftell(fp); + fseek(fp, save_pos, SEEK_SET); + return(size_of_file); +} + +/////////////////////////////////////////////////////////////////////////// +// +// US_CheckParm() - checks to see if a string matches one of a set of +// strings. The check is case insensitive. The routine returns the +// index of the string that matched, or -1 if no matches were found +// +/////////////////////////////////////////////////////////////////////////// +int +US_CheckParm(char *parm,char **strings) +{ + char cp,cs, + *p,*s; + int i; + + while (!isalpha(*parm)) // Skip non-alphas + parm++; + + for (i = 0;*strings && **strings;i++) + { + for (s = *strings++,p = parm,cs = cp = 0;cs == cp;) + { + cs = *s++; + if (!cs) + return(i); + cp = *p++; + + if (isupper(cs)) + cs = tolower(cs); + if (isupper(cp)) + cp = tolower(cp); + } + } + return(-1); +} + +/* +========================== += += Quit += +========================== +*/ + +/*void Quit(char *error, ...) +{ + short exit_code=0; + unsigned finscreen; + + va_list ap; + + va_start(ap,error); + +#ifndef CATALOG + if (!error) + { + CA_SetAllPurge (); + CA_CacheGrChunk (PIRACY); + finscreen = (unsigned)grsegs[PIRACY]; + } +#endif + + //ShutdownId (); + + if (error && *error) + { + vprintf(error,ap); + exit_code = 1; + } +#ifndef CATALOG + else + if (!NoWait) + { + movedata (finscreen,0,0xb800,0,4000); + bioskey (0); + } +#endif + + va_end(ap); + +#ifndef CATALOG + if (!error) + { + _argc = 2; + _argv[1] = "LAST.SHL"; + _argv[2] = "ENDSCN.SCN"; + _argv[3] = NULL; + if (execv("LOADSCN.EXE", _argv) == -1) + { + clrscr(); + puts("Couldn't find executable LOADSCN.EXE.\n"); + exit(1); + } + } +#endif + + exit(exit_code); +}*/ diff --git a/16/exmmtest/16_head.h b/16/exmmtest/16_head.h new file mode 100644 index 00000000..aac53a24 --- /dev/null +++ b/16/exmmtest/16_head.h @@ -0,0 +1,176 @@ +/* Project 16 Source Code~ + * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669 + * + * This file is part of Project 16. + * + * Project 16 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Project 16 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#if !defined(__LARGE__) && !defined(__COMPACT__) && !defined(__HUGE__) +#error Invalid memory model for compiling project 16 +#endif + +#if !defined(__i86__) && defined(__i386__) +#error i8088 only +#endif + +#ifndef _LIBHEAD_H_ +#define _LIBHEAD_H_ +//#include +#include +#include +#include // just for wait +#include // just for wait +#include +#include +#include +//#include +#include +//#include +#include +#include "../../src/lib/types.h" + +/* Control codes for all keys on the keyboard */ +//here temperarly +/* +#define KEY_A (0x1E) +#define KEY_B (0x30) +#define KEY_C (0x2E) +#define KEY_D (0x20) +#define KEY_E (0x12) +#define KEY_F (0x21) +#define KEY_G (0x22) +#define KEY_H (0x23) +#define KEY_I (0x17) +#define KEY_J (0x24) +#define KEY_K (0x25) +#define KEY_L (0x26) +#define KEY_M (0x32) +#define KEY_N (0x31) +#define KEY_O (0x18) +#define KEY_P (0x19) +#define KEY_Q (0x10) +#define KEY_R (0x13) +#define KEY_S (0x1F) +#define KEY_T (0x14) +#define KEY_U (0x16) +#define KEY_V (0x2F) +#define KEY_W (0x11) +#define KEY_X (0x2D) +#define KEY_Y (0x15) +#define KEY_Z (0x2C) +#define KEY_1 (0x02) +#define KEY_2 (0x03) +#define KEY_3 (0x04) +#define KEY_4 (0x05) +#define KEY_5 (0x06) +#define KEY_6 (0x07) +#define KEY_7 (0x08) +#define KEY_8 (0x09) +#define KEY_9 (0x0A) +#define KEY_0 (0x0B) +#define KEY_DASH (0x0C) // -_ +#define KEY_EQUAL (0x0D) // =+ +#define KEY_LBRACKET (0x1A) // [{ +#define KEY_RBRACKET (0x1B) // ]} +#define KEY_SEMICOLON (0x27) // ;: +#define KEY_RQUOTE (0x28) // '" +#define KEY_LQUOTE (0x29) // `~ +#define KEY_PERIOD (0x33) // .> +#define KEY_COMMA (0x34) // ,< +#define KEY_SLASH (0x35) // /? +#define KEY_BACKSLASH (0x2B) // \| +#define KEY_F1 (0x3B) +#define KEY_F2 (0x3C) +#define KEY_F3 (0x3D) +#define KEY_F4 (0x3E) +#define KEY_F5 (0x3F) +#define KEY_F6 (0x40) +#define KEY_F7 (0x41) +#define KEY_F8 (0x42) +#define KEY_F9 (0x43) +#define KEY_F10 (0x44) +#define KEY_ESC (0x01) +#define KEY_BACKSPACE (0x0E) +#define KEY_TAB (0x0F) +#define KEY_ENTER (0x1C) +#define KEY_CONTROL (0x1D) +#define KEY_LSHIFT (0x2A) +#define KEY_RSHIFT (0x36) +#define KEY_PRTSC (0x37) +#define KEY_ALT (0x38) +#define KEY_SPACE (0x39) +#define KEY_CAPSLOCK (0x3A) +#define KEY_NUMLOCK (0x45) +#define KEY_SCROLLLOCK (0x46) +#define KEY_HOME (0x47) +#define KEY_UP (0x48) +#define KEY_PGUP (0x49) +#define KEY_MINUS (0x4A) +#define KEY_LEFT (0x4B) +#define KEY_CENTER (0x4C) +#define KEY_RIGHT (0x4D) +#define KEY_PLUS (0x4E) +#define KEY_END (0x4F) +#define KEY_DOWN (0x50) +#define KEY_PGDOWN (0x51) +#define KEY_INS (0x52) +#define KEY_DEL (0x53) + +#define KEY_LWIN (0x73) +#define KEY_RWIN (0x74) +#define KEY_MENU (0x75) +*/ + +static dword far* clockdw= (dword far*) 0x046C; /* 18.2hz clock */ +//static dword clockdw=0; +extern int profilehandle,debughandle; //make it into game global + +#define nil ((void *)0) + +#define __DEBUG__ + +//#define peekb(segm,ofs) (*(byte far*)MK_FP((segm),(ofs))) +//#define peekw(segm,ofs) (*(word far*)MK_FP((segm),(ofs))) +//#define pokeb(segm,ofs,value) (peekb((segm),(ofs)) = (byte)(value)) +//#define pokew(segm,ofs,value) (peekw((segm),(ofs)) = (word)(value)) + +//typedef union REGPACK regs_t; +typedef enum {false,true} boolean; +//I hope this is correct! +//__self +typedef void _seg * memptr; +//typedef void __based(__self) * memptr; +//typedef __segment * memptr; +typedef struct +{ + int old_mode; //old video mode before game! +} global_game_variables_t; + +/* local function */ +void wait(clock_t wait); +void* AllocateLargestFreeBlock(size_t* Size); +size_t GetFreeSize(void); +void far *AllocateLargestFarFreeBlock(size_t far* Size); +size_t GetFarFreeSize(void); +long int filesize(FILE *fp); +int US_CheckParm(char *parm,char **strings); + +extern void CA_OpenDebug (void); +extern void CA_CloseDebug (void); + +#endif/*_LIBHEAD_H_*/ diff --git a/16/exmmtest/16_mm.c b/16/exmmtest/16_mm.c new file mode 100644 index 00000000..cc08b97d --- /dev/null +++ b/16/exmmtest/16_mm.c @@ -0,0 +1,1590 @@ +/* Catacomb Apocalypse Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// NEWMM.C + +/* +============================================================================= + + ID software memory manager + -------------------------- + +Primary coder: John Carmack + +RELIES ON +--------- +Quit (char *error) function + + +WORK TO DO +---------- +MM_SizePtr to change the size of a given pointer + +Multiple purge levels utilized + +EMS / XMS unmanaged routines + +============================================================================= +*/ +/* + +Open Watcom port by sparky4 + +*/ +#include "16_mm.h" +#pragma hdrstop + +#pragma warn -pro +#pragma warn -use + +/* +============================================================================= + + GLOBAL VARIABLES + +============================================================================= +*/ + +void (* beforesort) (void); +void (* aftersort) (void); +void (* XMSaddr) (void); // far pointer to XMS driver + +/* +============================================================================= + + LOCAL VARIABLES + +============================================================================= +*/ + +static char *ParmStringsexmm[] = {"noems","noxms",""}; + +/* +====================== += += MML_CheckForEMS += += Routine from p36 of Extending DOS += +======================= +*/ + +boolean MML_CheckForEMS(void) +{ + boolean emmcfems; + static char emmname[] = "EMMXXXX0"; //fix by andrius4669 +// mov dx,OFFSET emmname + __asm { + //LEA DX, emmname //fix by andrius4669 + mov dx,OFFSET emmname //fix by andrius4669 + mov ax,0x3d00 + int 0x21 // try to open EMMXXXX0 device + jc error + + mov bx,ax + mov ax,0x4400 + + int 0x21 // get device info + jc error + + and dx,0x80 + jz error + + mov ax,0x4407 + + int 0x21 // get status + jc error + or al,al + jz error + + mov ah,0x3e + int 0x21 // close handle + jc error + // + // EMS is good + // + mov emmcfems,1 + jmp End + error: + // + // EMS is bad + // + mov emmcfems,0 + End: + } + return(emmcfems); +} + + +/* +====================== += += MML_SetupEMS += +======================= +*/ + +byte MML_SetupEMS(mminfo_t *mm) +{ + byte str[160]; + byte err; + boolean errorflag=false; + + unsigned int EMSVer = 0; + //byte EMS_status; + unsigned totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle; + totalEMSpages = freeEMSpages = EMSpageframe = EMSpagesmapped = 0; + + __asm + { + mov ah,EMS_STATUS + int EMS_INT // make sure EMS hardware is present + or ah,ah + //mov [EMS_status],ah + jnz error + + mov ah,EMS_VERSION + int EMS_INT + or ah,ah + jnz error + mov [EMSVer],ax // set EMSVer + cmp al,0x32 // only work on ems 3.2 or greater + jb error + + mov ah,EMS_GETFRAME + int EMS_INT // find the page frame address + or ah,ah + jnz error + mov [EMSpageframe],bx + + mov ah,EMS_GETPAGES + int EMS_INT // find out how much EMS is there + or ah,ah + jnz error + mov [totalEMSpages],dx + mov [freeEMSpages],bx + or bx,bx + jz noEMS // no EMS at all to allocate + //EXPAND DONG!!!! + cmp [EMSVer],0x40 + jb low + cmp bx,[freeEMSpages] + jle getpages + mov bx,[freeEMSpages] + jmp getpages + +low: + cmp bx,4 + jle getpages // there is only 1,2,3,or 4 pages + mov bx,4 // we can't use more than 4 pages + +getpages: + mov [EMSpagesmapped],bx + mov ah,EMS_ALLOCPAGES // allocate up to 64k of EMS + int EMS_INT + or ah,ah + jnz error + mov [EMShandle],dx + jmp End +error: + mov err,ah + mov errorflag,1 + jmp End +noEMS: +End: + } + if(errorflag==true) + { + //err = CPURegs.h.ah; + strcpy(str,"MM_SetupEMS: EMS error "); + //itoa(err,str2,16); + MM_EMSerr(&str, err); + printf("%s\n",str); + return err; + } + mm->totalEMSpages=totalEMSpages; + mm->freeEMSpages=freeEMSpages; + mm->EMSpageframe=EMSpageframe; + mm->EMSpagesmapped=EMSpagesmapped; + mm->EMShandle=EMShandle; + mm->EMSVer=EMSVer; + return 0; +} + + +/* +====================== += += MML_ShutdownEMS += +======================= +*/ + +void MML_ShutdownEMS(mminfo_t *mm) +{ + boolean errorflag=false; + unsigned EMShandle=mm->EMShandle; + + if(!EMShandle) + return; + __asm + { + mov ah,EMS_FREEPAGES + mov dx,[EMShandle] + int EMS_INT + or ah,ah + jz ok + mov errorflag,1 + ok: + } + if(errorflag==true) printf("MML_ShutdownEMS: Error freeing EMS!\n"); //++++ add something +} + +/* +==================== += += MM_MapEMS += += Maps the 64k of EMS used by memory manager into the page frame += for general use. This only needs to be called if you are keeping += other things in EMS. += +==================== +*/ + +byte MM_MapEMS(mminfo_t *mm, mminfotype *mmi) +{ + byte str[160]; + unsigned EMShandle; + byte err; + boolean errorflag=false; + int i; + EMShandle=mm->EMShandle; + + for (i=0;i<4/*MAPPAGES*/;i++) + { + __asm + { + mov ah,EMS_MAPPAGE + mov bx,[i] // logical page + mov al,bl // physical page + mov dx,[EMShandle] // handle + int EMS_INT + or ah,ah + jnz error + jmp End + error: + mov err,ah + mov errorflag,1 + End: + } + if(errorflag==true) + { + //err = CPURegs.h.ah; + strcpy(str,"MM_MapEMS: EMS error "); + //itoa(err,str2,16); + MM_EMSerr(str, err); + printf("%s\n",str); + //printf("FACK! %x\n", err); + return err; + } + } + mmi->EMSmem = (i)*0x4000lu; + return 0; +} + +byte MM_MapXEMS(mminfo_t *mm, mminfotype *mmi) +{ +//SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle) + + //Maps up to 4 logical EMS pages to physical pages in the page frame, where: + //PhysicalStart = Physical page first logical page is mapped to + //LogicalStart = First logical page to map + //NumPages = Number of pages to map (1 to 4) + //Handle = EMS handle logical pages are allocated to + + /*//Create a buffer containing the page information +// FOR x = 0 TO NumPages - 1 +// MapInfo$ = MapInfo$ + MKI$(LogicalStart + x) + MKI$(PhysicalStart + x) +// NEXT*/ + +// Regs.ax = 0x5000 //Map the pages in the buffer +// Regs.cx = NumPages //to the pageframe +// Regs.dx = Handle +// Regs.ds = VARSEG(MapInfo$) +// Regs.si = SADD(MapInfo$) +// InterruptX 0x67, Regs, Regs +// EMS.Error = (Regs.ax AND 0xFF00&) \ 0x100 //Store the status code + +//END SUB + byte str[160]; + byte err; + word EMShandle; + boolean errorflag=false; + int i; + EMShandle=mm->EMShandle; + + if(mm->EMSVer<0x40) + return 5; + + for (i=0;iEMSmem = (i)*0x4000lu; + return 0; +} + +//========================================================================== + +/* +====================== += += MML_CheckForXMS += += Check for XMM driver += +======================= +*/ + +boolean MML_CheckForXMS(mminfo_t *mm) +{ + boolean errorflag=false; + mm->numUMBs = 0; + + __asm + { + mov ax,0x4300 + int 0x2f // query status of installed diver + cmp al,0x80 + je good + mov errorflag,1 + good: + } + if(errorflag==true) return false; + else return true; +} + + +/* +====================== += += MML_SetupXMS += += Try to allocate all upper memory block += +======================= +*/ + +void MML_SetupXMS(mminfo_t *mm, mminfotype *mmi) +{ + unsigned base,size; + +getmemory: + __asm + { + mov ax,0x4310 + int 0x2f + mov [WORD PTR XMSaddr],bx + mov [WORD PTR XMSaddr+2],es // function pointer to XMS driver + + mov ah,XMS_ALLOCUMB + mov dx,0xffff // try for largest block possible + //mov ax,dx // Set available Kbytes. + call [DWORD PTR XMSaddr] + or ax,ax + jnz gotone + + cmp bl,0xb0 // error: smaller UMB is available + jne done; + + mov ah,XMS_ALLOCUMB + call [DWORD PTR XMSaddr] // DX holds largest available UMB + or ax,ax + jz done // another error... + +gotone: + mov [base],bx + mov [size],dx +done: + } + printf("base=%u ", base); printf("size=%u\n", size); + MML_UseSpace(base,size, mm); + mmi->XMSmem += size*16; + mm->UMBbase[mm->numUMBs] = base; + mm->numUMBs++; + if(mm->numUMBs < MAXUMBS) + goto getmemory; +} + + +/* +====================== += += MML_ShutdownXMS += +====================== +*/ + +void MML_ShutdownXMS(mminfo_t *mm) +{ + int i; + unsigned base; + + for (i=0;inumUMBs;i++) + { + base = mm->UMBbase[i]; + __asm + { + mov ah,XMS_FREEUMB + mov dx,[base] + call [DWORD PTR XMSaddr] + } + } +} + +//========================================================================== + +/* +====================== += += MML_UseSpace += += Marks a range of paragraphs as usable by the memory manager += This is used to mark space for the near heap, far heap, ems page frame, += and upper memory blocks += +====================== +*/ + +void MML_UseSpace(/*d*/word segstart, dword seglength, mminfo_t *mm) +{ + mmblocktype huge *scan,huge *last; + word segm; + dword oldend; + dword extra; + + scan = last = mm->mmhead; + mm->mmrover = mm->mmhead; // reset rover to start of memory + +// +// search for the block that contains the range of segments +// + while(scan->start+scan->length < segstart) + { + last = scan; + scan = scan->next; + } + + //find out how many blocks it spans! + if(seglength>0xffffu) + { +// segm=seglength/0x4000u; + segm=seglength/0xffffu; + } + else segm=1; + + //++++emsver stuff! + if(segm>1/*extra>0xfffflu*/) + { + /*__asm + { + push ds + mov ax,ds + inc ax + mov ds,ax + }*/ + + +//MML_UseSpace(?segstart?, ?length?, mm); + + /*__asm + { + pop ds + }*/ + //printf("MML_UseSpace: Segment spans two blocks!\n"); + } + +// +// take the given range out of the block +// + oldend = scan->start + scan->length; + extra = oldend - (segstart+seglength); +/* +printf("segm=%u ", segm); +printf("ex=%lu ", extra); +printf("start+seglen=%lu ", segstart+seglength); +printf("len=%u ", scan->length); +printf("segsta=%x ", segstart); +printf("seglen=%lu\n", seglength); +*/ +//segu: +//++++todo: linked list of segment! +//printf("segm=%lu\n", segm); + if(segstart == scan->start) + { + last->next = scan->next; // unlink block + MM_FreeBlock(scan, mm); + scan = last; + } + else + scan->length = segstart-scan->start; // shorten block + +// segm--; + + if(extra > 0) + { + MM_GetNewBlock(mm); + mm->mmnew->next = scan->next; + scan->next = mm->mmnew; + mm->mmnew->start = segstart+seglength; + mm->mmnew->length = extra; + mm->mmnew->attributes = LOCKBIT; + }//else if(segm>0) goto segu; + +} + +//========================================================================== + +/* +==================== += += MML_ClearBlock += += We are out of blocks, so free a purgable block += +==================== +*/ + +void MML_ClearBlock(mminfo_t *mm) +{ + mmblocktype huge *scan,huge *last; + + scan = mm->mmhead->next; + + while(scan) + { + if(!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS)) + { + MM_FreePtr(scan->useptr, mm); + return; + } + scan = scan->next; + } + + printf("MM_ClearBlock: No purgable blocks!\n"); +} + + +//========================================================================== + +/* +=================== += += MM_Startup += += Grabs all space from turbo with malloc/farmalloc += Allocates bufferseg misc buffer += +=================== +*/ + +void MM_Startup(mminfo_t *mm, mminfotype *mmi) +{ + int i; + dword length,seglength; + //dword length; word seglength; + void huge *start; + word segstart;//,endfree; + + if(mm->mmstarted) + MM_Shutdown(mm); + + mm->mmstarted = true; + mm->bombonerror = true; + +// +// set up the linked list (everything in the free list; +// + //printf(" linked list making!\n"); + mm->mmhead = NULL; + mm->mmfree = &(mm->mmblocks[0]); + for(i=0;immblocks[i].next = &(mm->mmblocks[i+1]); + } + mm->mmblocks[i].next = NULL; + +// +// locked block of all memory until we punch out free space +// + //printf(" newblock making!\n"); + MM_GetNewBlock(mm); + mm->mmhead = mm->mmnew; // this will allways be the first node + mm->mmnew->start = 0; + mm->mmnew->length = 0xffff; + mm->mmnew->attributes = LOCKBIT; + mm->mmnew->next = NULL; + mm->mmrover = mm->mmhead; + +// +// get all available near conventional memory segments +// +//---- length=coreleft(); + printf(" nearheap making!\n"); + _heapgrow(); + length=_memmax();//(dword)GetFreeSize(); + start = (void huge *)(mm->nearheap = malloc(length)); + length -= 16-(FP_OFF(start)&15); + length -= SAVENEARHEAP; + seglength = length / 16; // now in paragraphs + segstart = FP_SEG(start)+(FP_OFF(start)+15)/16; + MML_UseSpace(segstart,seglength, mm); + mmi->nearheap = length; + printf("start=%FP segstart=%X seglen=%lu len=%lu\n", start, segstart, seglength, length); + printf(" near heap ok!\n"); + +// +// get all available far conventional memory segments +// +//---- length=farcoreleft(); + printf(" farheap making!\n"); + _fheapgrow(); + length=(dword)GetFarFreeSize();//0xffffUL*4UL; + //start = mm->farheap = halloc(length, 1); + start = mm->farheap = _fmalloc(length); + length -= 16-(FP_OFF(start)&15); + length -= SAVEFARHEAP; + seglength = length / 16; // now in paragraphs + segstart = FP_SEG(start)+(FP_OFF(start)+15)/16; + MML_UseSpace(segstart,seglength, mm); + mmi->farheap = length; + printf("start=%FP segstart=%X seglen=%lu len=%lu\n", start, segstart, seglength, length); + printf(" far heap ok!\n"); + + mmi->mainmem = mmi->nearheap + mmi->farheap; + + getch(); + +// +// detect EMS and allocate up to 64K at page frame +// +printf(" EMS1\n"); +printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); //bug! + mmi->EMSmem = 0; + for(i = 1;i < __argc;i++) + { + if(US_CheckParm(__argv[i],ParmStringsexmm) == 0) + goto emsskip; // param NOEMS + } +printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); //bug! + if(MML_CheckForEMS()) + { +printf(" EMS2\n"); +printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); //bug! + MML_SetupEMS(mm); // allocate space +printf(" EMS3\n"); +printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); //bug! + //TODO: EMS4! AND EMS 3.2 MASSIVE DATA HANDLMENT! + MML_UseSpace(mm->EMSpageframe,(MAPPAGES)*0x4000lu, mm); +printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); //bug! +printf(" EMS4\n"); + //if(mm->EMSVer<0x40) + MM_MapEMS(mm, mmi); // map in used pages + //else + //MM_MapXEMS(mm, mmi); // map in used pages + } + +// +// detect XMS and get upper memory blocks +// +emsskip: + mmi->XMSmem = 0; + for(i = 1;i < __argc;i++) + { + if(US_CheckParm(__argv[i],ParmStringsexmm) == 0) + goto xmsskip; // param NOXMS + } +printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); //bug! + if(MML_CheckForXMS(mm)) + { +printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); //bug! +printf(" XMS!\n"); + MML_SetupXMS(mm, mmi); // allocate as many UMBs as possible + } + +// +// allocate the misc buffer +// +xmsskip: + mm->mmrover = mm->mmhead; // start looking for space after low block + + MM_GetPtr(&(mm->bufferseg),BUFFERSIZE, mm, mmi); +} + +//========================================================================== + +/* +==================== += += MM_Shutdown += += Frees all conventional, EMS, and XMS allocated += +==================== +*/ + +void MM_Shutdown(mminfo_t *mm) +{ + if(!(mm->mmstarted)) + return; + + _ffree(mm->farheap); printf(" far freed\n"); + free(mm->nearheap); printf(" near freed\n"); + if(MML_CheckForEMS()){ MML_ShutdownEMS(mm); printf(" EMS freed\n"); } + if(MML_CheckForXMS(mm)){ MML_ShutdownXMS(mm); printf(" XMS freed\n"); } +} + +//========================================================================== + +/* +==================== += += MM_GetPtr += += Allocates an unlocked, unpurgable block += +==================== +*/ + +void MM_GetPtr(memptr *baseptr,dword size, mminfo_t *mm, mminfotype *mmi) +{ + mmblocktype huge *scan,huge *lastscan,huge *endscan,huge *purge,huge *next; + int search; + unsigned needed,startseg; + + needed = (size+15)/16; // convert size from bytes to paragraphs + + MM_GetNewBlock(mm); // fill in start and next after a spot is found + mm->mmnew->length = needed; + mm->mmnew->useptr = baseptr; + mm->mmnew->attributes = BASEATTRIBUTES; + + for(search = 0; search<3; search++) + { + // + // first search: try to allocate right after the rover, then on up + // second search: search from the head pointer up to the rover + // third search: compress memory, then scan from start + if(search == 1 && mm->mmrover == mm->mmhead) + search++; + + switch(search) + { + case 0: + lastscan = mm->mmrover; + scan = mm->mmrover->next; + endscan = NULL; + break; + case 1: + lastscan = mm->mmhead; + scan = mm->mmhead->next; + endscan = mm->mmrover; + break; + case 2: + MM_SortMem(mm); + lastscan = mm->mmhead; + scan = mm->mmhead->next; + endscan = NULL; + break; + } + + startseg = lastscan->start + lastscan->length; + + while(scan != endscan) + { + if(scan->start - startseg >= needed) + { + // + // got enough space between the end of lastscan and + // the start of scan, so throw out anything in the middle + // and allocate the new block + // + purge = lastscan->next; + lastscan->next = mm->mmnew; + mm->mmnew->start = *(unsigned *)baseptr = startseg; + mm->mmnew->next = scan; + while(purge != scan) + { // free the purgable block + next = purge->next; + MM_FreeBlock(purge, mm); + purge = next; // purge another if not at scan + } + mm->mmrover = mm->mmnew; + return; // good allocation! + } + + // + // if this block is purge level zero or locked, skip past it + // + if((scan->attributes & LOCKBIT) + || !(scan->attributes & PURGEBITS) ) + { + lastscan = scan; + startseg = lastscan->start + lastscan->length; + } + + + scan=scan->next; // look at next line + } + } + + if (mm->bombonerror) + { + printf(OUT_OF_MEM_MSG,(size-mmi->nearheap)); + exit(-5); + } + else + mm->mmerror = true; +} + +//========================================================================== + +/* +==================== += += MM_FreePtr += += Allocates an unlocked, unpurgable block += +==================== +*/ + +void MM_FreePtr(memptr *baseptr, mminfo_t *mm) +{ + mmblocktype huge *scan,huge *last; + + last = mm->mmhead; + scan = last->next; + + if(baseptr == mm->mmrover->useptr) // removed the last allocated block + mm->mmrover = mm->mmhead; + + while(scan->useptr != baseptr && scan) + { + last = scan; + scan = scan->next; + } + + if(!scan) + { + printf("MM_FreePtr: Block not found!\n"); + return; + } + + last->next = scan->next; + + MM_FreeBlock(scan, mm); +} +//========================================================================== + +/* +===================== += += MM_SetPurge += += Sets the purge level for a block (locked blocks cannot be made purgable) += +===================== +*/ + +void MM_SetPurge(memptr *baseptr, int purge, mminfo_t *mm) +{ + mmblocktype huge *start; + + start = mm->mmrover; + + do + { + if(mm->mmrover->useptr == baseptr) + break; + + mm->mmrover = mm->mmrover->next; + + if(!mm->mmrover) + mm->mmrover = mm->mmhead; + else if(mm->mmrover == start) + { + printf("MM_SetPurge: Block not found!"); + return; + } + + } while(1); + + mm->mmrover->attributes &= ~PURGEBITS; + mm->mmrover->attributes |= purge; +} + +//========================================================================== + +/* +===================== += += MM_SetLock += += Locks / unlocks the block += +===================== +*/ + +void MM_SetLock(memptr *baseptr, boolean locked, mminfo_t *mm) +{ + mmblocktype huge *start; + + start = mm->mmrover; + + do + { + if(mm->mmrover->useptr == baseptr) + break; + + mm->mmrover = mm->mmrover->next; + + if(!mm->mmrover) + mm->mmrover = mm->mmhead; + else if(mm->mmrover == start) + { + printf("MM_SetLock: Block not found!"); + return; + } + + } while(1); + + mm->mmrover->attributes &= ~LOCKBIT; + mm->mmrover->attributes |= locked*LOCKBIT; +} + +//========================================================================== + +/* +===================== += += MM_SortMem += += Throws out all purgable stuff and compresses movable blocks += +===================== +*/ + +void MM_SortMem(mminfo_t *mm) +{ + mmblocktype huge *scan,huge *last,huge *next; + unsigned start,length,source,dest,oldborder; + int playing; + + // + // lock down a currently playing sound + // +/*++++ playing = SD_SoundPlaying (); + if(playing) + { + switch (SoundMode) + { + case sdm_PC: + playing += STARTPCSOUNDS; + break; + case sdm_AdLib: + playing += STARTADLIBSOUNDS; + break; + } + MM_SetLock(&(memptr)audiosegs[playing],true); + } + + + SD_StopSound();*/ +// oldborder = bordercolor; +// VW_ColorBorder (15); + + if(beforesort) + beforesort(); + + scan = mm->mmhead; + + last = NULL; // shut up compiler warning + + while(scan) + { + if(scan->attributes & LOCKBIT) + { + // + // block is locked, so try to pile later blocks right after it + // + start = scan->start + scan->length; + } + else + { + if(scan->attributes & PURGEBITS) + { + // + // throw out the purgable block + // + next = scan->next; + MM_FreeBlock(scan, mm); + last->next = next; + scan = next; + continue; + } + else + { + // + // push the non purgable block on top of the last moved block + // + if(scan->start != start) + { + length = scan->length; + source = scan->start; + dest = start; + while(length > 0xf00) + { + movedata(source,0,dest,0,0xf00*16); + length -= 0xf00; + source += 0xf00; + dest += 0xf00; + } + movedata(source,0,dest,0,length*16); + + scan->start = start; + *(unsigned *)scan->useptr = start; + } + start = scan->start + scan->length; + } + } + + last = scan; + scan = scan->next; // go to next block + } + + mm->mmrover = mm->mmhead; + + if(aftersort) + aftersort(); + +// VW_ColorBorder (oldborder); + +/*++++ if(playing) + MM_SetLock(&(memptr)audiosegs[playing],false);*/ +} + + +//========================================================================== + +//****#if 0 +/* +===================== += += MM_ShowMemory += +===================== +*/ + +void MM_ShowMemory(/*page_t *page, */mminfo_t *mm) +{ + mmblocktype huge *scan; + word color,temp; + long end,owner; + word chx,chy; + byte scratch[160],str[16]; + +//**** VW_SetDefaultColors(); +//**** VW_SetLineWidth(40); +//++++mh temp = bufferofs; +//++++mh bufferofs = 0; +//**** VW_SetScreen (0,0); + + scan = mm->mmhead; + + end = -1; + +CA_OpenDebug (); + + chx=0; + chy=0; + + while(scan) + { + if(scan->attributes & PURGEBITS) + color = 5; // dark purple = purgable + else + color = 9; // medium blue = non purgable + if(scan->attributes & LOCKBIT) + color = 12; // red = locked + if(scan->start<=end) + { + //printf("); + write(debughandle,"\nMM_ShowMemory: Memory block order currupted!\n",strlen("\nMM_ShowMemory: Memory block order currupted!\n")); + //modexprint(&page, chx, chy, 1, 0, 24, "\nMM_ShowMemory: Memory block order currupted!\n"); + return; + } + end = scan->start+scan->length-1; + chy = scan->start/320; + chx = scan->start%320; + //modexhlin(page, scan->start, (unsigned)end, chy, color); + //for(chx=scan->start;chx+4>=(word)end;chx+=4) + //{ +//++++ modexClearRegion(page, chx, chy, 4, 4, color); + //} + +//++++ VW_Hlin(scan->start,(unsigned)end,0,color); + +//++++ VW_Plot(scan->start,0,15); +//++++ modexClearRegion(page, chx, chy, 4, 4, 15); + if(scan->next->start > end+1) +//++++ VW_Hlin(end+1,scan->next->start,0,0); // black = free + //for(chx=scan->next->start;chx+4>=(word)end+1;chx+=4) + //{ +//++++ chx+=scan->next->start; +//++++ modexClearRegion(page, chx, chy, 4, 4, 2); + //} + //modexhlin(page, end+1,scan->next->start, chy, 0); + +/* + end = scan->length-1; + y = scan->start/320; + x = scan->start%320; + VW_Hlin(x,x+end,y,color); + VW_Plot(x,y,15); + if (scan->next && scan->next->start > end+1) + VW_Hlin(x+end+1,x+(scan->next->start-scan->start),y,0); // black = free +*/ + +//****#if 0 +printf("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); //bug! +strcpy(scratch,"Seg:"); +ultoa (scan->start,str,16); +strcat (scratch,str); +strcat (scratch,"\tSize:"); +ultoa ((dword)scan->length,str,10); +strcat (scratch,str); +strcat (scratch,"\tOwner:0x"); +owner = (unsigned)scan->useptr; +ultoa (owner,str,16); +strcat (scratch,str); +strcat (scratch,"\n"); +write(debughandle,scratch,strlen(scratch)); +//modexprint(page, chx, chy, 1, 0, 24, &scratch); +//++++chy+=4; +//fprintf(stdout, "%s", scratch); +//****#endif + + scan = scan->next; + } + +CA_CloseDebug (); + +//++++mh IN_Ack(); +//**** VW_SetLineWidth(64); +//++++mh bufferofs = temp; +} +//****#endif + +//========================================================================== + +/* +===================== += += MM_DumpData += +===================== +*/ + +void MM_DumpData(mminfo_t *mm) +{ + mmblocktype far *scan,far *best; + long lowest,oldlowest; + word owner; + byte lock,purge; + FILE *dumpfile; + + + //++++free(mm->nearheap); + dumpfile = fopen ("mmdump.16","w"); + if (!dumpfile){ + printf("MM_DumpData: Couldn't open MMDUMP.16!\n"); + return; + } + + lowest = -1; + do + { + oldlowest = lowest; + lowest = 0xffff; + + scan = mm->mmhead; + while (scan) + { + owner = (word)scan->useptr; + + if (owner && owner oldlowest) + { + best = scan; + lowest = owner; + } + + scan = scan->next; + } + + if (lowest != 0xffff) + { + if (best->attributes & PURGEBITS) + purge = 'P'; + else + purge = '-'; + if (best->attributes & LOCKBIT) + lock = 'L'; + else + lock = '-'; + fprintf (dumpfile,"0x%p (%c%c) = %u\n" + ,(word)lowest,lock,purge,best->length); + } + + } while (lowest != 0xffff); + + fclose(dumpfile); + printf("MMDUMP.16 created.\n"); +} + +//========================================================================== + + +/* +====================== += += MM_UnusedMemory += += Returns the total free space without purging += +====================== +*/ + +dword MM_UnusedMemory(mminfo_t *mm) +{ + dword free; + mmblocktype huge *scan; + + free = 0; + scan = mm->mmhead; + + while(scan->next) + { + free += scan->next->start - (scan->start + scan->length); + scan = scan->next; + } + +// return free*16l; + return free; +} + +//========================================================================== + + +/* +====================== += += MM_TotalFree += += Returns the total free space with purging += +====================== +*/ + +dword MM_TotalFree(mminfo_t *mm) +{ + dword free; + mmblocktype huge *scan; + + free = 0; + scan = mm->mmhead; + + while(scan->next) + { + if((scan->attributes&PURGEBITS) && !(scan->attributes&LOCKBIT)) + free += scan->length; + free += scan->next->start - (scan->start + scan->length); + scan = scan->next; + } + +// return free*16l; + return free; +} + +//========================================================================== + +/* +===================== += += MM_Report += +===================== +*/ + +void MM_Report(/*page_t *page, */mminfo_t *mm, mminfotype *mmi) +{ + if(MML_CheckForEMS()) + { + printf("EMM v%x.%x available\n", mm->EMSVer>>4,mm->EMSVer&0x0F); + printf("totalEMSpages=%u\n", mm->totalEMSpages); + printf("freeEMSpages=%u\n", mm->freeEMSpages); + printf("EMSpageframe=%x\n", mm->EMSpageframe); + } + if(MML_CheckForXMS(mm)) printf("XMSaddr=%X\n", *XMSaddr); + printf("near=%lu\n", mmi->nearheap); + printf("far=%lu\n", mmi->farheap); + printf("EMSmem=%lu\n", mmi->EMSmem); + printf("XMSmem=%lu\n", mmi->XMSmem); + printf("mainmem=%lu\n", mmi->mainmem); + printf("UnusedMemory=%lu\n", MM_UnusedMemory(mm)); + printf("TotalFree=%lu\n", MM_TotalFree(mm)); + //mmi->nearheap+mmi->farheap+ + printf("TotalUsed=%lu\n", mmi->mainmem+mmi->EMSmem+mmi->XMSmem);//+); +// printf("\n"); +// printf("UnusedMemory=%lu kb\n", MM_UnusedMemory()/10248); +// printf("TotalFree=%lu kb\n", MM_TotalFree()/10248); +} + +//========================================================================== + +/* +===================== += += MM_EMSerr += +===================== +*/ + +void MM_EMSerr(byte *stri, byte err) +{ + //Returns a text string describing the error code in EMS.Error. + switch(err) + { + case 0x0: + strcat(stri, "successful"); + break; + case 0x80: + strcat(stri, "internal error"); + break; + case 0x81: + strcat(stri, "hardware malfunction"); + break; + case 0x82: + strcat(stri, "busy .. retry later"); + break; + case 0x83: + strcat(stri, "invalid handle"); + break; + case 0x84: + strcat(stri, "undefined function requested by application"); + break; + case 0x85: + strcat(stri, "no more handles available"); + break; + case 0x86: + strcat(stri, "error in save or restore of mapping context"); + break; + case 0x87: + strcat(stri, "insufficient memory pages in system"); + break; + case 0x88: + strcat(stri, "insufficient memory pages available"); + break; + case 0x89: + strcat(stri, "zero pages requested"); + break; + case 0x8A: + strcat(stri, "invalid logical page number encountered"); + break; + case 0x8B: + strcat(stri, "invalid physical page number encountered"); + break; + case 0x8C: + strcat(stri, "page-mapping hardware state save area is full"); + break; + case 0x8D: + strcat(stri, "save of mapping context failed"); + break; + case 0x8E: + strcat(stri, "restore of mapping context failed"); + break; + case 0x8F: + strcat(stri, "undefined subfunction"); + break; + case 0x90: + strcat(stri, "undefined attribute type"); + break; + case 0x91: + strcat(stri, "feature not supported"); + break; + case 0x92: + strcat(stri, "successful, but a portion of the source region has been overwritten"); + break; + case 0x93: + strcat(stri, "length of source or destination region exceeds length of region allocated to either source or destination handle"); + break; + case 0x94: + strcat(stri, "conventional and expanded memory regions overlap"); + break; + case 0x95: + strcat(stri, "offset within logical page exceeds size of logical page"); + break; + case 0x96: + strcat(stri, "region length exceeds 1 MB"); + break; + case 0x97: + strcat(stri, "source and destination EMS regions have same handle and overlap"); + break; + case 0x98: + strcat(stri, "memory source or destination type undefined"); + break; + case 0x9A: + strcat(stri, "specified alternate map register or DMA register set not supported"); + break; + case 0x9B: + strcat(stri, "all alternate map register or DMA register sets currently allocated"); + break; + case 0x9C: + strcat(stri, "alternate map register or DMA register sets not supported"); + break; + case 0x9D: + strcat(stri, "undefined or unallocated alternate map register or DMA register set"); + break; + case 0x9E: + strcat(stri, "dedicated DMA channels not supported"); + break; + case 0x9F: + strcat(stri, "specified dedicated DMA channel not supported"); + break; + case 0xA0: + strcat(stri, "no such handle name"); + break; + case 0xA1: + strcat(stri, "a handle found had no name, or duplicate handle name"); + break; + case 0xA2: + strcat(stri, "attempted to wrap around 1M conventional address space"); + break; + case 0xA3: + strcat(stri, "source array corrupted"); + break; + case 0xA4: + strcat(stri, "operating system denied access"); + break; + default: + strcat(stri, "undefined error"); + } +} + +//========================================================================== + +/* +===================== += += MM_BombOnError += +===================== +*/ + +void MM_BombOnError(boolean bomb, mminfo_t *mm) +{ + mm->bombonerror = bomb; +} + +void MM_GetNewBlock(mminfo_t *mm) +{ + if(!mm->mmfree) + MML_ClearBlock(mm); + mm->mmnew=mm->mmfree; + mm->mmfree=mm->mmfree->next; + /*if(!(mm->mmnew=mm->mmfree)) + { + printf("MM_GETNEWBLOCK: No free blocks!"); + return; + } + mm->mmfree=mm->mmfree->next;*/ +} + +void MM_FreeBlock(mmblocktype *x, mminfo_t *mm) +{ + x->useptr=NULL; + x->next=mm->mmfree; + mm->mmfree=x; +} + +void MM_seguin(void) +{ + __asm + { + push ds + mov ax,ds + inc ax + mov ds,ax + } +} + +void MM_segude(void) +{ + __asm + { + pop ds + } +} + +/* +pull data from far and put it into ds var +mov ax,es:si +mov x,ax +*/ +/* +ss stack segment +sp top of stack +bp bottem of stack +*/ diff --git a/16/exmmtest/16_mm.h b/16/exmmtest/16_mm.h new file mode 100644 index 00000000..a431bf7d --- /dev/null +++ b/16/exmmtest/16_mm.h @@ -0,0 +1,192 @@ +/* Catacomb Apocalypse Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// ID_MM.H + +#ifndef __16_EXMM__ +#define __16_EXMM__ + +#include +#include +//#include +#include "16_head.h" +//#include "modex16.h" +//#include "src/lib/16_ca.h" +//++++mh #include "src/lib/16_in.h" + +#ifdef __DEBUG__ // 1 == Debug/Dev ; 0 == Production/final +#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%lu bytes" +#else +#define OUT_OF_MEM_MSG "\npee\n" +#endif + + +#define SAVENEARHEAP 0x200 // space to leave in data segment +#define SAVEFARHEAP 0x400 // space to leave in far heap + +#define BUFFERSIZE 0x1000 // miscelanious, allways available buffer + +#define MAXBLOCKS 720 + + + +//-------- + +#define EMS_INT 0x67 + +#define EMS_STATUS 0x40 +#define EMS_GETFRAME 0x41 +#define EMS_GETPAGES 0x42 +#define EMS_ALLOCPAGES 0x43 +#define EMS_MAPPAGE 0x44 +#define EMS_MAPXPAGE 0x50 +#define EMS_FREEPAGES 0x45 +#define EMS_VERSION 0x46 + +//-------- + +#define XMS_VERSION 0x00 + +#define XMS_ALLOCHMA 0x01 +#define XMS_FREEHMA 0x02 + +#define XMS_GENABLEA20 0x03 +#define XMS_GDISABLEA20 0x04 +#define XMS_LENABLEA20 0x05 +#define XMS_LDISABLEA20 0x06 +#define XMS_QUERYA20 0x07 + +#define XMS_QUERYREE 0x08 +#define XMS_ALLOC 0x09 +#define XMS_FREE 0x0A +#define XMS_MOVE 0x0B +#define XMS_LOCK 0x0C +#define XMS_UNLOCK 0x0D +#define XMS_GETINFO 0x0E +#define XMS_RESIZE 0x0F + +#define XMS_ALLOCUMB 0x10 +#define XMS_FREEUMB 0x11 + +//========================================================================== + +typedef struct +{ + dword nearheap,farheap,EMSmem,XMSmem,mainmem; + //__segment segu; +} mminfotype; + +//========================================================================== + +extern void (* beforesort) (void); +extern void (* aftersort) (void); +extern void (* XMSaddr) (void); // far pointer to XMS driver + +//========================================================================== + +/* +============================================================================= + + LOCAL INFO + +============================================================================= +*/ + +#define LOCKBIT 0x80 // if set in attributes, block cannot be moved +#define PURGEBITS 3 // 0-3 level, 0= unpurgable, 3= purge first +#define PURGEMASK 0xfffc +#define BASEATTRIBUTES 0 // unlocked, non purgable + +#define MAXUMBS 12 +#define MAPPAGES 4//mm->EMSpagesmapped + +typedef struct mmblockstruct +{ + //word start,length; + word start; dword length; + unsigned attributes; + memptr *useptr; // pointer to the segment start + struct mmblockstruct huge *next; +} mmblocktype; + + +typedef struct +{ + memptr bufferseg; + boolean mmstarted, bombonerror, mmerror; + void huge *farheap; + void *nearheap; + //byte EMS_status; + unsigned totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle; + unsigned int EMSVer; + word numUMBs,UMBbase[MAXUMBS]; + //dword numUMBs,UMBbase[MAXUMBS]; + mmblocktype huge mmblocks[MAXBLOCKS],huge *mmhead,huge *mmfree,huge *mmrover,huge *mmnew; +} mminfo_t; + +/* +============================================================================= + + GLOBAL VARIABLES + +============================================================================= +*/ + + +/* +============================================================================= + + LOCAL VARIABLES + +============================================================================= +*/ + +//========================================================================== + +boolean MML_CheckForEMS(void); +byte MML_SetupEMS(mminfo_t *mm); +void MML_ShutdownEMS(mminfo_t *mm); +byte MM_MapEMS(mminfo_t *mm, mminfotype *mmi); +byte MM_MapXEMS(mminfo_t *mm, mminfotype *mmi); +boolean MML_CheckForXMS(mminfo_t *mm); +void MML_SetupXMS(mminfo_t *mm, mminfotype *mmi); +void MML_ShutdownXMS(mminfo_t *mm); +void MML_UseSpace(/*d*/word segstart, dword seglength, mminfo_t *mm); +void MML_ClearBlock(mminfo_t *mm); + +void MM_Startup(mminfo_t *mm, mminfotype *mmi); +void MM_Shutdown(mminfo_t *mm); + +void MM_GetPtr(memptr *baseptr,dword size, mminfo_t *mm, mminfotype *mmi); +void MM_FreePtr(memptr *baseptr, mminfo_t *mm); +void MM_SetPurge(memptr *baseptr, int purge, mminfo_t *mm); +void MM_SetLock(memptr *baseptr, boolean locked, mminfo_t *mm); +void MM_SortMem(mminfo_t *mm); +void MM_ShowMemory(/*page_t *page, */mminfo_t *mm); +void MM_DumpData(mminfo_t *mm); +dword MM_UnusedMemory(mminfo_t *mm); +dword MM_TotalFree(mminfo_t *mm); +void MM_Report(/*page_t *page, */mminfo_t *mm, mminfotype *mmi); +static void MM_EMSerr(byte *stri, byte err); +void MM_BombOnError(boolean bomb, mminfo_t *mm); +void MM_GetNewBlock(mminfo_t *mm); +void MM_FreeBlock(mmblocktype *x, mminfo_t *mm); + +//========================================================================== + +#endif diff --git a/16/exmmtest/EX.DSK b/16/exmmtest/EX.DSK new file mode 100644 index 0000000000000000000000000000000000000000..1b9f077efd731d713379f65eb96dc34f525ea053 GIT binary patch literal 1298 zcmWG3ElSE)a8_{6&nro-C{b|B%t=*{VqoMI5@(cRVBkt&_{hl1z`$^XaTa49qYI-H z;|GRg46_&t7~B|SfY8$=-q%;pgMpC%WB{pjb|gxrp&7Ae0#$mrI=T>RDv|a>{Nzl) zM~uKwf%u6Sl|YvQZ6{JC*iS^N1%^H`DqSOdeM4M>Lx75z82W%->%i$f28L7y5uhp- z1}>l%*%-9+oC5-Yq!vRJgA@ZZP=pUG&IOlo2C_UDsu?(eW-8u156=6AURnrK?z1P0TU6# fMvxTDCK!#wMk4dUS751z-Bu2U4Tb;zGcW)ETse%N literal 0 HcmV?d00001 diff --git a/16/exmmtest/EX.PRJ b/16/exmmtest/EX.PRJ new file mode 100644 index 0000000000000000000000000000000000000000..9c0d250c7c658ee54f02846d511762b47d518f2f GIT binary patch literal 6727 zcmeI0S#VQT7{|Yxq-{!Dy0Dk+3Q@KprA1P}jr1mIquESSDG;c%O-q%Mnzp#0rHb3= zxZ#WsKDqA;;xazCj8BeiIxcKJ`0She3SPhe2{#iG!p%}(#_>RZ_d8#{<(%)HbGPtF zyelRvav&bNA=*7GyZX0A<$98;>ZVD2C~Kmi`7<(*MEjUT`-OZ!@SxBf68xY7zkVqA zk>JNniM|w;UkQHAG}2+_8ag60M+J{D$#@*3AK8a~0)7U5VMxD1`i)FPV?@8B^9S%J z@E5$~Jtn5%2NB_L1*?w$N5wdfK|Ic44SmZr(ckcUrxTfI6g{1WaZ~Q-G=HPLmQfoQ}>63H7drI1`w~ zkY+=g!!XW8S4MXpFdwi07Xz2Dv$}HuOG`wU8x1UOU`QK*O+XjW4fFs}pcm)^wlHV_ z*apO)y9v?|q!CElA>9n=7D%@Ow*fnV+ZpsQa0j}hz)oNcxD&Vw*u|i`A>9Mqi|&2E z{pdabJP14lJPJGp>;@hOOf`%WpcE(r%)nB~!4)jNS*0;jR!7!HTKqwe-RDpuZlB_5 zcQ}g=opXeSj4^oJEjfFSkKr<2p39qv8l@6yTEQ`!SZG|fjA*&Eb9_=19_3PL4lO>b z`wCqPo32H(uEk1Si&eT7t930d)3vx<*WwCYiz{_4uF|zw!wdI9H~WQOo({>(d#Bmf z%(ZZ`ys~i>?<6AEg&&&2yV$A(0@NyQ6{^bnnM(Oy8*!d=O`vbgG};<;268xweevjE z4rV!5omDBZ(v*>axLQ>Fw3~lwfYMc_vrsyQ59H0H6{F#O*{A@XD`2Pp5SPY@Sn58 z>kT_YVXKl9BPqJPbK;YVNqqQ7xbnFZ4ZTKNr`OAg8g0oG5lxqOB6cX@$F?%gr?s?P zZBDy`vz?afluq-={b;6gn!q#DT3Rl}o;fd})9mv(R!}8X@$9sgn#=9z%*dtbH2Zvx z6RDcNM3p98(sE^-FU}=&NryayTB@T-e8#kvnv2%~&#NtcZ3vxapU-hJO`)k|PP(M! z66>Jt3~Qq;>5;oIji&R?Do;A3<>Go}%uDE!4tWUmG?QlWO4M3vuEaVxJ(s4_?DIL! zra3g1Dv~Z~xiaRJSQ~{@kVvMBXdbV78cU`-=Yox*#(K`8s_jOrvCR0L;eEqy!!E-n zL$jgQ@V)ej^rSQ-d87qWrKIv#;C*bVsy4E*&vd@-RPwddM7_Qft`fmg!7@QJMOj}? zE(I@@kShc$#jjO@69ub!^d)(sk5MVG2=@uB8C^$wyxD&^2^5xv7o+={7tp{tL9WnCk!l literal 0 HcmV?d00001 diff --git a/16/exmmtest/EXMMTEST.EXE b/16/exmmtest/EXMMTEST.EXE new file mode 100644 index 0000000000000000000000000000000000000000..345ea3093fddae9ae2bacbe2181dfabc1eca09c7 GIT binary patch literal 11318 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 #include -#include "src/lib/16_head.h" +/*#include "src/lib/16_head.h" #include "src/lib/16_ca.h" -#include "src/lib/16_mm.h" +#include "src/lib/16_mm.h"*/ +#include "16_head.h" +#include "16_ca.h" +#include "16_mm.h" //#include "src/lib/modex16.h" #pragma hdrstop @@ -42,7 +45,7 @@ void main(int argc, char *argv[]) { mminfo_t mm; mminfotype mmi; - __segment segu; + void _seg * segu; #ifdef FILERL memptr bigbuffer; char *bakapee; @@ -65,7 +68,7 @@ main(int argc, char *argv[]) #ifdef FILERL if(argv[1]) bakapee = argv[1]; - else bakapee = "data/koishi~~.pcx"; + else bakapee = "../../data/koishi~~.pcx"; #endif textInit(); @@ -95,7 +98,7 @@ main(int argc, char *argv[]) //printf("mmi.segu=%p\n", (mmi.segu)); #ifdef FILERL // bakapeehandle = open(bakapee,O_RDONLY | O_BINARY, S_IREAD); - printf("size of big buffer~=%u\n", _bmsize(segu, bigbuffer)); +//wat printf("size of big buffer~=%u\n", _bmsize(segu, bigbuffer)); // if(CA_FarRead(bakapeehandle,(void far *)&bigbuffer,sizeof(bigbuffer),&mm)) #ifdef FILEREAD printf(" read\n"); diff --git a/DEBUG.16 b/DEBUG.16 deleted file mode 100644 index b8b544cc..00000000 --- a/DEBUG.16 +++ /dev/null @@ -1,16 +0,0 @@ -Seg:0 Size:6828 Owner:0x1674 -Seg:1b85 Size:33 Owner:0x46c7 -Seg:1ba6 Size:256 Owner:0xc25c -Seg:1f4b Size:45238 Owner:0x90c3 -Seg:d022 Size:4294967263 Owner:0x91e8 -Seg:d022 Size:4294967263 Owner:0x8b04 -Seg:d022 Size:4294967263 Owner:0x26b8 -Seg:d022 Size:4294967263 Owner:0xf04e -Seg:d022 Size:4294967263 Owner:0x7f94 -Seg:d022 Size:4294967263 Owner:0xc01b -Seg:d022 Size:4294967263 Owner:0x1a2 -Seg:d022 Size:4294967263 Owner:0x9005 -Seg:d022 Size:4294967263 Owner:0x3350 -Seg:d022 Size:4294967263 Owner:0x2b8 -Seg:d022 Size:419 Owner:0x2eb8 -Seg:e000 Size:4294909951 Owner:0xc02b diff --git a/MMDUMP.16 b/MMDUMP.16 deleted file mode 100644 index 60f5dafbc176fc15bbaebf38ed3bb91cd5e35144..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 396 zcmZ{gK@I{T3`Jd=cn93+!sJsZ43l^msmvL?k6YJX$D=41W5ks8d;PyHE`XOA_C#iP zc