mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-27 09:31:18 +00:00
Banking progress
(cherry picked from commit d0abf45529c34e14ed3ce43b9be3a140f78bc4a9)
This commit is contained in:
parent
c550a122da
commit
a52b5dc4a9
@ -925,28 +925,39 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
} else if (statement instanceof StatementCallExecute) {
|
||||
// TODO: This part seems never to be executed! Old code?
|
||||
StatementCallExecute call = (StatementCallExecute) statement;
|
||||
RValue procedureRVal = call.getProcedureRVal();
|
||||
// Generate ASM for a call
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
|
||||
if (!(procedureRVal instanceof ProcedureRef)) {
|
||||
asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL);
|
||||
}
|
||||
// StatementCallExecute call = (StatementCallExecute) statement;
|
||||
// Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
// Procedure procedureFrom = block.getProcedure(this.program); // We obtain from where the procedure is called, to validate the bank equality.
|
||||
// RValue procedureRVal = call.getProcedureRVal();
|
||||
// // Same as PHI
|
||||
// if(procedure.isDeclaredBanked() && procedureFrom.getBank() != procedure.getBank()) {
|
||||
// AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.bankCallPrepare(procedure.getBankArea(), procedure.getBank(), call.getProcedure().getFullName(), program), program);
|
||||
// AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.bankCallExecute(procedure.getBankArea(), procedure.getBank(), call.getProcedure().getFullName(), program), program);
|
||||
// AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.bankCallFinalize(procedure.getBankArea(), procedure.getBank(), call.getProcedure().getFullName(), program), program);
|
||||
// } else {
|
||||
// AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
|
||||
// }
|
||||
// // Generate ASM for a call
|
||||
// AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
|
||||
// if (!(procedureRVal instanceof ProcedureRef)) {
|
||||
// asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL);
|
||||
// }
|
||||
StatementCallExecute call = (StatementCallExecute) statement;
|
||||
ProcedureRef procedureRef = call.getProcedure();
|
||||
if(procedureRef != null) {
|
||||
ProgramScope scope = getScope();
|
||||
Procedure procedure = scope.getProcedure(procedureRef);
|
||||
Procedure procedureFrom = block.getProcedure(this.program); // We obtain from where the procedure is called, to validate the bank equality.
|
||||
RValue procedureRVal = call.getProcedureRVal();
|
||||
// Same as PHI
|
||||
if (procedure.isDeclaredBanked() && procedureFrom.getBank() != procedure.getBank()) {
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.bankCallPrepare(procedure.getBankArea(), procedure.getBank(), call.getProcedure().getFullName(), program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.bankCallExecute(procedure.getBankArea(), procedure.getBank(), call.getProcedure().getFullName(), program), program);
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.bankCallFinalize(procedure.getBankArea(), procedure.getBank(), call.getProcedure().getFullName(), program), program);
|
||||
} else {
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
|
||||
}
|
||||
if (!(procedureRVal instanceof ProcedureRef)) {
|
||||
asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL);
|
||||
}
|
||||
} else {
|
||||
RValue procedureRVal = call.getProcedureRVal();
|
||||
// Generate ASM for a call
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
|
||||
if (!(procedureRVal instanceof ProcedureRef)) {
|
||||
asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL);
|
||||
}
|
||||
}
|
||||
} else if (statement instanceof StatementExprSideEffect) {
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.exprSideEffect((StatementExprSideEffect) statement, program), program);
|
||||
} else if (statement instanceof StatementReturn) {
|
||||
|
55
src/test/kc/examples/cx16/banking/cx16-banking-0.c
Normal file
55
src/test/kc/examples/cx16/banking/cx16-banking-0.c
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file cx16-banking-1.c
|
||||
* @author your name (you@domain.com)
|
||||
* @brief This program demonstrates a simple example of a banked call.
|
||||
* @version 0.1
|
||||
* @date 2023-04-05
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
// The linker specification of the different segments.
|
||||
#pragma link("cx16-banking-1.ld")
|
||||
#pragma var_model(mem)
|
||||
|
||||
#include <cx16.h>
|
||||
#include <conio.h>
|
||||
#include <printf.h>
|
||||
#include <kernal.h>
|
||||
|
||||
#include "cx16-banking-0.h"
|
||||
|
||||
|
||||
// The target computer platform is the Commander X16,
|
||||
// which implements banking in ram between 0xA0000 and 0xBFFF,
|
||||
// and in ram between 0xC000 and 0xFFFF.
|
||||
#pragma target(cx16)
|
||||
|
||||
char* const SCREEN = (char*)0x0400;
|
||||
|
||||
#pragma code_seg(Bank1) // The sequent functions will be addressed specified by segment bank1 in the linker.
|
||||
#pragma bank(ram, 1) // The sequent functions will be banked using call method ram in bank number 1.
|
||||
|
||||
char __stackcall plus(char a, char b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
#pragma code_seg(Code) // The sequent functions will be addressed in the default main memory location (segment Code).
|
||||
#pragma nobank(dummy) // The sequent functions will consider no banking calculations anymore.
|
||||
|
||||
void load_bank(char bank, char *file) {
|
||||
bank_set_bram(bank);
|
||||
cbm_k_setnam(file);
|
||||
cbm_k_setlfs(1,8,2);
|
||||
cbm_k_load((char*)0xA000, 0);
|
||||
cbm_k_close(1);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
|
||||
load_bank(1, "BANK1.BIN");
|
||||
|
||||
SCREEN[0] = plus('0', 7);
|
||||
}
|
||||
|
20
src/test/kc/examples/cx16/banking/cx16-banking-0.h
Normal file
20
src/test/kc/examples/cx16/banking/cx16-banking-0.h
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
// Function declarations
|
||||
// char add_a(char a);
|
||||
// char add_b(char a);
|
||||
// char add_c(char a);
|
||||
// char add_d(char a);
|
||||
// char add_e(char a);
|
||||
// char add_f(char a);
|
||||
|
||||
// char add_m(char a);
|
||||
|
||||
// char mul_a(char m);
|
||||
// char mul_b(char m);
|
||||
// char mul_c(char m);
|
||||
// char mul_d(char m);
|
||||
// char mul_e(char m);
|
||||
// char mul_f(char m);
|
||||
|
||||
// char mul_m(char m);
|
12
src/test/kc/examples/cx16/banking/cx16-banking-0.ld
Normal file
12
src/test/kc/examples/cx16/banking/cx16-banking-0.ld
Normal file
@ -0,0 +1,12 @@
|
||||
.file [name="%O", type="prg", segments="Program"]
|
||||
.file [name="BANK1.BIN", type="bin", segments="Bank1"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
.segmentdef Basic [start=$0801]
|
||||
.segmentdef Code [start=%P]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segmentdef Bank1 [start=$A000, min=$A000, max=$BFFF, align=$100]
|
||||
.segment Basic
|
||||
:BasicUpstart(%E)
|
||||
.segment Code
|
||||
.segment Data
|
||||
|
168
src/test/kc/examples/cx16/banking/cx16-banking-1.c
Normal file
168
src/test/kc/examples/cx16/banking/cx16-banking-1.c
Normal file
@ -0,0 +1,168 @@
|
||||
/**
|
||||
* @file cx16-banking-1.c
|
||||
* @author your name (you@domain.com)
|
||||
* @brief This program demonstrates a simple example of a banked call.
|
||||
* @version 0.1
|
||||
* @date 2023-04-05
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
// The linker specification of the different segments.
|
||||
#pragma link("cx16-banking-1.ld")
|
||||
#pragma var_model(mem)
|
||||
|
||||
#include <cx16.h>
|
||||
#include <conio.h>
|
||||
#include <printf.h>
|
||||
#include <kernal.h>
|
||||
|
||||
#include "cx16-banking-1.h"
|
||||
|
||||
|
||||
// The target computer platform is the Commander X16,
|
||||
// which implements banking in ram between 0xA0000 and 0xBFFF,
|
||||
// and in ram between 0xC000 and 0xFFFF.
|
||||
#pragma target(cx16)
|
||||
|
||||
|
||||
#pragma code_seg(Bank1) // The sequent functions will be addressed specified by segment bank1 in the linker.
|
||||
#pragma bank(ram, 1) // The sequent functions will be banked using call method ram in bank number 1.
|
||||
|
||||
|
||||
// Functional code
|
||||
|
||||
char add_a(char a) {
|
||||
printf("add_a(%02x:%04p), ",bank_get_bram(), (void*)&add_a);
|
||||
return a+1;
|
||||
}
|
||||
|
||||
char add_c(char a) {
|
||||
printf("add_c(%02x:%04p), ",bank_get_bram(),(void*)&add_c);
|
||||
return add_a(a)+1; // Non banked call in ram bank 1.
|
||||
}
|
||||
|
||||
char add_d(char a) {
|
||||
printf("add_d(%02x:%04p), ",bank_get_bram(),(void*)&add_d);
|
||||
return mul_a(a)+1; // Banked call fram ram bank 1 to ram bank 2.
|
||||
}
|
||||
|
||||
char add_e(char a) {
|
||||
printf("add_e(%02x:%04p), ",bank_get_bram(),(void*)&add_e);
|
||||
return mul_b(a)+1; // Banked call fram ram bank 1 to ram bank 2.
|
||||
}
|
||||
|
||||
char add_f(char a) {
|
||||
printf("add_f(%02x:%04p), ",bank_get_bram(),(void*)&add_f);
|
||||
return add_m(a)+1; // Non banked call fram ram bank 1 to main memory.
|
||||
}
|
||||
|
||||
|
||||
#pragma code_seg(Bank2) // The sequent functions will be addressed specified by segment bank2 in the linker.
|
||||
#pragma bank(ram, 2) // The sequent functions will be banked using call method ram in bank number 2.
|
||||
|
||||
char mul_a(char m) {
|
||||
printf("mul_a(%02x:%04p), ",bank_get_bram(),(void*)&mul_a);
|
||||
return m * 2;
|
||||
}
|
||||
|
||||
char mul_c(char m) {
|
||||
printf("mul_c(%02x:%04p), ",bank_get_bram(),(void*)&mul_c);
|
||||
return add_a(m)*2; // Banked call fram ram bank 2 to ram bank 1.
|
||||
}
|
||||
|
||||
char mul_d(char m) {
|
||||
printf("mul_d(%02x:%04p), ",bank_get_bram(),(void*)&mul_d);
|
||||
return mul_a(m)*2; // Non banked call in ram bank 2.
|
||||
}
|
||||
|
||||
char mul_e(char a) {
|
||||
printf("mul_e(%02x:%04p), ",bank_get_bram(),(void*)&mul_e);
|
||||
return mul_b(a)*2; // Non Banked call in ram bank 2.
|
||||
}
|
||||
|
||||
char mul_f(char m) {
|
||||
printf("mul_f(%02x:%04p), ",bank_get_bram(),(void*)&mul_f);
|
||||
return add_m(m)*2; // Non banked call fram ram bank 2 to main memory.
|
||||
}
|
||||
|
||||
|
||||
#pragma code_seg(Code) // The sequent functions will be addressed in the default main memory location (segment Code).
|
||||
#pragma nobank(dummy) // The sequent functions will consider no banking calculations anymore.
|
||||
|
||||
// The __bank directive declares this function to be banked using call method ram in bank number 1 of banked ram.
|
||||
char __bank(ram, 1) add_b(char a) {
|
||||
printf("add_b(%02x:%04p), ",bank_get_bram(),(void*)&add_b);
|
||||
return a+1;
|
||||
}
|
||||
|
||||
// The __bank directive declares this function to be banked using call method ram in bank number 2 of banked ram.
|
||||
char __bank(ram, 2) mul_b(char m) {
|
||||
printf("mul_b(%02x:%04p), ",bank_get_bram(),(void*)&mul_b);
|
||||
return m*2;
|
||||
}
|
||||
|
||||
// Allocated in main memory.
|
||||
char add_m(char a) {
|
||||
printf("add_m(%02x:%04p), ",bank_get_bram(),(void*)&add_m);
|
||||
return add_e(a)+1; // Banked call to ram in bank 1 fram main memory.
|
||||
}
|
||||
|
||||
// Allocated in main memory.
|
||||
char mul_m(char m) {
|
||||
printf("mul_m(%02x:%04p), ",bank_get_bram(),(void*)&mul_m);
|
||||
return mul_e(m)*2; // Banked call to ram in bank 2 fram main memory.
|
||||
}
|
||||
|
||||
|
||||
// Practically this means that the main() function is placed in main memory ...
|
||||
|
||||
void load_bank(char bank, char *file) {
|
||||
bank_set_bram(bank);
|
||||
cbm_k_setnam(file);
|
||||
cbm_k_setlfs(1,8,2);
|
||||
cbm_k_load((char*)0xA000, 0);
|
||||
cbm_k_close(1);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
|
||||
clrscr();
|
||||
cx16_k_screen_set_charset(1,0);
|
||||
|
||||
load_bank(1, "BANK1.BIN");
|
||||
load_bank(2, "BANK2.BIN");
|
||||
|
||||
bank_set_bram(0);
|
||||
|
||||
asm{.byte $db}
|
||||
__export char result = add_a(1);
|
||||
printf("result = %u\n", result); // Banked call to ram in bank 1 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", add_b(1)); // Banked call to ram in bank 1 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", add_c(1)); // Banked call to ram in bank 1 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", add_d(1)); // Banked call to ram in bank 1 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", add_e(1)); // Banked call to ram in bank 1 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", add_f(1)); // Banked call to ram in bank 1 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", mul_a(1)); // Banked call to ram in bank 2 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", mul_b(1)); // Banked call to ram in bank 2 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", mul_c(1)); // Banked call to ram in bank 2 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", mul_d(1)); // Banked call to ram in bank 2 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", mul_e(1)); // banked call to ram in bank 2 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", mul_f(1)); // banked call to ram in bank 2 fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", add_m(1)); // Near call in main memory fram main memory.
|
||||
// asm{.byte $db}
|
||||
// printf("result = %u\n", mul_m(1)); // Near call in main memory fram main memory.
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file cx16-banking-1.c
|
||||
* @author your name (you@domain.com)
|
||||
* @brief This program demonstrates a simple example of a banked call.
|
||||
* @version 0.1
|
||||
* @date 2023-04-05
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
// The linker specification of the different segments.
|
||||
#pragma var_model(mem)
|
||||
|
||||
#include <cx16.h>
|
||||
#include <conio.h>
|
||||
#include <printf.h>
|
||||
#include <kernal.h>
|
||||
|
||||
// The target computer platform is the Commander X16,
|
||||
// which implements banking in ram between 0xA0000 and 0xBFFF,
|
||||
// and in ram between 0xC000 and 0xFFFF.
|
||||
#pragma target(cx16)
|
||||
|
||||
char __stackcall plus(char a, char b) {
|
||||
if (a > 0) {
|
||||
return a + plus(a - b, b);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
|
||||
char result = plus(4, 1);
|
||||
printf("result = %u\n", result);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user