mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-06-03 07:29:37 +00:00
- Now compiling the eight queens example with conio asm library.
- Added proper return value handling for __varcall functions. - Added many fixes concerning start functions. - Optimized asm library examples. - Added a return value asm library example.
This commit is contained in:
parent
4012887479
commit
07cb0ba6fa
|
@ -641,6 +641,9 @@ public class Program {
|
|||
this.asmImports = asmImports;
|
||||
}
|
||||
|
||||
/**
|
||||
* 820/20 - Add a new library in the asm import list.
|
||||
*/
|
||||
public AsmLibrary addAsmImportLibrary(String asmImportLibraryName) {
|
||||
Path asmImportResource = Paths.get(asmImportLibraryName + ".asm").toAbsolutePath();
|
||||
AsmLibrary asmLibrary = new AsmLibrary(asmImportLibraryName, asmImportResource);
|
||||
|
@ -649,6 +652,9 @@ public class Program {
|
|||
return asmLibrary;
|
||||
}
|
||||
|
||||
/**
|
||||
* 820/20 - Add the procedure to a library.
|
||||
*/
|
||||
public void addAsmImportProcedures(AsmLibrary asmImportLibrary, Procedure.CallingConvention callingConvention, List<String> procedures) {
|
||||
|
||||
for(String procedureName : procedures) {
|
||||
|
@ -656,7 +662,24 @@ public class Program {
|
|||
}
|
||||
}
|
||||
|
||||
public AsmLibrary isProcedureInAsmImport(String procedureName) {
|
||||
/**
|
||||
* 820/20 - Check if the procedure is in the asm import list.
|
||||
*/
|
||||
public boolean isProcedureAsmImport(String procedureName) {
|
||||
Map<String, AsmLibrary> asmImports = this.getAsmImports();
|
||||
for (String asmImportKey : asmImports.keySet()) {
|
||||
AsmLibrary library = asmImports.get(asmImportKey);
|
||||
if (library.hasProcedure(procedureName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 820/20 - Get the asm import library of the procedure.
|
||||
*/
|
||||
public AsmLibrary getProcedureAsmImportLibrary(String procedureName) {
|
||||
Map<String, AsmLibrary> asmImports = this.getAsmImports();
|
||||
for (String asmImportKey : asmImports.keySet()) {
|
||||
AsmLibrary library = asmImports.get(asmImportKey);
|
||||
|
@ -664,7 +687,7 @@ public class Program {
|
|||
return library;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setProcedureAsAsmImport(Procedure procedure, AsmLibrary asmImport) {
|
||||
|
|
|
@ -221,6 +221,11 @@ public class Procedure extends Scope {
|
|||
return procedureType.getReturnType();
|
||||
}
|
||||
|
||||
// 820/11 - Check if the variable is a return variable of the procedure.
|
||||
public boolean isReturn(Variable returnvar) {
|
||||
return findVariable(returnvar.getLocalName()) != null && returnvar.isVariable() && returnvar.getLocalName().contains("return");
|
||||
}
|
||||
|
||||
public List<Variable> getParameters() {
|
||||
ArrayList<Variable> parameters = new ArrayList<>();
|
||||
for(String name : parameterNames) {
|
||||
|
|
|
@ -226,9 +226,13 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||
throw new CompileError("main() has wrong number of parameters. It must have zero or 2 parameters.", mainProc.getDefinitionSource());
|
||||
}
|
||||
|
||||
// For each imported library, call the __start procedure of the library.
|
||||
// 820/17 - For each imported library, call the start procedure of the library.
|
||||
for(AsmLibrary importedLibrary: program.getAsmImports().values()) {
|
||||
startSequence.addStatement( new StatementCall(null, "__" + importedLibrary.getFullName() + "_start", new ArrayList<>(), StatementSource.NONE, Comment.NO_COMMENTS));
|
||||
String procedureStartName = "__" + importedLibrary.getFullName() + "_start";
|
||||
Procedure procedureStart = this.program.getScope().getProcedure(new ProcedureRef(procedureStartName));
|
||||
if(procedureStart != null) {
|
||||
startSequence.addStatement(new StatementCall(null, procedureStartName, new ArrayList<>(), StatementSource.NONE, Comment.NO_COMMENTS));
|
||||
}
|
||||
}
|
||||
|
||||
final Label startReturnLabel = startProcedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
|
||||
|
@ -543,7 +547,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||
|
||||
String procedureName = varDecl.getVarName();
|
||||
Procedure procDeclared = (Procedure)program.getScope().getSymbol(new SymbolRef(procedureName));
|
||||
AsmLibrary asmImport = this.program.isProcedureInAsmImport(procedureName);
|
||||
AsmLibrary asmImport = this.program.getProcedureAsmImportLibrary(procedureName);
|
||||
|
||||
// We skip the procedure definition if:
|
||||
// - it is already defined in an asm library.
|
||||
|
@ -620,7 +624,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||
|
||||
procedure = (Procedure) existingSymbol;
|
||||
} else {
|
||||
AsmLibrary asmImport = this.program.isProcedureInAsmImport(procedure.getFullName());
|
||||
AsmLibrary asmImport = this.program.getProcedureAsmImportLibrary(procedure.getFullName());
|
||||
if(asmImport != null)
|
||||
this.program.setProcedureAsAsmImport(procedure, asmImport);
|
||||
program.getScope().add(procedure);
|
||||
|
|
|
@ -61,6 +61,8 @@ public class Pass1CallVar extends Pass2SsaOptimization {
|
|||
final LValue lValue = call.getlValue();
|
||||
if(lValue!=null) {
|
||||
Variable returnVar = procedure.getLocalVariable("return");
|
||||
// 820/11 - Procedure return value of an asm library.
|
||||
returnVar.setAsmLibrary(procedure.getAsmLibrary()); // This is key to bind the variable during assembler generation!
|
||||
generateCallFinalize(lValue, returnVar, source, comments, stmtIt, statement);
|
||||
}
|
||||
stmtIt.remove();
|
||||
|
@ -85,6 +87,7 @@ public class Pass1CallVar extends Pass2SsaOptimization {
|
|||
for(int i = 0; i < parameterDefs.size(); i++) {
|
||||
final RValue parameterVal = call.getParameters().get(i);
|
||||
final Variable parameterDef = parameterDefs.get(i);
|
||||
// 820/10 - Procedure parameters in an asm library.
|
||||
parameterDef.setAsmLibrary(procedure.getAsmLibrary());
|
||||
stmtIt.add(new StatementAssignment(parameterDef.getVariableRef(), parameterVal, false, source, comments));
|
||||
comments = Comment.NO_COMMENTS;
|
||||
|
|
|
@ -88,7 +88,7 @@ public class Pass4CodeGeneration {
|
|||
asm.startChunk(currentScope, null, "File Comments");
|
||||
generateComments(asm, program.getMainFileComments());
|
||||
|
||||
// Create a namespace if the output of the compile is an .asm library instead of a program.
|
||||
// 820/24 - Create a namespace if the output of the compile is an .asm library instead of a program.
|
||||
if (program.getAsmLibrary() != null) {
|
||||
asm.startChunk(currentScope, null, "Library");
|
||||
asm.addNamespaceBegin(program.getAsmLibrary());
|
||||
|
@ -190,17 +190,24 @@ public class Pass4CodeGeneration {
|
|||
}
|
||||
}
|
||||
}
|
||||
generateScopeEnding(asm, currentScope);
|
||||
// 820/24 - Scope ending of the normal assembler and/or asm library export generation.
|
||||
if (oldProcedure != null && !oldProcedure.isDeclaredExtern()) {
|
||||
// The current block is in a different scope. End the old scope.
|
||||
generateScopeEnding(asm, currentScope);
|
||||
}
|
||||
|
||||
currentScope = ScopeRef.ROOT;
|
||||
asm.startChunk(currentScope, null, "File Data");
|
||||
addData(asm, ScopeRef.ROOT);
|
||||
addAbsoluteAddressData(asm, ScopeRef.ROOT);
|
||||
|
||||
// 820/24 - Close the namespace of the asm library.
|
||||
if (program.getAsmLibrary() != null) {
|
||||
asm.addNamespaceEnd();
|
||||
}
|
||||
|
||||
// In case of an asm library import, we generate the instructions to import the library.
|
||||
// 820/25 - Import asm libraries.
|
||||
// TODO: Solve the need for the #define __asm_import__, to solve the .segmentdef conflict.
|
||||
for(String asmLibraryName : program.getAsmImports().keySet()) {
|
||||
asm.addComment("Asm library " + asmLibraryName + ":", false);
|
||||
|
@ -912,7 +919,7 @@ public class Pass4CodeGeneration {
|
|||
}
|
||||
final Bank.CallingDistance callingDistance = Bank.CallingDistance.forCall(fromProcedure.getBank(), toProcedure.getBank());
|
||||
if(Bank.CallingDistance.NEAR.equals(callingDistance)) {
|
||||
asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false);
|
||||
asm.addInstruction("jsr", CpuAddressingMode.ABS, toProcedure.getCallFullName(), false);
|
||||
} else {
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.callBanked(toProcedure, callingDistance, program), program);
|
||||
}
|
||||
|
|
|
@ -59,16 +59,24 @@ public class Pass4LiveRangeEquivalenceClassesFinalize extends Pass2Base {
|
|||
EquivalenceClassAdder equivalenceClassAdder = new EquivalenceClassAdder(liveRangeEquivalenceClassSet);
|
||||
equivalenceClassAdder.visitGraph(getGraph());
|
||||
|
||||
// Add any load/store variables with an initializer - and load/store struct variables
|
||||
// TODO: SVEN - this needs to be carefully tested and reworked where necessary.
|
||||
// The purpose here is to allocate variables that are not compiled but in libraries.
|
||||
// And these need to be allocated to equivalence classes in order to coalesce.
|
||||
for(Variable variable : getSymbols().getAllVariables(true)) {
|
||||
if(variable.getScope() instanceof Procedure procedure) {
|
||||
// check if export
|
||||
// 820/10 - __varcall exported zeropages to be allocated in equivalence classes.
|
||||
if(getProgram().isProcedureAsmExport((procedure.getFullName()))) {
|
||||
List<Variable> params = procedure.getParameters();
|
||||
if(params.contains(variable)) {
|
||||
addToEquivalenceClassSet(variable.getVariableRef(), new ArrayList<>(), liveRangeEquivalenceClassSet);
|
||||
}
|
||||
}
|
||||
// 820/11 - __varcall imported return values to be allocated in equivalence classes.
|
||||
if(procedure.isAsmImportLibrary()) {
|
||||
if(procedure.isReturn(variable)) {
|
||||
addToEquivalenceClassSet(variable.getVariableRef(), new ArrayList<>(), liveRangeEquivalenceClassSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ void conio_x16_init() {
|
|||
}
|
||||
|
||||
// Returns a value if a key is pressed.
|
||||
inline unsigned char kbhit(void)
|
||||
unsigned char kbhit(void)
|
||||
{
|
||||
cbm_k_clrchn();
|
||||
return cbm_k_getin();
|
||||
|
|
1556
src/test/kc/examples/eightqueens/conio_var.asm
Normal file
1556
src/test/kc/examples/eightqueens/conio_var.asm
Normal file
File diff suppressed because it is too large
Load Diff
21
src/test/kc/examples/eightqueens/conio_var.h
Normal file
21
src/test/kc/examples/eightqueens/conio_var.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
extern __phicall __asm_import(conio_var) void __conio_var_start();
|
||||
extern __varcall __asm_import(conio_var) void conio_x16_init();
|
||||
extern __varcall __asm_import(conio_var) void clrscr();
|
||||
extern __varcall __asm_import(conio_var) void gotoxy(__zp($b) char x, __zp(2) char y);
|
||||
extern __varcall __asm_import(conio_var) __zp(2) char wherex();
|
||||
extern __varcall __asm_import(conio_var) __zp(2) char wherey();
|
||||
extern __varcall __asm_import(conio_var) void screensize(__zp(6) char *x, __zp($e) char *y);
|
||||
extern __varcall __asm_import(conio_var) __zp(2) char screensizex();
|
||||
extern __varcall __asm_import(conio_var) __zp(2) char screensizey();
|
||||
extern __varcall __asm_import(conio_var) void cputln();
|
||||
extern __stackcall __asm_import(conio_var) void cputc(__zp(8) char c);
|
||||
extern __varcall __asm_import(conio_var) void cputcxy(__zp($b) char x, __zp(2) char y, __zp(4) char c);
|
||||
extern __varcall __asm_import(conio_var) void cputs(__zp($c) const char *s);
|
||||
extern __varcall __asm_import(conio_var) void cputsxy(__zp($b) char x, __zp(2) char y, __zp($e) const char *s);
|
||||
extern __varcall __asm_import(conio_var) __zp(2) char textcolor(__zp($b) char color);
|
||||
extern __varcall __asm_import(conio_var) __zp(2) char bgcolor(__zp($b) char color);
|
||||
extern __varcall __asm_import(conio_var) __zp($b) char bordercolor(__zp(3) char color);
|
||||
extern __varcall __asm_import(conio_var) __zp($b) char kbhit();
|
||||
extern __varcall __asm_import(conio_var) __zp($b) char cursor(__zp(2) char onoff);
|
||||
extern __varcall __asm_import(conio_var) __zp(2) char scroll(__zp(5) char onoff);
|
||||
extern __varcall __asm_import(conio_var) void screenlayer1();
|
|
@ -75,7 +75,7 @@ __conio_var_start: {
|
|||
// __conio_var_start::@1
|
||||
// #pragma constructor_for(conio_x16_init, cputc, clrscr, cscroll)
|
||||
// [4] callexecute conio_x16_init -- call_var_near
|
||||
jsr conio_var.conio_x16_init
|
||||
jsr conio_x16_init
|
||||
// __conio_var_start::@return
|
||||
// [5] return
|
||||
rts
|
||||
|
@ -91,25 +91,25 @@ conio_x16_init: {
|
|||
.label conio_x16_init__7 = 5
|
||||
// screenlayer1()
|
||||
// [7] callexecute screenlayer1 -- call_var_near
|
||||
jsr conio_var.screenlayer1
|
||||
jsr screenlayer1
|
||||
// textcolor(CONIO_TEXTCOLOR_DEFAULT)
|
||||
// [8] textcolor::color = WHITE -- vbuz1=vbuc1
|
||||
lda #WHITE
|
||||
sta.z conio_var.textcolor.color
|
||||
// [9] callexecute textcolor -- call_var_near
|
||||
jsr conio_var.textcolor
|
||||
jsr textcolor
|
||||
// bgcolor(CONIO_BACKCOLOR_DEFAULT)
|
||||
// [10] bgcolor::color = BLUE -- vbuz1=vbuc1
|
||||
lda #BLUE
|
||||
sta.z conio_var.bgcolor.color
|
||||
// [11] callexecute bgcolor -- call_var_near
|
||||
jsr conio_var.bgcolor
|
||||
jsr bgcolor
|
||||
// cursor(0)
|
||||
// [12] cursor::onoff = 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z conio_var.cursor.onoff
|
||||
// [13] callexecute cursor -- call_var_near
|
||||
jsr conio_var.cursor
|
||||
jsr cursor
|
||||
// cbm_k_plot_get()
|
||||
// [14] call cbm_k_plot_get
|
||||
jsr cbm_k_plot_get
|
||||
|
@ -144,7 +144,7 @@ conio_x16_init: {
|
|||
lda __conio+1
|
||||
sta.z conio_var.gotoxy.y
|
||||
// [26] callexecute gotoxy -- call_var_near
|
||||
jsr conio_var.gotoxy
|
||||
jsr gotoxy
|
||||
// __conio.scroll[0] = 1
|
||||
// [27] *((char *)&__conio+$f) = 1 -- _deref_pbuc1=vbuc2
|
||||
lda #1
|
||||
|
@ -346,7 +346,7 @@ cputsxy: {
|
|||
// [61] gotoxy::x = cputsxy::x
|
||||
// [62] gotoxy::y = cputsxy::y
|
||||
// [63] callexecute gotoxy -- call_var_near
|
||||
jsr conio_var.gotoxy
|
||||
jsr gotoxy
|
||||
// cputs(s)
|
||||
// [64] cputs::s = cputsxy::s -- pbuz1=pbuz2
|
||||
lda.z s
|
||||
|
@ -354,7 +354,7 @@ cputsxy: {
|
|||
lda.z s+1
|
||||
sta.z conio_var.cputs.s+1
|
||||
// [65] callexecute cputs -- call_var_near
|
||||
jsr conio_var.cputs
|
||||
jsr cputs
|
||||
// cputsxy::@return
|
||||
// }
|
||||
// [66] return
|
||||
|
@ -392,7 +392,7 @@ cputs: {
|
|||
lda.z c
|
||||
pha
|
||||
// [73] callexecute cputc -- call_stack_near
|
||||
jsr conio_var.cputc
|
||||
jsr cputc
|
||||
// sideeffect stackpullpadding(1) -- _stackpullpadding_1
|
||||
pla
|
||||
jmp __b1
|
||||
|
@ -409,13 +409,13 @@ cputcxy: {
|
|||
// [75] gotoxy::x = cputcxy::x
|
||||
// [76] gotoxy::y = cputcxy::y
|
||||
// [77] callexecute gotoxy -- call_var_near
|
||||
jsr conio_var.gotoxy
|
||||
jsr gotoxy
|
||||
// cputc(c)
|
||||
// [78] stackpush(char) = cputcxy::c -- _stackpushbyte_=vbuz1
|
||||
lda.z c
|
||||
pha
|
||||
// [79] callexecute cputc -- call_stack_near
|
||||
jsr conio_var.cputc
|
||||
jsr cputc
|
||||
// sideeffect stackpullpadding(1) -- _stackpullpadding_1
|
||||
pla
|
||||
// cputcxy::@return
|
||||
|
@ -557,7 +557,7 @@ cputc: {
|
|||
__b6:
|
||||
// cputln()
|
||||
// [108] callexecute cputln -- call_var_near
|
||||
jsr conio_var.cputln
|
||||
jsr cputln
|
||||
jmp __b7
|
||||
// cputc::@5
|
||||
__b5:
|
||||
|
@ -587,14 +587,14 @@ cputc: {
|
|||
__b8:
|
||||
// cputln()
|
||||
// [114] callexecute cputln -- call_var_near
|
||||
jsr conio_var.cputln
|
||||
jsr cputln
|
||||
rts
|
||||
// [115] phi from cputc to cputc::@1 [phi:cputc->cputc::@1]
|
||||
// cputc::@1
|
||||
__b1:
|
||||
// cputln()
|
||||
// [116] callexecute cputln -- call_var_near
|
||||
jsr conio_var.cputln
|
||||
jsr cputln
|
||||
rts
|
||||
}
|
||||
// screensizey
|
||||
|
@ -1243,7 +1243,7 @@ cscroll: {
|
|||
// [218] gotoxy::y = 0 -- vbuz1=vbuc1
|
||||
sta.z conio_var.gotoxy.y
|
||||
// [219] callexecute gotoxy -- call_var_near
|
||||
jsr conio_var.gotoxy
|
||||
jsr gotoxy
|
||||
// cscroll::@return
|
||||
__breturn:
|
||||
// }
|
||||
|
@ -1264,7 +1264,7 @@ cscroll: {
|
|||
lda __conio+7
|
||||
sta.z conio_var.gotoxy.y
|
||||
// [225] callexecute gotoxy -- call_var_near
|
||||
jsr conio_var.gotoxy
|
||||
jsr gotoxy
|
||||
// clearline()
|
||||
// [226] call clearline
|
||||
jsr clearline
|
||||
|
|
71
src/test/kc/library/kbhit-library-1.c
Normal file
71
src/test/kc/library/kbhit-library-1.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
// Tests kbhit function call return value
|
||||
// Print a bunch of different stuff using printf
|
||||
|
||||
// Instead of using conio.c and conio.h, this code imports a
|
||||
// conio (.asm) library, already pre-compiled.
|
||||
// The sequent #include of <conio.h> is ignored, as the functions are declared as external.
|
||||
// In this way, any external library function, even when it is part of the standard C libraries,
|
||||
// is ignored and not compiled when declared as external.
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
|
||||
#include "conio_var.h"
|
||||
|
||||
// Linkage
|
||||
#pragma link("library.ld")
|
||||
|
||||
#include <conio.h>
|
||||
#include <cx16-conio.h>
|
||||
#include <printf.h>
|
||||
|
||||
void main() {
|
||||
|
||||
clrscr();
|
||||
|
||||
char c = 'e';
|
||||
signed char sc = -12;
|
||||
unsigned char uc = 34;
|
||||
signed int si = -1234;
|
||||
unsigned int ui = 5678;
|
||||
signed long sl = -123456;
|
||||
unsigned long ul = 567890;
|
||||
|
||||
gotoxy(10,2);
|
||||
// char
|
||||
printf("A char: %c\n", c);
|
||||
|
||||
gotoxy(10,4);
|
||||
// pointer
|
||||
printf("A pointer: %p\n", &c);
|
||||
|
||||
gotoxy(10,6);
|
||||
// percent sign
|
||||
printf("A percent: %%\n");
|
||||
|
||||
gotoxy(10,8);
|
||||
// signed char
|
||||
printf("A signed char: %hhd\n", sc);
|
||||
|
||||
gotoxy(10,10);
|
||||
// unsigned char
|
||||
printf("An unsigned char: %hhu\n", uc);
|
||||
|
||||
gotoxy(50,2);
|
||||
// signed int
|
||||
printf("A signed int: %d\n", si);
|
||||
|
||||
gotoxy(50,4);
|
||||
// unsigned int
|
||||
printf("An unsigned int: %u\n", ui);
|
||||
|
||||
gotoxy(50,6);
|
||||
// signed long
|
||||
printf("A signed long: %ld\n", sl);
|
||||
|
||||
gotoxy(50,8);
|
||||
// unsigned long
|
||||
printf("An unsigned long: %lu\n", ul);
|
||||
|
||||
}
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
#pragma zp_reserve(0x80..0xFF)
|
||||
|
||||
#pragma code_seg(CodeConIO)
|
||||
#pragma data_seg(DataConIO)
|
||||
|
||||
//#include "conio-test.h"
|
||||
|
||||
#include <conio.h>
|
||||
|
|
6
src/test/kc/library/lib/library.ld
Normal file
6
src/test/kc/library/lib/library.ld
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
#if __asm_import__
|
||||
#else
|
||||
.segmentdef Code [start=%P]
|
||||
.segmentdef Data [startAfter="CodeConIO"]
|
||||
#endif
|
19
src/test/kc/library/lib/library_return.c
Normal file
19
src/test/kc/library/lib/library_return.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
#pragma link("library.ld")
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library("library_return")
|
||||
#pragma asm_export("library_return", __varcall, return_1)
|
||||
#pragma asm_export("library_return", __stackcall, return_2)
|
||||
|
||||
#pragma zp_reserve(0x80..0xFF)
|
||||
|
||||
char return_1(char num) {
|
||||
return num+1;
|
||||
}
|
||||
|
||||
char return_2(char num) {
|
||||
return num+2;
|
||||
}
|
||||
|
57
src/test/kc/library/library_return.asm
Normal file
57
src/test/kc/library/library_return.asm
Normal file
|
@ -0,0 +1,57 @@
|
|||
// File Comments
|
||||
// Library
|
||||
.namespace library_return {
|
||||
// Upstart
|
||||
.cpu _65c02
|
||||
|
||||
#if __asm_import__
|
||||
#else
|
||||
.segmentdef Code [start=$80d]
|
||||
.segmentdef Data [startAfter="CodeConIO"]
|
||||
#endif
|
||||
// Global Constants & labels
|
||||
.const STACK_BASE = $103
|
||||
.segment Code
|
||||
// return_2
|
||||
// __zp(2) char return_2(__zp(2) char num)
|
||||
return_2: {
|
||||
.const OFFSET_STACK_NUM = 0
|
||||
.const OFFSET_STACK_RETURN_0 = 0
|
||||
.label num = 2
|
||||
.label return = 2
|
||||
// [0] return_2::num#0 = stackidx(char,return_2::OFFSET_STACK_NUM) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_NUM,x
|
||||
sta.z num
|
||||
// return num+2;
|
||||
// [1] return_2::return#0 = return_2::num#0 + 2 -- vbuz1=vbuz1_plus_2
|
||||
lda.z return
|
||||
clc
|
||||
adc #2
|
||||
sta.z return
|
||||
// return_2::@return
|
||||
// }
|
||||
// [2] stackidx(char,return_2::OFFSET_STACK_RETURN_0) = return_2::return#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN_0,x
|
||||
// [3] return
|
||||
rts
|
||||
}
|
||||
// return_1
|
||||
// __zp(2) char return_1(__zp(2) char num)
|
||||
return_1: {
|
||||
.label num = 2
|
||||
.label return = 2
|
||||
.label return_1__0 = 2
|
||||
// num+1
|
||||
// [4] return_1::$0 = return_1::num + 1 -- vbuz1=vbuz1_plus_1
|
||||
inc.z return_1__0
|
||||
// return num+1;
|
||||
// [5] return_1::return = return_1::$0
|
||||
// return_1::@return
|
||||
// }
|
||||
// [6] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
}
|
2
src/test/kc/library/library_return.h
Normal file
2
src/test/kc/library/library_return.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
extern __varcall __asm_import(library_return) __zp(2) char return_1(__zp(2) char num);
|
||||
extern __stackcall __asm_import(library_return) __zp(2) char return_2(__zp(2) char num);
|
|
@ -14,7 +14,7 @@
|
|||
#include "conio_var.h"
|
||||
|
||||
// Linkage
|
||||
#pragma link("printf-library.ld")
|
||||
#pragma link("library.ld")
|
||||
|
||||
#include <conio.h>
|
||||
#include <cx16-conio.h>
|
||||
|
|
18
src/test/kc/library/return-library-1.c
Normal file
18
src/test/kc/library/return-library-1.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Tests a return value from a library function.
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
|
||||
#include "library_return.h"
|
||||
|
||||
// Linkage
|
||||
#pragma link("library.ld")
|
||||
|
||||
__export char test = 0;
|
||||
|
||||
void main() {
|
||||
|
||||
test = return_1(10);
|
||||
test = return_2(20);
|
||||
}
|
Loading…
Reference in New Issue
Block a user