Browse Source

replace libGDCC with new allocator, merge lithlib into lithmain

master
Alison Watson 10 months ago
parent
commit
c1da4a06cd
23 changed files with 387 additions and 81 deletions
  1. +1
    -1
      credits.txt
  2. BIN
      pk7/acs/lithlib.bin
  3. BIN
      pk7/acs/lithmain.bin
  4. +0
    -1
      pk7/lzscript/Playsim/Events.zsc
  5. +2
    -2
      source/d_vm.c
  6. +7
    -21
      source/include/m_memory.h
  7. +20
    -1
      source/include/m_str.h
  8. +1
    -0
      source/include/m_types.h
  9. +1
    -1
      source/include/m_vec.h
  10. +2
    -2
      source/m_file.c
  11. +6
    -7
      source/m_math.c
  12. +310
    -0
      source/m_memory.c
  13. +5
    -5
      source/m_str.c
  14. +17
    -17
      source/p_data.c
  15. +1
    -1
      source/p_gui_bip.c
  16. +1
    -1
      source/p_items.c
  17. +1
    -1
      source/p_log.c
  18. +2
    -2
      source/p_notes.c
  19. +2
    -4
      source/p_obituary.c
  20. +1
    -1
      source/p_save.c
  21. +2
    -2
      source/p_weapons.c
  22. +1
    -1
      source/w_monster.c
  23. +4
    -10
      tools/genbuild.rb

+ 1
- 1
credits.txt View File

@@ -31,7 +31,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/ \*
* See <licenses/GDCC-libc.txt> for licensing of GDCC libc, as is included in *
* linked binary form in <acs/lithlib.bin>. *
* linked binary form in <acs/lithmain.bin>. *
* *
* See <licenses/base64.txt> for licensing of Base64 Decoding/Encoding, as is *
* included in linked binary form in <acs/lithmain.bin>. *


BIN
pk7/acs/lithlib.bin View File


BIN
pk7/acs/lithmain.bin View File


+ 0
- 1
pk7/lzscript/Playsim/Events.zsc View File

@@ -138,7 +138,6 @@ override void WorldLoaded(WorldEvent ev)
if(ev.isReopen) {
CallACS("Lith_WorldReopen");
} else {
CallACS("lithlib@gsinit");
CallACS("lithmain@gsinit");
CallACS("Lith_PreInit");
}


+ 2
- 2
source/d_vm.c View File

@@ -66,9 +66,9 @@ struct dcd_info const dcdinfo[0xFF] = {
noinit static Cps_Decl(memory, 0xFFFF);

/* VM state */
static struct gui_state gst;
noinit static struct gui_state gst;

static u32 r1, r2;
noinit static u32 r1, r2;

static cstr const action_names[] = {
#define ACT(name) #name,


+ 7
- 21
source/include/m_memory.h View File

@@ -14,28 +14,14 @@
#ifndef m_memory_h
#define m_memory_h

#define Calloc_real(n, s) calloc(n, s)
#define Dalloc_real(p) free(p)
#define Nalloc_real(s) calloc(1, s)
#define Malloc_real(s) malloc(s)
#define Ralloc_real(p, s) realloc(p, s)
#define Salloc_real(t) calloc(1, sizeof(t))
#include "m_types.h"

#if MEMORY_DEBUG
#include <stdio.h>
#include <ACS_ZDoom.h>
#define AllocLog(name) (ACS_BeginPrint(), \
__nprintf("%s:%i: " name, __FILE__, __LINE__), \
ACS_EndLog())
#else
#define AllocLog(name) ((void)0)
#endif
#include <stddef.h>

#define Salloc(t) Malloc(sizeof(t))

#define Calloc(n, s) (AllocLog("Calloc"), Calloc_real(n, s))
#define Dalloc(p) (AllocLog("Dalloc"), Dalloc_real(p))
#define Nalloc(s) (AllocLog("Nalloc"), Nalloc_real(s))
#define Malloc(s) (AllocLog("Malloc"), Malloc_real(s))
#define Ralloc(p, s) (AllocLog("Ralloc"), Ralloc_real(p, s))
#define Salloc(t) (AllocLog("Salloc"), Salloc_real(t))
stkcall void Dalloc(void *p);
stkcall void *Malloc(size_t s);
stkcall void *Ralloc(void *p, size_t s);

#endif

+ 20
- 1
source/include/m_str.h View File

@@ -14,6 +14,9 @@
#include <GDCC.h>
#include <stdio.h>

#define Stringify(s) #s
#define XStringify(s) Stringify(s)

#define L(name) LanguageV(name)
#define LC(name) LanguageVC(nil, name)

@@ -32,7 +35,23 @@
(ACS_BeginPrint(), PrintChrSt(s1), PrintChrSt(s2), ACS_EndStrParam())

#define fastmemset(p, s, c, ...) \
for(i32 _i = 0; _i < (c); _i++) ((byte __VA_ARGS__ *)(p))[_i] = s;
for(register i32 _i = 0; _i < (c); _i++) ((byte __VA_ARGS__ *)(p))[_i] = s

#define fastmemmove(lhs, rhs, s) \
do { \
register char *_lhs = (void *)(lhs); \
register char const *_rhs = (void *)(rhs); \
register size_t _s = (s); \
if(_lhs < _rhs) { \
while(_s--) \
*_lhs++ = *_rhs++; \
} else { \
_lhs += _s; \
_rhs += _s; \
while(_s--) \
*--_lhs = *--_rhs; \
} \
} while(0)

str l_strupper(str in);
u32 l_strhash(astr s);


+ 1
- 0
source/include/m_types.h View File

@@ -26,6 +26,7 @@

#define script [[__call("ScriptI")]]
#define script_str [[__call("ScriptS")]]
#define stkcall [[__call("StkCall")]]
#define sync [[__call("SScriptI")]]
#define sync_str [[__call("SScriptS")]]
#define optargs(x) [[__optional_args(x)]]


+ 1
- 1
source/include/m_vec.h View File

@@ -46,6 +46,6 @@
#define Vec_Clear(vec) \
(Dalloc((vec##V)), (vec##V) = nil, (vec##C) = (vec##S) = 0)

#define Vec_MoveEnd(vec, i, l) (memmove(&(vec##V)[(vec##C)], i, l), (vec##C) += (l))
#define Vec_MoveEnd(vec, i, l) (fastmemmove(&(vec##V)[(vec##C)], i, l), (vec##C) += (l))

#endif

+ 2
- 2
source/m_file.c View File

@@ -95,7 +95,7 @@ static ssize_t MemRead(void *memdata, char *buf, size_t size) {
if(size > avail)
size = avail;

memmove(buf, mem->mem + mem->pos, size);
fastmemmove(buf, mem->mem + mem->pos, size);
mem->pos += size;
return size;
}
@@ -115,7 +115,7 @@ static ssize_t MemWrite(void *memdata, cstr buf, size_t size) {
mem->mem = newmem;
}

memmove(mem->mem + mem->pos, buf, size);
fastmemmove(mem->mem + mem->pos, buf, size);
mem->mem[mem->pos += size] = '\0';
return size;
}


+ 6
- 7
source/m_math.c View File

@@ -74,15 +74,14 @@ u64 crc64_str(void __str_ars const *data, size_t len, u64 result)

i32 fastabs(i32 n)
{
__asm(
"BAnd W 1(Stk() LocReg(Lit(:n)) Lit(0x80000000_s31.0))"
"Jcnd_Tru W 1(Stk() Lit(:\"neg\"))"
"Retn W 1(LocReg(Lit(:n)))"
[[return]] __asm(
"BAnd (Stk() LocReg(Lit(:n)) Lit(0x80000000_s31.0))"
"Jcnd_Tru(Stk() Lit(:\"neg\"))"
"Retn (LocReg(Lit(:n)))"
":\"neg\""
"Neg:I W 1(Stk() LocReg(Lit(:n)))"
"Retn W 1(Stk())"
"Neg:I (Stk() LocReg(Lit(:n)))"
"Retn (Stk())"
);
return 0; /* shh... */
}

k64 powlk(k64 x, i32 y)


+ 310
- 0
source/m_memory.c View File

@@ -0,0 +1,310 @@
/* ---------------------------------------------------------------------------|
*
* Distributed under the CC0 public domain license.
* By Alison G. Watson. Attribution is encouraged, though not required.
* See licenses/cc0.txt for more information.
*
* ---------------------------------------------------------------------------|
*
* Memory allocations.
*
* ---------------------------------------------------------------------------|
*/

#include "common.h"

#define _mem_idn 0x71711177
#define _mem_beg 0xADEADBED
#define _mem_frg 64
#define _mem_siz 268435456

#define _pls_siz 67108864

enum {
_tag_free,
_tag_static,
};

struct mem_blk {
struct mem_blk *prv, *nxt;
size_t siz;
u32 tag, idn;
char dat[];
};

struct mem_top {
struct mem_blk beg, *cur;
char dat[];
};

noinit static
char mem_dat[_mem_siz];

static
struct mem_top *mem_top;

noinit static
char pls_stk[_pls_siz], *pls_cur;

stkcall static
void AllocInit(void) {
mem_top = (void *)mem_dat;

mem_top->beg.prv = mem_top->beg.nxt = mem_top->cur = (void *)mem_top->dat;
mem_top->beg.tag = _tag_static;
mem_top->beg.idn = _mem_beg;

mem_top->cur->prv = mem_top->cur->nxt = &mem_top->beg;
mem_top->cur->tag = _tag_free;
mem_top->cur->siz = sizeof(mem_dat) - sizeof(struct mem_top);
}

stkcall static
struct mem_blk *MergeAdjacent(struct mem_blk *blk, struct mem_blk *adj) {
adj->siz += blk->siz;
adj->nxt = blk->nxt;
adj->nxt->prv = adj;

if(blk == mem_top->cur) {
mem_top->cur = adj;
}

return adj;
}

#ifndef NDEBUG
stkcall static
struct mem_blk *CheckUsedBlock(struct mem_blk *blk, cstr func) {
if((void *)blk < (void *)mem_dat ||
(void *)blk > (void *)(mem_dat + sizeof mem_dat)) {
Str(err, s" ERROR: out of bounds block ");
ACS_BeginPrint();
PrintChrSt(func);
ACS_PrintString(err);
ACS_PrintHex((uintptr_t)blk);
ACS_EndLog();
return nil;
}

if(blk->idn != _mem_idn) {
Str(err, s" ERROR: invalid identifier for ");
ACS_BeginPrint();
PrintChrSt(func);
ACS_PrintString(err);
ACS_PrintHex((uintptr_t)blk);
ACS_EndLog();
return nil;
}

if(blk->tag == _tag_free) {
Str(err, s" ERROR: already freed ");
ACS_BeginPrint();
PrintChrSt(func);
ACS_PrintString(err);
ACS_PrintHex((uintptr_t)blk);
ACS_EndLog();
return nil;
}

return blk;
}
#else
#define CheckUsedBlock(blk, func) blk
#endif

#define GetBlock(p) \
((struct mem_blk *)((char *)p - sizeof(struct mem_blk)))

stkcall
void Dalloc(register void *p) {
register struct mem_blk *blk;

if(!p) {
return;
}

#ifndef NDEBUG
if(!mem_top) {
Str(err, s"Dalloc ERROR: memory not initialized but freeing pointer");
ACS_BeginPrint();
ACS_PrintString(err);
ACS_EndLog();
return;
}
#endif

blk = CheckUsedBlock(GetBlock(p), __func__);
blk->tag = _tag_free;

if(blk->prv->tag == _tag_free) blk = MergeAdjacent(blk, blk->prv);
if(blk->nxt->tag == _tag_free) MergeAdjacent(blk->nxt, blk);
}

stkcall
void *Malloc(register size_t rs) {
/* TODO: tagging */
register struct mem_blk *cur, *blk, *end;
register size_t s = rs + sizeof(struct mem_blk);

if(!mem_top) {
AllocInit();
}

end = (cur = blk = mem_top->cur)->prv;

do {
if(cur == end) {
/* well, no more memory to check...
* don't worry, this won't ever really happen, right?
*/
#ifndef NDEBUG
Str(err, s"Malloc ERROR: out of memory - couldn't allocate ");
ACS_BeginPrint();
ACS_PrintString(err);
ACS_PrintInt(s);
ACS_EndLog();
#endif
return nil;
} else if(cur->tag != _tag_free) {
blk = cur = cur->nxt;
} else {
cur = cur->nxt;
}
} while(blk->tag != _tag_free || blk->siz < s);

register size_t rest = blk->siz - s;

if(rest > _mem_frg) {
register struct mem_blk *nxt = (void *)&blk->dat[rs];

nxt->prv = blk;
nxt->nxt = blk->nxt;
nxt->nxt->prv = nxt;
nxt->siz = rest;
nxt->tag = _tag_free;
nxt->idn = _mem_idn;

blk->nxt = nxt;
blk->siz = s;
}

blk->tag = _tag_static; /* TODO */
blk->idn = _mem_idn;
fastmemset(blk->dat, 0, rs);

mem_top->cur = blk->nxt;

return blk->dat;
}

stkcall
void *Ralloc(register void *p, register size_t s) {
register size_t os;
register char *nxt;

if(!p) {
return Malloc(s);
}

os = CheckUsedBlock(GetBlock(p), __func__)->siz - sizeof(struct mem_blk);

nxt = Malloc(s);

if(!nxt) {
return nil;
}

fastmemmove(nxt, p, min(os, s));
Dalloc(p);

if(os < s) {
fastmemset(&nxt[os], 0, s - os);
}

return nxt;
}

stkcall
void __sta *__GDCC__alloc(register void __sta *p, register size_t s) {
if(!p) {
return Malloc(s);
} else if(s == 0) {
Dalloc(p);
return 0;
} else {
return Ralloc(p, s);
}
}

stkcall
void __GDCC__alloc_dump(void) {
struct mem_blk *blk = mem_top->cur;

do {
ACS_BeginPrint();
PrintChars("blk:", 4);
ACS_PrintHex((uintptr_t)blk);
PrintChars(" prv:", 5);
ACS_PrintHex((uintptr_t)blk->prv);
PrintChars(" nxt:", 5);
ACS_PrintHex((uintptr_t)blk->nxt);
PrintChars(" siz:", 5);
ACS_PrintHex(blk->siz);
PrintChars(" tag:", 5);
ACS_PrintInt(blk->tag);
PrintChars(" idn:", 5);
ACS_PrintHex(blk->idn);
ACS_EndLog();

blk = blk->nxt;
} while(blk != mem_top->cur);
}

stkcall
void *__GDCC__Plsa(u32 s) {
[[return]] __asm(
"Jcnd_Tru(Sta(Lit(:pls_cur)) Lit(:\"ok\"))"
"Move (Sta(Lit(:pls_cur)) Lit(:pls_stk))"
":\"ok\""
"Move (Stk() Sta(Lit(:pls_cur)))"
"Add:U(Sta(Lit(:pls_cur)) Sta(Lit(:pls_cur)) LocReg(Lit(:s)))"
#ifndef NDEBUG
"CmpGT:U (Stk() Sta(Lit(:pls_cur))"
" Lit(+ :pls_stk " XStringify(_pls_siz) "_32.0))"
"Jcnd_Nil(Stk() Lit(:\"overflow\"))"
#endif
"Retn (Stk())"
":\"overflow\""
);

#ifndef NDEBUG
Str(err, s"Plsa ERROR: stack overflow ");
ACS_BeginPrint();
ACS_PrintString(err);
ACS_PrintHex((uintptr_t)pls_cur);
ACS_PrintChar(' ');
ACS_PrintInt(s);
ACS_EndLog();
return nil;
#endif
}

stkcall
void __GDCC__Plsf(void *p) {
#ifndef NDEBUG
if(p >= (void *)pls_cur) {
Str(err, s"Plsf ERROR: incorrect stack pointer ");
ACS_BeginPrint();
ACS_PrintString(err);
ACS_PrintHex((uintptr_t)p);
ACS_PrintChar(' ');
ACS_PrintHex((uintptr_t)pls_cur);
ACS_EndLog();
return;
}
#endif

pls_cur = p;
}

/* EOF */

+ 5
- 5
source/m_str.c View File

@@ -78,7 +78,7 @@ char *lstrcpy3(char *out, cstr s1, cstr s2, cstr s3)

i32 lstrcmp_str(cstr s1, astr s2)
{
register i32 res;
i32 res;

while((res = *s1 - *s2++) == 0)
if(*s1++ == '\0') break;
@@ -90,7 +90,7 @@ i32 faststrcmp(cstr s1, cstr s2)
{
if(s1 == s2) return 0;

register i32 res;
i32 res;

while((res = *s1 - *s2++) == 0)
if(*s1++ == '\0') break;
@@ -102,7 +102,7 @@ i32 faststrcasecmp(cstr s1, cstr s2)
{
if(s1 == s2) return 0;

register i32 res;
i32 res;

while((res = ToUpper(*s1) - ToUpper(*s2++)) == 0)
if(*s1++ == '\0') break;
@@ -111,7 +111,7 @@ i32 faststrcasecmp(cstr s1, cstr s2)
}

cstr scoresep(i96 num) {
static char out[48];
noinit static char out[48];

if(!num) {
out[0] = '0';
@@ -139,7 +139,7 @@ cstr scoresep(i96 num) {
}

cstr alientext(i32 num) {
static char out[80];
noinit static char out[80];

if(!num) {
strcpy(out, u8"");


+ 17
- 17
source/p_data.c View File

@@ -21,29 +21,29 @@

static void SetupAttributes(struct player *p)
{
memmove(p->attr.names[at_acc], "ACC", 3);
memmove(p->attr.names[at_def], "DEF", 3);
memmove(p->attr.names[at_str], "STR", 3);
memmove(p->attr.names[at_vit], "VIT", 3);
memmove(p->attr.names[at_stm], "STM", 3);
memmove(p->attr.names[at_luk], "LUK", 3);
fastmemmove(p->attr.names[at_acc], "ACC", 3);
fastmemmove(p->attr.names[at_def], "DEF", 3);
fastmemmove(p->attr.names[at_str], "STR", 3);
fastmemmove(p->attr.names[at_vit], "VIT", 3);
fastmemmove(p->attr.names[at_stm], "STM", 3);
fastmemmove(p->attr.names[at_luk], "LUK", 3);

switch(p->pclass) {
case pcl_marine: memmove(p->attr.names[at_spc], "RGE", 3); break;
case pcl_cybermage: memmove(p->attr.names[at_spc], "CON", 3); break;
case pcl_informant: memmove(p->attr.names[at_spc], "ADR", 3); break;
case pcl_wanderer: memmove(p->attr.names[at_spc], "AGI", 3); break;
case pcl_assassin: memmove(p->attr.names[at_spc], "RSH", 3); break;
case pcl_darklord: memmove(p->attr.names[at_spc], "REF", 3); break;
case pcl_thoth: memmove(p->attr.names[at_spc], "???", 3); break;
case pcl_marine: fastmemmove(p->attr.names[at_spc], "RGE", 3); break;
case pcl_cybermage: fastmemmove(p->attr.names[at_spc], "CON", 3); break;
case pcl_informant: fastmemmove(p->attr.names[at_spc], "ADR", 3); break;
case pcl_wanderer: fastmemmove(p->attr.names[at_spc], "AGI", 3); break;
case pcl_assassin: fastmemmove(p->attr.names[at_spc], "RSH", 3); break;
case pcl_darklord: fastmemmove(p->attr.names[at_spc], "REF", 3); break;
case pcl_thoth: fastmemmove(p->attr.names[at_spc], "???", 3); break;
}

if(p->pclass & pcl_robot) {
memmove(p->attr.names[at_vit], "POT", 3);
memmove(p->attr.names[at_stm], "REP", 3);
fastmemmove(p->attr.names[at_vit], "POT", 3);
fastmemmove(p->attr.names[at_stm], "REP", 3);
} else if(p->pclass & pcl_nonhuman) {
memmove(p->attr.names[at_vit], "POT", 3);
memmove(p->attr.names[at_stm], "REG", 3);
fastmemmove(p->attr.names[at_vit], "POT", 3);
fastmemmove(p->attr.names[at_stm], "REG", 3);
}

p->attr.expprev = 0;


+ 1
- 1
source/p_gui_bip.c View File

@@ -232,7 +232,7 @@ static void SearchUI(struct gui_state *g, struct player *p) {
u64 crc = crc64(txt_buf, txt_len);

char query[128];
memmove(query, txt_buf, txt_len);
fastmemmove(query, txt_buf, txt_len);
query[txt_len] = '\0';

p->bip.resnum = p->bip.rescur = 0;


+ 1
- 1
source/p_items.c View File

@@ -177,7 +177,7 @@ void P_Inv_PInit(struct player *p)
[_inv_legs] = {2, 3, "Legs", _cont_body},
};

memmove(p->inv, baseinv, sizeof baseinv);
fastmemmove(p->inv, baseinv, sizeof baseinv);

for(i32 i = 0; i < _inv_num; i++) {
ListCtor(&p->inv[i].items);


+ 1
- 1
source/p_log.c View File

@@ -31,7 +31,7 @@ static void LogV(i32 levl) {

static void LogPop(struct player *p) {
p->log.hudC--;
memmove(&p->log.hudV[0], &p->log.hudV[1], sizeof p->log.hudV[0] * p->log.hudC);
fastmemmove(&p->log.hudV[0], &p->log.hudV[1], sizeof p->log.hudV[0] * p->log.hudC);
}

static void LogH(struct player *p, struct logdat *ld) {


+ 2
- 2
source/p_notes.c View File

@@ -46,8 +46,8 @@ void P_CBI_TabNotes(struct gui_state *g, struct player *p)
cstr s = Cps_Expand(CBIState(g)->notebox.txtbuf, 0, l);

Dalloc(p->notes[i]);
p->notes[i] = Nalloc(l + 1);
memmove(p->notes[i], s, l);
p->notes[i] = Malloc(l + 1);
fastmemmove(p->notes[i], s, l);

P_Data_Save(p);
}


+ 2
- 4
source/p_obituary.c View File

@@ -28,11 +28,9 @@ void Sc_Obituary(void)
Str(ob_slime, s"(slime)");
Str(ob_suicide, s"(suicide)");

struct pronoun {
static struct {
cstr sub, obj, psd, psi, act;
};

static struct pronoun pronoun[pro_max] = {
} const pronoun[pro_max] = {
{"they", "them", "their", "theirs", "they're"},
{"she", "her", "her", "hers", "she's" },
{"he", "him", "his", "his", "he's" },


+ 1
- 1
source/p_save.c View File

@@ -43,7 +43,7 @@ script static void Load_note(struct savefile *save, struct savechunk *chunk) {
if(!len) continue;

Dalloc(save->p->notes[i]);
char *n = save->p->notes[i] = Nalloc(len + 1);
char *n = save->p->notes[i] = Malloc(len + 1);
for(i32 j = 0; j < len; j++) n[j] = fgetc(save->fp) & 0xFF;
}
}


+ 2
- 2
source/p_weapons.c View File

@@ -257,8 +257,8 @@ bool Sc_WeaponPickup(i32 name)
script_str ext("ACS") addr(OBJ "CircleSpread")
k32 Sc_CircleSpread(k32 mdx, k32 mdy, bool getpitch)
{
static k32 A;
static k32 P;
noinit static k32 A;
noinit static k32 P;

if(!getpitch)
{


+ 1
- 1
source/w_monster.c View File

@@ -376,7 +376,7 @@ void Sc_MonsterInfo(void)
}
}

Dbg_Log(log_dmon, "no monster %S", cname);
Dbg_Log(log_dmon, "ERROR no monster %S", cname);

/* If the monster failed all checks, give them this so we don't
need to recheck every tick.


+ 4
- 10
tools/genbuild.rb View File

@@ -150,8 +150,6 @@ build #{INFCHO.join " "}: infc #{INFCIN.join " "} | tools/infc.rb

build $#{IR}/libc.ir: makelib
#{TYPE} = libc
build $#{IR}/libGDCC.ir: makelib
#{TYPE} = libGDCC
_end_

inputs_lithium = []
@@ -166,16 +164,12 @@ for f in SRCS
end

fp << <<_end_
build pk7/acs/lithmain.bin: ld #{inputs_lithium.join " "}
#{LFLAGS} = $#{LFLAGS} -llithlib $#{INITSC} "lithmain@gsinit"
#{STA } = 1400000
#{NUMOUT} = $#{IR}/lithmain_ld.txt
build pk7/acs/lithlib.bin: ld $#{IR}/libc.ir $#{IR}/libGDCC.ir
#{LFLAGS} = $#{LFLAGS} $#{INITSC} "lithlib@gsinit"
build pk7/acs/lithmain.bin: ld #{inputs_lithium.join " "} $#{IR}/libc.ir
#{LFLAGS} = $#{LFLAGS} $#{INITSC} "lithmain@gsinit"
#{STA } = 70000
#{NUMOUT} = $#{IR}/lithlib_ld.txt
#{NUMOUT} = $#{IR}/lithmain_ld.txt

build lithium: phony _dec _snd _text _fs pk7/acs/lithmain.bin pk7/acs/lithlib.bin
build lithium: phony _dec _snd _text _fs pk7/acs/lithmain.bin

default lithium
_end_


Loading…
Cancel
Save