/* * rpl.c * * This file is part of Emu48 * * Copyright (C) 1995 Sebastien Carlier * */ #include "pch.h" #include "Emu48.h" //| SX | GX | Name //#7056A #806E9 =TEMPOB //#7056F #806EE =TEMPTOP //#70574 #806F3 =RSKTOP (B) //#70579 #806F8 =DSKTOP (D1) //#7066E #807ED =AVMEM (D) //#705B0 #8072F =INTRPPTR (D0) #define TEMPOB ((cCurrentRomType=='S')?0x7056A:0x806E9) #define TEMPTOP ((cCurrentRomType=='S')?0x7056F:0x806EE) #define RSKTOP ((cCurrentRomType=='S')?0x70574:0x806F3) #define DSKTOP ((cCurrentRomType=='S')?0x70579:0x806F8) #define AVMEM ((cCurrentRomType=='S')?0x7066E:0x807ED) #define INTRPPTR ((cCurrentRomType=='S')?0x705B0:0x8072F) DWORD RPL_SkipOb(DWORD d) { BYTE X[8]; DWORD n, l; Npeek(X,d,5); n = Npack(X, 5); // read prolog switch (n) { case 0x02911: l= 10; break; // System Binary case 0x02933: l= 21; break; // Real case 0x02955: l= 26; break; // Long Real case 0x02977: l= 37; break; // Complex case 0x0299D: l= 47; break; // Long Complex case 0x029BF: l= 7; break; // Character case 0x02BAA: l= 15; break; // Extended Pointer case 0x02E92: l= 11; break; // XLIB Name case 0x02A74: // List case 0x02AB8: // Algebraic case 0x02ADA: // Unit case 0x02D9D: // Program n=d+5; do { d=n; n=RPL_SkipOb(d); } while (d!=n); return n+5; case 0x0312B: return d; // SEMI case 0x02E48: // Global Name case 0x02E6D: // Local Name case 0x02AFC: // Tagged Npeek(X,d+5,2); n = 7 + Npack(X,2)*2; return RPL_SkipOb(d+n); case 0x02A96: // Directory d+=8; n = Read5(d); if (n==0) { return d+5; } else { d+=n; Npeek(X,d,2); n = Npack(X,2)*2 + 4; return RPL_SkipOb(d+n); } case 0x029E8: // Array case 0x02A0A: // Linked Array case 0x02A2C: // String case 0x02A4E: // Binary Integer case 0x02B1E: // Graphic case 0x02B40: // Library case 0x02B62: // Backup case 0x02B88: // Library Data case 0x02BCC: // Reserved 1 case 0x02BEE: // Reserved 2 case 0x02C10: // Reserved 3 case 0x02DCC: // Code l = 5+Read5(d+5); break; default: return d+5; } return d+l; } DWORD RPL_ObjectSize(BYTE *o) { DWORD n, l = 0; n = Npack(o, 5); // read prolog switch (n) { case 0x02911: l= 10; break; // System Binary case 0x02933: l= 21; break; // Real case 0x02955: l= 26; break; // Long Real case 0x02977: l= 37; break; // Complex case 0x0299D: l= 47; break; // Long Complex case 0x029BF: l= 7; break; // Character case 0x02BAA: l= 15; break; // Extended Pointer case 0x02E92: l= 11; break; // XLIB Name case 0x02A74: // List case 0x02AB8: // Algebraic case 0x02ADA: // Unit case 0x02D9D: // Program n=5; do { l+=n; o+=n; n=RPL_ObjectSize(o); } while (n); l += 5; break; case 0x0312B: l= 0; break; // SEMI case 0x02E48: // Global Name case 0x02E6D: // Local Name case 0x02AFC: // Tagged n = 7 + Npack(o+5,2)*2; l = n + RPL_ObjectSize(o+n); break; case 0x02A96: // Directory n = Npack(o+8,5); if (n==0) // empty dir { l=13; } else { l = 8+n; n = Npack(o+l,2)*2 + 4; l += n; l += RPL_ObjectSize(o+l); } break; case 0x029E8: // Array case 0x02A0A: // Linked Array case 0x02A2C: // String case 0x02A4E: // Binary Integer case 0x02B1E: // Graphic case 0x02B40: // Library case 0x02B62: // Backup case 0x02B88: // Library Data case 0x02BCC: // Reserved 1 case 0x02BEE: // Reserved 2 case 0x02C10: // Reserved 3 case 0x02DCC: // Code l = 5 + Npack(o+5,5); break; default: l=5; } return l; } DWORD RPL_CreateTemp(DWORD l) { DWORD a, b, c; BYTE *p; l += 6; a = Read5(TEMPTOP); b = Read5(RSKTOP); // start of available mem c = Read5(DSKTOP); // end of available mem if ((b+l)>c) return 0; // check if there is enough memory Write5(TEMPTOP, a+l); // adjust end of temporary objects Write5(RSKTOP, b+l); // adjust start of available mem Write5(AVMEM, (c-(b+l))/5); // free memory (*5 nibbles) p = (BYTE*)LocalAlloc(0,b-a); Npeek(p,a,b-a); Nwrite(p,a+l,b-a); LocalFree(p); Write5(a+l-5,l); // set temporary object length field return (a+1); // return temporary object address } DWORD RPL_Pick(UINT l) { DWORD stkp; if (l==0) return 0; stkp = Read5(DSKTOP) + (l-1)*5; return Read5(stkp); } VOID RPL_Replace(DWORD n) { DWORD stkp; stkp = Read5(DSKTOP); Write5(stkp,n); return; } VOID RPL_Push(DWORD n) { DWORD stkp, avmem; avmem = Read5(AVMEM); if (avmem==0) return; avmem--; Write5(AVMEM,avmem); stkp = Read5(DSKTOP); stkp-=5; Write5(stkp,n); Write5(DSKTOP,stkp); return; }