Compare commits

...

5 commits

Author SHA1 Message Date
4bbbf45141 Merge pull request 'sasm-linker' (#1) from sasm-linker into main
Reviewed-on: #1
2024-11-09 23:06:35 +01:00
slederer
fbc72c5438 sasm: show filename when processing INCBIN
libgen: renamed
2024-11-09 23:02:39 +01:00
slederer
91cb059f38 use precompiled standard library (not really a linker) 2024-11-09 22:22:48 +01:00
slederer
5ce5bc44b8 sasm: use filesize() for incbin directive 2024-11-09 19:03:09 +01:00
slederer
ab57b5ce7a sasm: add INCBIN meta directive 2024-11-09 00:54:57 +01:00
10 changed files with 151 additions and 25 deletions

1
.gitignore vendored
View file

@ -4,6 +4,7 @@ lib/stdlib.s
tests/*.s tests/*.s
examples/*.s examples/*.s
!runtime.s !runtime.s
!stdlibwrap.s
*.o *.o
*.exe *.exe
*.bin *.bin

View file

@ -1051,3 +1051,16 @@ FLOAT32_ERR_TRUNC:
.BYTE "integer overflow",0 .BYTE "integer overflow",0
FLOAT32_ERR_DIVZ: FLOAT32_ERR_DIVZ:
.BYTE "float division by zero",0 .BYTE "float division by zero",0
%export _ADDFLOAT32
%export _CMPFLOAT32
%export _CMPINTFLOAT32
%export _DIVFLOAT32
%export _FRACTFLOAT32
%export _GETFLOAT32EXP
%export _INTFLOAT32
%export _INTTOFLOAT32
%export _MULFLOAT32
%export _NEGFLOAT32
%export _SUBFLOAT32
%export _TRUNCFLOAT32

View file

@ -387,7 +387,7 @@ READCHANW_XT:
; --- check if a string is already initialized ; --- check if a string is already initialized
; parameters: addr ; parameters: addr
; returns: 1 if it is initialied, 0 otherwise ; returns: 1 if it is initialized, 0 otherwise
_STRINGISINITED: _STRINGISINITED:
LOADI.S1.X2Y ; load length field, keep addr LOADI.S1.X2Y ; load length field, keep addr
CBRANCH.NZ STRIN_XT1 ; if not zero, it is already inited CBRANCH.NZ STRIN_XT1 ; if not zero, it is already inited
@ -1616,7 +1616,7 @@ MEM_FREE_XT:
; Since the return stack is no longer valid afterwards, directly ; Since the return stack is no longer valid afterwards, directly
; jumps to _MAIN instead of using RET. ; jumps to _MAIN instead of using RET.
; parameters: [ start of heap address ] ; parameters: [ _MAIN entry point, start of heap address ]
_MEM_INIT: _MEM_INIT:
; initialize anchor chunk with start of heap address ; initialize anchor chunk with start of heap address
; and heap size - header size ; and heap size - header size
@ -1663,7 +1663,9 @@ _MEM_INIT:
LOADCP _MEM_FREE ; add chunk to free list LOADCP _MEM_FREE ; add chunk to free list
CALL CALL
LOADCP _MAIN ; get address of _MAIN from program header
LOADCP _MAIN_PTR
LOADI
JUMP JUMP
; allocate a string with MEM_ALLOC. ; allocate a string with MEM_ALLOC.
@ -1937,3 +1939,35 @@ NEWLINESTR:
.BYTE 13,10 .BYTE 13,10
.CPOOL .CPOOL
%export _APPENDSTRING
%export _ARRAYTOSET
%export _BOUNDSCHECK
%export _CHARTOSTRING
%export _CHECK_ALLOC
%export _CLEARBIT
%export _CLEARMEM
%export _CMPSTRING
%export _CMPSTRINGL
%export _CMPWORDS
%export _COPYSTRING
%export _COPYWORDS
%export _ENUMCHECK
%export _INDEXSTRING
%export _INITSTRING
%export _INITSTRINGF
%export _INITSTRINGFROM
%export _ISCHARINSTRING
%export _ISINTINARRAY
%export _MEM_ALLOC
%export _MEM_INIT
%export _MEM_FREE
%export _RANGECHECK
%export _RUNTIME_ERR
%export _SETBIT
%export _SETSTRINGCHAR
%export _SETSTRINGLENGTH
%export _STRINGTOCHAR
%export _STRING_ALLOC
%export _TESTBIT
%export MEM_DUMP

11
lib/stdlibwrap.s Normal file
View file

@ -0,0 +1,11 @@
.ORG 24576 + 32
.EQU _HEAP_SZ_PTR 24576 + 4
.EQU _STACK_SZ_PTR 24576 + 8
.EQU _MAIN_PTR 24576 + 12
%include "coreloader.lsym"
%include "runtime.s"
%include "float32.s"
%include "stdlib.s"
_MAIN:

View file

@ -86,6 +86,12 @@ begin
countIns(1); countIns(1);
end; end;
procedure emitInclude(s:string);
begin
writeln(outfile, '%include "',s,'"');
emitIns('.CPOOL');
end;
procedure emitPrologue; procedure emitPrologue;
begin begin
writeln(outfile, #9, '.ORG ', startAddress); writeln(outfile, #9, '.ORG ', startAddress);
@ -95,12 +101,21 @@ begin
emitIns2Int('.WORD', defaultHeapSize); emitIns2Int('.WORD', defaultHeapSize);
emitLabelRaw('_STACK_SZ_PTR'); emitLabelRaw('_STACK_SZ_PTR');
emitIns2Int('.WORD', defaultStackSize); emitIns2Int('.WORD', defaultStackSize);
emitIns2Int('.WORD', 0); emitLabelRaw('_MAIN_PTR');
emitIns2('.WORD', '_MAIN');
emitIns2('LOADCP','_END'); (* end of program is start of heap *) emitIns2('LOADCP','_END'); (* end of program is start of heap *)
emitIns2('LOADCP', '_MEM_INIT'); (* MEM_INIT initializes heap and sets FP/RP *) emitIns2('LOADCP', '_MEM_INIT'); (* MEM_INIT initializes heap and sets FP/RP *)
(* since RP is not initialized yet, we cannot use CALL (* since RP is not initialized yet, we cannot use CALL
and MEM_INIT jumps to _MAIN after it is done *) and MEM_INIT jumps to _MAIN after it is done *)
emitIns('JUMP'); emitIns('JUMP');
emitIns2('BRANCH','@+2'); (* NOP, to make alignment explicit *)
emitIns('.CPOOL'); (* header/prologue + 2 constants is 32 bytes *)
if useStdlib then
begin
writeln(outfile, '%include "stdlib.lsym"');
writeln(outfile, '%incbin "stdlib.lib"');
end;
end; end;
function bytes2words(size:integer):integer; function bytes2words(size:integer):integer;
@ -274,12 +289,6 @@ begin
end; end;
end; end;
procedure emitInclude(s:string);
begin
writeln(outfile, '%include "',s,'"');
emitIns('.CPOOL');
end;
procedure emitUnitEpilogue; procedure emitUnitEpilogue;
begin begin
emitIns('.CPOOL'); emitIns('.CPOOL');
@ -307,10 +316,6 @@ begin
else else
emitInclude('coreloader.lsym'); emitInclude('coreloader.lsym');
emitInclude('float32.lib');
emitInclude('runtime.lib');
emitInclude('stdlib.lib');
rewindStringList(usedUnits); rewindStringList(usedUnits);
while nextStringListItem(usedUnits, unitName) do while nextStringListItem(usedUnits, unitName) do
emitInclude(unitName + UnitSuffix2); emitInclude(unitName + UnitSuffix2);

View file

@ -9,6 +9,7 @@ var
outfile:TextFile; outfile:TextFile;
infile:TextFile; infile:TextFile;
lineno:integer; lineno:integer;
infilePath,outfilePath:string;
procedure errorExit2(reason:string;arg:string); forward; procedure errorExit2(reason:string;arg:string); forward;
@ -78,6 +79,17 @@ begin
clean := (not strcontains( name, '_')) and (name[1] <> '='); clean := (not strcontains( name, '_')) and (name[1] <> '=');
end; end;
procedure removeLeadingZeroes(var s:string);
begin
while length(s) > 1 do
begin
if s[1] = '0' then
delete(s,1,1)
else
break;
end;
end;
procedure processFile(inpath,outpath:string); procedure processFile(inpath,outpath:string);
var line:string; var line:string;
addr,name:string; addr,name:string;
@ -94,6 +106,8 @@ begin
begin begin
readln(infile, line); readln(infile, line);
splitLine(line, addr, name, clean); splitLine(line, addr, name, clean);
removeLeadingZeroes(addr);
if clean then if clean then
writeln(outfile, #9, '.EQU ', name, ' $', addr); writeln(outfile, #9, '.EQU ', name, ' $', addr);
end; end;
@ -104,7 +118,13 @@ end;
begin begin
if ParamCount > 0 then if ParamCount > 0 then
begin begin
processFile(ParamStr(1), getOutfileName(ParamStr(1))); infilePath := ParamStr(1);
outfilePath := getOutfileName(infilePath);
if ParamCount > 1 then
outfilePath := ParamStr(2);
processFile(infilePath, outfilePath);
end end
else else
writeln('No file name given.'); writeln('No file name given.');

View file

@ -9,9 +9,10 @@ fpc -gl lsymgen.pas
sasm ..\lib\coreloader.s sasm ..\lib\coreloader.s
lsymgen ..\lib\coreloader.sym lsymgen ..\lib\coreloader.sym
py pcomp.py -n ..\lib\stdlib.pas py pcomp.py -n ..\lib\stdlib.pas
libgen ..\lib\stdlib.s sasm ..\lib\stdlibwrap.s ..\lib\stdlib.lib
libgen ..\lib\runtime.s lsymgen ..\lib\stdlibwrap.sym ..\lib\stdlib.lsym
libgen ..\lib\float32.s
rem exit /b
py pcomp.py sasm.pas py pcomp.py sasm.pas
py pcomp.py pcomp.pas py pcomp.py pcomp.pas

View file

@ -372,12 +372,17 @@ procedure printPassNo;
begin begin
write('P', pass, ' '); write('P', pass, ' ');
end; end;
procedure printFilename(var f:string);
procedure printCurrentLineno;
begin begin
write(#13); write(#13);
printPassNo; printPassNo;
write(filename, ' ', lineno); write(f);
end;
procedure printCurrentLineno;
begin
printFilename(filename);
write(' ', lineno);
ClrEol; ClrEol;
end; end;
@ -2041,6 +2046,37 @@ begin
errorExit2('Unrecognized directive', lastToken.tokenText); errorExit2('Unrecognized directive', lastToken.tokenText);
end; end;
procedure readImage(filename:string);
var f:InputFileType;
c:char;
i:integer;
size:integer;
begin
printFilename(filename);
ClrEol;
openFileWithDefault(f, filename);
size := filesize(f);
pc := pc + size;
bytesCount := bytesCount + size;
if pass = 2 then
begin
for i := 1 to size do
begin
read(f,c);
write(outfile,c);
end;
end;
close(f);
printCurrentLineno;
end;
procedure parseMetaDirective; procedure parseMetaDirective;
var filename:string; var filename:string;
sym:TreeDataRef; sym:TreeDataRef;
@ -2071,6 +2107,13 @@ begin
errorExit2('Symbol expected', ''); errorExit2('Symbol expected', '');
readNextToken; readNextToken;
end end
else
if lastToken.tokenText = '%INCBIN' then
begin
filename := curToken.tokenText;
readNextToken;
readImage(filename);
end
else else
errorExit2('Invalid meta directive', lastToken.tokenText); errorExit2('Invalid meta directive', lastToken.tokenText);
end; end;

View file

@ -457,15 +457,13 @@ def create_image_with_stuff():
slotnr = putfile("../lib/coreloader.lsym", "coreloader.lsym", f, part, partstart, slotnr) slotnr = putfile("../lib/coreloader.lsym", "coreloader.lsym", f, part, partstart, slotnr)
slotnr = putfile("../lib/coreloader.prog", "coreloader.prog", f, part, partstart, slotnr) slotnr = putfile("../lib/coreloader.prog", "coreloader.prog", f, part, partstart, slotnr)
slotnr = putfile("../lib/float32.lib", "float32.lib", f, part, partstart, slotnr)
slotnr = putfile("../lib/runtime.lib", "runtime.lib", f, part, partstart, slotnr)
slotnr = putfile("../lib/stdlib.lib", None, f, part, partstart, slotnr) slotnr = putfile("../lib/stdlib.lib", None, f, part, partstart, slotnr)
slotnr = putfile("../lib/stdlib.inc", None, f, part, partstart, slotnr) slotnr = putfile("../lib/stdlib.inc", None, f, part, partstart, slotnr)
slotnr = putfile("../lib/stdlib.lsym", None, f, part, partstart, slotnr)
slotnr = putfile("../pcomp/sasm.prog", None , f, part, partstart, slotnr) slotnr = putfile("../pcomp/sasm.prog", None , f, part, partstart, slotnr)
slotnr = putfile("../pcomp/pcomp.prog", None , f, part, partstart, slotnr) slotnr = putfile("../pcomp/pcomp.prog", None , f, part, partstart, slotnr)
slotnr = putfile("../pcomp/lsymgen.prog", None , f, part, partstart, slotnr) slotnr = putfile("../pcomp/lsymgen.prog", None , f, part, partstart, slotnr)
slotnr = putfile("../pcomp/libgen.prog", None , f, part, partstart, slotnr)
slotnr = putfile("../progs/reclaim.prog", None , f, part, partstart, slotnr) slotnr = putfile("../progs/reclaim.prog", None , f, part, partstart, slotnr)
slotnr = putfile("../progs/dumpdir.prog", None , f, part, partstart, slotnr) slotnr = putfile("../progs/dumpdir.prog", None , f, part, partstart, slotnr)