diff options
Diffstat (limited to 'asmcode.c')
-rw-r--r-- | asmcode.c | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/asmcode.c b/asmcode.c new file mode 100644 index 0000000..46e8283 --- /dev/null +++ b/asmcode.c @@ -0,0 +1,239 @@ +/* asmcode.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Verwaltung der Code-Datei */ +/* */ +/* Historie: 18. 5.1996 Grundsteinlegung */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include <string.h> + +#include "version.h" +#include "endian.h" +#include "chunks.h" +#include "asmdef.h" +#include "asmsub.h" + +static Word LenSoFar; +static LongInt RecPos,LenPos; + +#define CodeBufferSize 512 + +static Word CodeBufferFill; +static Byte CodeBuffer[CodeBufferSize+1]; + +/** + static Boolean Write2(void *Buffer) +BEGIN + Boolean OK; + + if (BigEndian) WSwap(Buffer,2); + OK=(fwrite(Buffer,1,2,PrgFile)==2); + if (BigEndian) WSwap(Buffer,2); + return OK; +END + + static Boolean Write4(void *Buffer) +BEGIN + Boolean OK; + + if (BigEndian) DSwap(Buffer,4); + OK=(fwrite(Buffer,1,4,PrgFile)==4); + if (BigEndian) DSwap(Buffer,4); + return OK; +END +**/ + static void FlushBuffer(void) +BEGIN + if (CodeBufferFill>0) + BEGIN + if (fwrite(CodeBuffer,1,CodeBufferFill,PrgFile)!=CodeBufferFill) ChkIO(10004); + CodeBufferFill=0; + END +END + + void DreheCodes(void) +BEGIN + int z; + LongInt l=CodeLen*Granularity(); + + switch (ActListGran) + BEGIN + case 2: + for (z=0; z<(l>>1); z++) + WAsmCode[z]=((WAsmCode[z]&0xff)<<8)+((WAsmCode[z]&0xff00)>>8); + break; + case 4: + for (z=0; z<(l>>2); z++) + { +#ifdef __STDC__ + DAsmCode[z]=((DAsmCode[z]&0xff000000u)>>24)+ + ((DAsmCode[z]&0x00ff0000u)>>8)+ + ((DAsmCode[z]&0x0000ff00u)<<8)+ + ((DAsmCode[z]&0x000000ffu)<<24); +#else + DAsmCode[z]=((DAsmCode[z]&0xff000000)>>24)+ + ((DAsmCode[z]&0x00ff0000)>>8)+ + ((DAsmCode[z]&0x0000ff00)<<8)+ + ((DAsmCode[z]&0x000000ff)<<24); +#endif + } + break; + END +END + +/*--- neuen Record in Codedatei anlegen. War der bisherige leer, so wird --- + ---- dieser ueberschrieben. ------------------------------------------------*/ + + static void WrRecHeader(void) +BEGIN + Byte b; + + if (ActPC!=SegCode) + BEGIN + b=FileHeaderDataRec; if (fwrite(&b,1,1,PrgFile)!=1) ChkIO(10004); + END + if (fwrite(&HeaderID,1,1,PrgFile)!=1) ChkIO(10004); + if (ActPC!=SegCode) + BEGIN + b=ActPC; if (fwrite(&b,1,1,PrgFile)!=1) ChkIO(10004); + b=Grans[ActPC]; if (fwrite(&b,1,1,PrgFile)!=1) ChkIO(10004); + END +END + + void NewRecord(LargeWord NStart) +BEGIN + LongInt h; + LongWord PC; + + FlushBuffer(); + if (LenSoFar==0) + BEGIN + if (fseek(PrgFile,RecPos,SEEK_SET)!=0) ChkIO(10003); + WrRecHeader(); + h=NStart; + if (NOT Write4(PrgFile,&h)) ChkIO(10004); + LenPos=ftell(PrgFile); + if (NOT Write2(PrgFile,&LenSoFar)) ChkIO(10004); + END + else + BEGIN + h=ftell(PrgFile); + if (fseek(PrgFile,LenPos,SEEK_SET)!=0) ChkIO(10003); + if (NOT Write2(PrgFile,&LenSoFar)) ChkIO(10004); + if (fseek(PrgFile,h,SEEK_SET)!=0) ChkIO(10003); + + RecPos=h; LenSoFar=0; + WrRecHeader(); + PC=NStart; + if (NOT Write4(PrgFile,&PC)) ChkIO(10004); + LenPos=ftell(PrgFile); + if (NOT Write2(PrgFile,&LenSoFar)) ChkIO(10004); + END +END + +/*--- Codedatei eroeffnen --------------------------------------------------*/ + + void OpenFile(void) +BEGIN + Word h; + + errno=0; + PrgFile=fopen(OutName,OPENWRMODE); + if (PrgFile==Nil) ChkIO(10001); + + errno=0; h=FileMagic; + if (NOT Write2(PrgFile,&h)) ChkIO(10004); + + CodeBufferFill=0; + RecPos=ftell(PrgFile); LenSoFar=0; + NewRecord(PCs[ActPC]); +END + +/*---- Codedatei schliessen -------------------------------------------------*/ + + void CloseFile(void) +BEGIN + Byte Head; + String h; + LongWord Adr; + + sprintf(h,"AS %s/%s-%s",Version,ARCHPRNAME,ARCHSYSNAME); + + NewRecord(PCs[ActPC]); + fseek(PrgFile,RecPos,SEEK_SET); + + if (StartAdrPresent) + BEGIN + Head=FileHeaderStartAdr; + if (fwrite(&Head,sizeof(Head),1,PrgFile)!=1) ChkIO(10004); + Adr=StartAdr; + if (NOT Write4(PrgFile,&Adr)) ChkIO(10004); + END + + Head=FileHeaderEnd; + if (fwrite(&Head,sizeof(Head),1,PrgFile)!=1) ChkIO(10004); + if (fwrite(h,1,strlen(h),PrgFile)!=strlen(h)) ChkIO(10004); + fclose(PrgFile); if (Magic!=0) unlink(OutName); +END + +/*--- erzeugten Code einer Zeile in Datei ablegen ---------------------------*/ + + void WriteBytes(void) +BEGIN + Word ErgLen; + + if (CodeLen==0) return; ErgLen=CodeLen*Granularity(); + if ((TurnWords!=0)!=(BigEndian!=0)) DreheCodes(); + if (((LongInt)LenSoFar)+((LongInt)ErgLen)>0xffff) NewRecord(PCs[ActPC]); + if (CodeBufferFill+ErgLen<CodeBufferSize) + BEGIN + memcpy(CodeBuffer+CodeBufferFill,BAsmCode,ErgLen); + CodeBufferFill+=ErgLen; + END + else + BEGIN + FlushBuffer(); + if (ErgLen<CodeBufferSize) + BEGIN + memcpy(CodeBuffer,BAsmCode,ErgLen); CodeBufferFill=ErgLen; + END + else if (fwrite(BAsmCode,1,ErgLen,PrgFile)!=ErgLen) ChkIO(10004); + END + LenSoFar+=ErgLen; + if ((TurnWords!=0)!=(BigEndian!=0)) DreheCodes(); +END + + void RetractWords(Word Cnt) +BEGIN + Word ErgLen; + + ErgLen=Cnt*Granularity(); + if (LenSoFar<ErgLen) + BEGIN + WrError(1950); return; + END + + if (MakeUseList) DeleteChunk(SegChunks+ActPC,ProgCounter()-Cnt,Cnt); + + PCs[ActPC]-=Cnt; + + if (CodeBufferFill>=ErgLen) CodeBufferFill-=ErgLen; + else + BEGIN + if (fseek(PrgFile,-(ErgLen-CodeBufferFill),SEEK_CUR)==-1) + ChkIO(10004); + CodeBufferFill=0; + END + + LenSoFar-=ErgLen; + + Retracted=True; +END + + void asmcode_init(void) +BEGIN +END |