mirror of https://gitlab.com/camelot/kickc.git
- Fixed test cases. Full retest of all test cases.
- Treat global variables of libraries, as part of the .asm library .namespace. - Fix bugs. - Assign meaningful struct names to .asm internal variables and labels. (Remove the $x notation).
This commit is contained in:
parent
e371d304f6
commit
00df07b7bf
|
@ -13,6 +13,8 @@ import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
|||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/** Formatting of numbers, constants, names and more for KickAssembler */
|
||||
public class AsmFormat {
|
||||
|
||||
|
@ -287,11 +289,12 @@ public class AsmFormat {
|
|||
public static String getAsmSymbolName(Program program, Symbol symbol, ScopeRef codeScopeRef) {
|
||||
ScopeRef symbolScopeRef = symbol.getScope().getRef();
|
||||
String asmName = symbol.getLocalName();
|
||||
String asmLibraryLabel = null;
|
||||
String asmLibraryLabel = "";
|
||||
if(symbol instanceof Variable boundVariable) {
|
||||
if (boundVariable.getAsmName() != null) {
|
||||
asmName = boundVariable.getAsmName();
|
||||
asmLibraryLabel = boundVariable.getAsmExportLibraryLabel();
|
||||
if(boundVariable.getAsmExportLibraryLabel() != null)
|
||||
asmLibraryLabel = boundVariable.getAsmExportLibraryLabel() + ".";
|
||||
}
|
||||
}
|
||||
if(!symbolScopeRef.equals(codeScopeRef)) {
|
||||
|
@ -299,11 +302,12 @@ public class AsmFormat {
|
|||
if (codeScopeRef instanceof ProcedureRef procedureRef) {
|
||||
Procedure procedure = program.getScope().getProcedure(procedureRef);
|
||||
String procedureAsmLibraryLabel = procedure.getAsmLibraryLabel();
|
||||
if (asmLibraryLabel != null) {
|
||||
// #820/34 - Handle global variables within libraries correctly.
|
||||
if (!asmLibraryLabel.isEmpty()) {
|
||||
if (procedureAsmLibraryLabel != null && procedureAsmLibraryLabel.equals(asmLibraryLabel)) {
|
||||
return asmFix2(symbolScopeRef.getFullName() + "." + asmName, symbolScopeRef.getFullName());
|
||||
} else {
|
||||
return asmFix2(asmLibraryLabel + "." + symbolScopeRef.getFullName() + "." + asmName, symbolScopeRef.getFullName());
|
||||
return asmFix2(asmLibraryLabel + symbolScopeRef.getFullName() + "." + asmName, symbolScopeRef.getFullName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +336,22 @@ public class AsmFormat {
|
|||
if (namespace != null)
|
||||
asmName = namespace + "." + asmName;
|
||||
}
|
||||
return asmFix2(asmName, codeScopeRef.getLocalName());
|
||||
// #820/34 - Handle global variables within libraries.
|
||||
if(codeScopeRef.equals(ScopeRef.ROOT)) {
|
||||
String asmLibraryName = program.getScope().getAsmLibraryName();
|
||||
HashMap<String, Symbol> asmLibraryNameSpaceSymbols = program.getAsmLibraryNamespaceSymbols();
|
||||
if(program.isAsmLibraryNamespace()) {
|
||||
asmLibraryNameSpaceSymbols.put(asmName, symbol);
|
||||
}
|
||||
if(asmLibraryName.isEmpty() || asmLibraryNameSpaceSymbols.get(asmName) == null) {
|
||||
return asmFix2(asmName, codeScopeRef.getLocalName());
|
||||
} else {
|
||||
asmLibraryName = asmLibraryName + ".";
|
||||
return asmLibraryName + asmFix2(asmName, codeScopeRef.getLocalName());
|
||||
}
|
||||
} else {
|
||||
return asmFix2(asmName, codeScopeRef.getLocalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ import dk.camelot64.kickc.model.symbols.Procedure;
|
|||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
@ -257,9 +259,15 @@ public class AsmLibrary extends AsmLine {
|
|||
|
||||
private String generateVariableStructForward(Variable variable, Program program) {
|
||||
StringBuilder signature = new StringBuilder();
|
||||
// #820/50 - Handle struct definitions correctly for proper declaration.
|
||||
if(variable.isStruct()) {
|
||||
String structName = variable.getType().toCDecl();
|
||||
signature.append(structName).append(";\n");
|
||||
SymbolType symbolType = variable.getType();
|
||||
if(symbolType instanceof SymbolTypeStruct typeStruct) {
|
||||
if(typeStruct.getTypeDefName() == null) {
|
||||
String structName = variable.getType().toCDecl();
|
||||
signature.append(structName).append(";\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return signature.toString();
|
||||
|
||||
|
@ -313,7 +321,11 @@ public class AsmLibrary extends AsmLine {
|
|||
}
|
||||
}
|
||||
}
|
||||
headers.append(generateVariableHeader(globalVariable, program));
|
||||
// TODO: #820/50 - Declaration of global variables only when they are exported using asm_export pragma.
|
||||
// This requires rework. It is a challenge to generate only those global var
|
||||
// By default at this moment, all global variables in libraries are encapsulated in the asm namespace.
|
||||
// This prevents any conflict of global variables.
|
||||
// headers.append(generateVariableHeader(globalVariable, program));
|
||||
structs.append(generateVariableStructForward(globalVariable, program));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package dk.camelot64.kickc.asm;
|
||||
|
||||
/** The end of a namespace scope (for an .asm library and other assembler level encapsulation purposes) */
|
||||
/** #820/1 - The end of a namespace scope (for an .asm library and other assembler level encapsulation purposes) */
|
||||
public class AsmNamespaceEnd extends AsmLine {
|
||||
|
||||
public AsmNamespaceEnd() {
|
||||
|
@ -18,7 +18,7 @@ public class AsmNamespaceEnd extends AsmLine {
|
|||
|
||||
@Override
|
||||
public String getAsm() {
|
||||
return "}";
|
||||
return "} // namespace";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -138,9 +138,24 @@ public class AsmProgram {
|
|||
return asmLabel;
|
||||
}
|
||||
|
||||
public void addNamespaceBegin(String namespace) { addLine(new AsmNamespaceBegin(namespace)); }
|
||||
|
||||
public void addNamespaceEnd() { addLine(new AsmNamespaceEnd()); }
|
||||
/** #820/1 - Handle begin namespace for the .asm library.
|
||||
*
|
||||
* @param program
|
||||
*/
|
||||
public void addNamespaceBegin(Program program) {
|
||||
program.setAsmLibraryNamespace(true);
|
||||
addLine(new AsmNamespaceBegin(program.getAsmLibraryLabel()));
|
||||
}
|
||||
|
||||
/** #820/1 - Handle end namespace for the .asm library.
|
||||
*
|
||||
* @param program
|
||||
*/
|
||||
public void addNamespaceEnd(Program program) {
|
||||
program.setAsmLibraryNamespace(false);
|
||||
addLine(new AsmNamespaceEnd());
|
||||
}
|
||||
|
||||
public void addScopeBegin(String label) {
|
||||
addLine(new AsmScopeBegin(label));
|
||||
|
|
|
@ -120,6 +120,16 @@ public class Program {
|
|||
*/
|
||||
private AsmIdentifier asmLibraryName;
|
||||
|
||||
/** #820/34 - Declare global variables that aren't yet declared.
|
||||
* Specifies whether during ASM generation, a library .namespace is active.
|
||||
*/
|
||||
private boolean asmLibraryNamespace;
|
||||
|
||||
/** #820/34 - Declare global variables that aren't yet declared.
|
||||
* Keeps all the symbols that have been added into the library
|
||||
*/
|
||||
private HashMap<String, Symbol> asmLibraryNamespaceSymbols;
|
||||
|
||||
/**
|
||||
* Defines the asm source to be imported with the defined procedures.
|
||||
*/
|
||||
|
@ -128,7 +138,7 @@ public class Program {
|
|||
/**
|
||||
* Defines the asm source to be exported with the defined procedures.
|
||||
*/
|
||||
private Map<String, AsmExportLibrary> asmExports;
|
||||
private final Map<String, AsmExportLibrary> asmExports;
|
||||
|
||||
|
||||
/** All #pragma code segments. Collected during parsing. These are used by the bank() pragmas to validate if the code segment exists during compilation.*/
|
||||
|
@ -147,6 +157,8 @@ public class Program {
|
|||
this.asmImports = new LinkedHashMap<>();
|
||||
this.asmExports = new LinkedHashMap<>();
|
||||
this.currentPath = new File(".").toPath();
|
||||
this.asmLibraryNamespace = false;
|
||||
this.asmLibraryNamespaceSymbols = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -878,4 +890,21 @@ public class Program {
|
|||
procedure.setDeclaredInline(false);
|
||||
}
|
||||
|
||||
public boolean isAsmLibraryNamespace() {
|
||||
return asmLibraryNamespace;
|
||||
}
|
||||
|
||||
public void setAsmLibraryNamespace(boolean asmLibraryNamespace) {
|
||||
this.asmLibraryNamespace = asmLibraryNamespace;
|
||||
}
|
||||
|
||||
public HashMap<String, Symbol> getAsmLibraryNamespaceSymbols() {
|
||||
return asmLibraryNamespaceSymbols;
|
||||
}
|
||||
|
||||
public void setAsmLibraryNamespaceSymbols(HashMap<String, Symbol> asmLibraryNamespaceSymbols) {
|
||||
this.asmLibraryNamespaceSymbols = asmLibraryNamespaceSymbols;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package dk.camelot64.kickc.model.symbols;
|
||||
|
||||
import dk.camelot64.kickc.asm.AsmIdentifier;
|
||||
import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
|
@ -17,7 +18,9 @@ public abstract class Scope implements Symbol {
|
|||
/** The default data segment. */
|
||||
public static final String SEGMENT_DATA_DEFAULT = "Data";
|
||||
|
||||
private String name;
|
||||
protected String name;
|
||||
|
||||
protected AsmIdentifier asmLibraryIdentifier;
|
||||
private HashMap<String, Symbol> symbols;
|
||||
private int intermediateVarCount = 0;
|
||||
private int intermediateLabelCount = 1;
|
||||
|
@ -28,6 +31,7 @@ public abstract class Scope implements Symbol {
|
|||
|
||||
public Scope(String name, Scope parentScope, String segmentData) {
|
||||
this.name = name;
|
||||
this.asmLibraryIdentifier = new AsmIdentifier("");
|
||||
this.parentScope = parentScope;
|
||||
this.symbols = new LinkedHashMap<>();
|
||||
this.segmentData = Objects.requireNonNull(segmentData);
|
||||
|
@ -47,7 +51,7 @@ public abstract class Scope implements Symbol {
|
|||
return this.getScope().getContainingProcedure();
|
||||
}
|
||||
|
||||
private void setFullName() {
|
||||
protected void setFullName() {
|
||||
String scopeName = (parentScope == null) ? "" : parentScope.getFullName();
|
||||
fullName = (scopeName.length() > 0) ? scopeName + "::" + name : name;
|
||||
}
|
||||
|
@ -185,6 +189,13 @@ public abstract class Scope implements Symbol {
|
|||
return symbols.get(name);
|
||||
}
|
||||
|
||||
public Symbol replaceLocalSymbol(String oldName, String newName) {
|
||||
Symbol symbolValue = symbols.get(oldName);
|
||||
symbols.put(newName, symbolValue);
|
||||
symbols.remove(oldName);
|
||||
return symbolValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for a symbol by it's (short) name. Looks through this scope first and then through any parent scope.
|
||||
*
|
||||
|
@ -343,6 +354,15 @@ public abstract class Scope implements Symbol {
|
|||
return (StructDefinition) symbol;
|
||||
}
|
||||
|
||||
public StructDefinition replaceLocalStructDefinition(String oldName, String newName) {
|
||||
final Symbol oldSymbol = getLocalSymbol(oldName);
|
||||
if(oldSymbol != null && !(oldSymbol instanceof StructDefinition))
|
||||
throw new InternalError("Symbol is not a struct definition! " + oldSymbol.toString());
|
||||
return (StructDefinition) replaceLocalSymbol(oldName, newName);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public EnumDefinition getLocalEnumDefinition(String name) {
|
||||
final Symbol symbol = getLocalSymbol(name);
|
||||
if(symbol != null && !(symbol instanceof EnumDefinition))
|
||||
|
@ -454,4 +474,14 @@ public abstract class Scope implements Symbol {
|
|||
return result;
|
||||
}
|
||||
|
||||
public String getAsmLibraryName() {
|
||||
if(asmLibraryIdentifier != null)
|
||||
return asmLibraryIdentifier.getAsm();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAsmLibraryName(String asmLibraryName) {
|
||||
this.asmLibraryIdentifier.setIdentifier(asmLibraryName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,19 +7,37 @@ import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
|||
/**
|
||||
* A struct definition containing a set of variables.
|
||||
* The struct definition can either represent a struct (member memory-layout is linearly consecutive ) or a union (member start at the same memory address)
|
||||
* #820/50 - Link the typedef to the structure definition, if any.
|
||||
*/
|
||||
public class StructDefinition extends Scope {
|
||||
|
||||
private boolean isUnion;
|
||||
|
||||
private SymbolTypeStruct typeDefStruct;
|
||||
|
||||
public StructDefinition(String name, boolean isUnion, Scope parentScope) {
|
||||
super(name, parentScope, SEGMENT_DATA_DEFAULT);
|
||||
this.isUnion = isUnion;
|
||||
this.typeDefStruct = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SymbolType getType() {
|
||||
return new SymbolTypeStruct(this, false, false);
|
||||
if(typeDefStruct == null) {
|
||||
return new SymbolTypeStruct(this, false, false);
|
||||
} else {
|
||||
return typeDefStruct;
|
||||
}
|
||||
}
|
||||
|
||||
public void setName(String typedefName) {setFullName();}
|
||||
|
||||
public SymbolTypeStruct getTypeDefStruct() {
|
||||
return typeDefStruct;
|
||||
}
|
||||
|
||||
public void setTypeDefStruct(SymbolTypeStruct typeDefStruct) {
|
||||
this.typeDefStruct = typeDefStruct;
|
||||
}
|
||||
|
||||
public boolean isUnion() {
|
||||
|
|
|
@ -101,6 +101,13 @@ public interface SymbolType {
|
|||
return null;
|
||||
}
|
||||
|
||||
/** #820/50 - Get the type definition of the type, if any */
|
||||
default String getTypeDefName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
default void setTypeDefName(String typeDefName) {}
|
||||
|
||||
/**
|
||||
* Get the size of the type (in bytes).
|
||||
*
|
||||
|
|
|
@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.types;
|
|||
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
|
@ -10,7 +11,10 @@ import dk.camelot64.kickc.model.values.ConstantValue;
|
|||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
/** A struct/union */
|
||||
/**
|
||||
* A struct/union
|
||||
* #820/50 - Handle typedefs linkage.
|
||||
*/
|
||||
public class SymbolTypeStruct implements SymbolType {
|
||||
|
||||
/** Name of the struct/union type. */
|
||||
|
@ -27,12 +31,15 @@ public class SymbolTypeStruct implements SymbolType {
|
|||
/** Const type qualifier. */
|
||||
private final boolean isNomodify;
|
||||
|
||||
private String typeDefName;
|
||||
|
||||
public SymbolTypeStruct(String structName, boolean isUnion, int sizeBytes, boolean isVolatile, boolean isNomodify) {
|
||||
this.structName = structName;
|
||||
this.isUnion = isUnion;
|
||||
this.sizeBytes = sizeBytes;
|
||||
this.isVolatile = isVolatile;
|
||||
this.isNomodify = isNomodify;
|
||||
this.typeDefName = null;
|
||||
}
|
||||
|
||||
public SymbolTypeStruct(StructDefinition structDefinition, boolean isVolatile, boolean isNomodify) {
|
||||
|
@ -41,14 +48,34 @@ public class SymbolTypeStruct implements SymbolType {
|
|||
this.sizeBytes = calculateSizeBytes(structDefinition, null);
|
||||
this.isVolatile = isVolatile;
|
||||
this.isNomodify = isNomodify;
|
||||
this.typeDefName = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SymbolType getQualified(boolean isVolatile, boolean isNomodify) {
|
||||
return new SymbolTypeStruct(this.structName, isUnion, this.sizeBytes, isVolatile, isNomodify);
|
||||
SymbolTypeStruct typeStruct = new SymbolTypeStruct(this.structName, isUnion, this.sizeBytes, isVolatile, isNomodify);
|
||||
typeStruct.typeDefName = this.typeDefName;
|
||||
return typeStruct;
|
||||
}
|
||||
|
||||
public boolean isUnion() {
|
||||
public String getTypeDefName() {
|
||||
return this.typeDefName;
|
||||
}
|
||||
|
||||
public void setTypeDefName(String typeDefName) {
|
||||
this.typeDefName = typeDefName;
|
||||
}
|
||||
|
||||
|
||||
public String getStructName() {
|
||||
if(typeDefName != null) {
|
||||
return typeDefName;
|
||||
} else {
|
||||
return structName;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUnion() {
|
||||
return isUnion;
|
||||
}
|
||||
|
||||
|
@ -146,12 +173,16 @@ public class SymbolTypeStruct implements SymbolType {
|
|||
cdecl.append("volatile ");
|
||||
if(isNomodify())
|
||||
cdecl.append("const ");
|
||||
if(isUnion) {
|
||||
cdecl.append("union ");
|
||||
} else {
|
||||
cdecl.append("struct ");
|
||||
if(getTypeDefName() == null) {
|
||||
if (isUnion) {
|
||||
cdecl.append("union ");
|
||||
} else {
|
||||
cdecl.append("struct ");
|
||||
}
|
||||
cdecl.append(this.getStructName());
|
||||
} else {
|
||||
cdecl.append(this.getStructName());
|
||||
}
|
||||
cdecl.append(this.getStructTypeName());
|
||||
if(parentCDecl.length()>0)
|
||||
cdecl.append(" ");
|
||||
cdecl.append(parentCDecl);
|
||||
|
@ -161,9 +192,9 @@ public class SymbolTypeStruct implements SymbolType {
|
|||
@Override
|
||||
public String getConstantFriendlyName() {
|
||||
if(isUnion) {
|
||||
return "UNION_"+structName.toUpperCase(Locale.ENGLISH);
|
||||
return "UNION_"+getStructName().toUpperCase(Locale.ENGLISH);
|
||||
} else {
|
||||
return "STRUCT_"+structName.toUpperCase(Locale.ENGLISH);
|
||||
return "STRUCT_"+getStructName().toUpperCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -375,6 +375,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||
if(!program.hasAsmImportLibrary(asmLibraryName)) {
|
||||
program.setAsmLibraryName(asmLibraryName);
|
||||
program.addAsmExportLibrary(asmLibraryName, exportAll);
|
||||
// The scope of the program needs to have a reference to the name of the .asm library.
|
||||
// For use in AsmFormat!
|
||||
program.getScope().setAsmLibraryName(asmLibraryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +390,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||
Procedure.CallingConvention callingConvention = currentCallingConvention;
|
||||
List<String> procedures = pragmaParamAsmExportProcedures(ctx.pragmaParam());
|
||||
AsmExportLibrary asmExportLibrary = program.addAsmExportLibrary(asmExportLibraryName, false);
|
||||
program.addAsmExportProcedures(asmExportLibrary, callingConvention, procedures);
|
||||
program.addAsmExportProcedures(asmExportLibrary, currentCallingConvention, procedures);
|
||||
// TODO: #820/2 - Ensure that an export can be done with a calling convention tagged.
|
||||
// Versus the current currentCallingConvention implementation.
|
||||
//program.addAsmExportProcedures(asmExportLibrary, Procedure.CallingConvention.VAR_CALL, procedures);
|
||||
}
|
||||
}
|
||||
case CParser.PRAGMA_ASM_IMPORT -> { // Defines that an asm routine or capability library is imported into the program.
|
||||
|
@ -2559,6 +2565,32 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||
String typedefName = varDecl.getVarName();
|
||||
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
|
||||
varBuilder.build();
|
||||
if(typedefName != null) {
|
||||
// #820/50 - Define the name of structures, based on the typedef name, if any.
|
||||
// For structures, the generation of CDecl has a hidden and conceptual problem ...
|
||||
// Structures with an empty name get the structure name $n allocated by the compiler.
|
||||
// And this name can vary depending on the structure declaration order etc.
|
||||
// Also, the structure name struct $0 etc is not C syntax compatible.
|
||||
// So, in order to avoid conflicts, we use the typedef name if given.
|
||||
// We could also have given the struct name the typedef name appended with _s,
|
||||
// but that idea seemed to be way too complicated to implement.
|
||||
// Because the generated struct definition name $n gets assigned during parsing
|
||||
// before the typedef name is parsed.
|
||||
// It is complicated to replace the structure definition name once it is defined and allocated.
|
||||
// So the idea is that the typedef name gets stored as part of the structure type definition,
|
||||
// and used in CDecl when needed.
|
||||
if(varDecl.declType instanceof SymbolTypeStruct) {
|
||||
ProgramScope programScope = program.getScope();
|
||||
StructDefinition structDef = ((SymbolTypeStruct) varDecl.declType).getStructDefinition(programScope);
|
||||
if(structDef.getLocalName().startsWith("$")) {
|
||||
varDecl.declType.setTypeDefName(typedefName);
|
||||
//StructDefinition structDefinition = ((SymbolTypeStruct) varDecl.declType).replaceStructDefinition(programScope, typedefName);
|
||||
StructDefinition structDefinition = ((SymbolTypeStruct) varDecl.declType).getStructDefinition(programScope);
|
||||
structDefinition.setTypeDefStruct((SymbolTypeStruct) varDecl.declType);
|
||||
//((SymbolTypeStruct) varDecl.declType).setStructName(typedefName);
|
||||
}
|
||||
}
|
||||
}
|
||||
scopeStack.pop();
|
||||
varDecl.exitType();
|
||||
return null;
|
||||
|
|
|
@ -102,6 +102,8 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
|
|||
final long stringLength = constantString.getStringLength();
|
||||
final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD);
|
||||
Variable strConst = Variable.createConstant(name, new SymbolTypePointer(SymbolType.BYTE, new ArraySpec(arraySize), false, false), blockScope, constantString, blockScope.getSegmentData());
|
||||
// #820 - Set the library for string constant pointers.
|
||||
strConst.setAsmExportLibrary(getProgram().getAsmLibraryName());
|
||||
blockScope.add(strConst);
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");
|
||||
|
|
|
@ -47,8 +47,12 @@ public class Pass1StructTypeSizeFix extends Pass2SsaOptimization {
|
|||
|
||||
// Update all SIZEOF_XXX constants
|
||||
for(Scope subScope : getProgramScope().getAllScopes(false)) {
|
||||
if(subScope instanceof StructDefinition) {
|
||||
SymbolTypeStruct typeStruct = new SymbolTypeStruct((StructDefinition) subScope, false, false);
|
||||
// #820/50 - Ensure that the structure definitions within the scope are used.
|
||||
if(subScope instanceof StructDefinition structDef) {
|
||||
SymbolTypeStruct typeStruct = structDef.getTypeDefStruct();
|
||||
if(typeStruct == null) {
|
||||
typeStruct = new SymbolTypeStruct((StructDefinition) subScope, false, false);
|
||||
}
|
||||
StructDefinition structDefinition = typeStruct.getStructDefinition(getProgramScope());
|
||||
int sizeBytes = typeStruct.calculateSizeBytes(structDefinition, getProgramScope());
|
||||
if(sizeBytes != typeStruct.getSizeBytes()) {
|
||||
|
|
|
@ -103,9 +103,9 @@ public class Pass4CodeGeneration {
|
|||
String asmLibraryName = program.getAsmLibraryName();
|
||||
ScopeRef currentScope = ScopeRef.ROOT;
|
||||
|
||||
asm.startChunk(currentScope, null, null);
|
||||
|
||||
// 820/25 - #import .asm libraries only once!
|
||||
asm.startChunk(currentScope, null, null);
|
||||
asm.addImportOnce();
|
||||
|
||||
// Add file level comments
|
||||
|
@ -115,7 +115,7 @@ public class Pass4CodeGeneration {
|
|||
// #820/24 - Create a namespace if the output of the compile is an .asm library instead of a program.
|
||||
if (program.getAsmLibraryName() != null) {
|
||||
asm.startChunk(currentScope, null, "Library");
|
||||
asm.addNamespaceBegin(program.getAsmLibraryLabel());
|
||||
asm.addNamespaceBegin(program);
|
||||
}
|
||||
|
||||
asm.startChunk(currentScope, null, "Upstart");
|
||||
|
@ -238,26 +238,22 @@ public class Pass4CodeGeneration {
|
|||
generateScopeEnding(asm, currentScope);
|
||||
}
|
||||
|
||||
currentScope = ScopeRef.ROOT;
|
||||
asm.startChunk(currentScope, null, "File Data Internal or Ignore");
|
||||
|
||||
addData(asm, ScopeRef.ROOT, null);
|
||||
addAbsoluteAddressData(asm, ScopeRef.ROOT, null);
|
||||
|
||||
// #820/24 - Close the namespace of the asm library.
|
||||
if (program.getAsmLibraryName() != null) {
|
||||
asm.addNamespaceEnd();
|
||||
}
|
||||
|
||||
// #820/34 - Export the global data, but when the compilation is an .asm export library.
|
||||
if (program.getAsmLibraryName() != null) {
|
||||
asm.startChunk(currentScope, null, "Exported Global Data");
|
||||
if (program.getAsmLibraryName() == null) {
|
||||
asm.startChunk(ScopeRef.ROOT, null, "File Data Internal or Ignore");
|
||||
addData(asm, ScopeRef.ROOT, null);
|
||||
addAbsoluteAddressData(asm, ScopeRef.ROOT, null);
|
||||
} else {
|
||||
// #820/34 - Export the global data, but when the compilation is an .asm export library.
|
||||
asm.startChunk(ScopeRef.ROOT, null, "Exported Global Data");
|
||||
// Add the global data elements for the ROOT scope of the .asm library.
|
||||
addData(asm, ScopeRef.ROOT, program.getAsmLibraryName());
|
||||
addAbsoluteAddressData(asm, ScopeRef.ROOT, program.getAsmLibraryName());
|
||||
// #820/24 - Close the namespace of the asm library.
|
||||
asm.addNamespaceEnd(program);
|
||||
}
|
||||
|
||||
generateImportAsmLibraries(asm, program); // #820/25 - .asm library #import stub code.
|
||||
// #820/25 - .asm library #import stub code.
|
||||
generateImportAsmLibraries(asm, program);
|
||||
|
||||
program.setAsm(asm);
|
||||
}
|
||||
|
@ -298,7 +294,7 @@ public class Pass4CodeGeneration {
|
|||
if (asm.hasStash()) asm.startChunk(currentScope, null, "Outside Flow");
|
||||
// Generate all stashed ASM lines
|
||||
asm.addStash();
|
||||
addData(asm, currentScope, null);
|
||||
addData(asm, currentScope, program.getAsmLibraryName());
|
||||
asm.addScopeEnd();
|
||||
}
|
||||
}
|
||||
|
@ -405,16 +401,16 @@ public class Pass4CodeGeneration {
|
|||
if(varExportAsmLibrary != null) {
|
||||
return varExportAsmLibrary.equals(exportAsmLibrary);
|
||||
} else {
|
||||
return false;
|
||||
return true; // Bugfix
|
||||
}
|
||||
} else {
|
||||
boolean isImportAsmLibraryGlobal = constantVar.isAsmImportLibraryGlobal();
|
||||
boolean isExportAsmLibraryParameter = constantVar.isAsmExportLibraryParameter();
|
||||
boolean isExportAsmLibraryReturn = constantVar.isAsmExportLibraryReturn();
|
||||
return ( varExportAsmLibrary == null || isExportAsmLibraryParameter || isExportAsmLibraryReturn )
|
||||
&& !isImportAsmLibraryGlobal;
|
||||
}
|
||||
boolean isImportAsmLibraryGlobal = constantVar.isAsmImportLibraryGlobal();
|
||||
boolean isExportAsmLibraryParameter = constantVar.isAsmExportLibraryParameter();
|
||||
boolean isExportAsmLibraryReturn = constantVar.isAsmExportLibraryReturn();
|
||||
return ( varExportAsmLibrary == null || isExportAsmLibraryParameter || isExportAsmLibraryReturn )
|
||||
&& !isImportAsmLibraryGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasData(Variable constantVar) {
|
||||
ConstantValue constantValue = constantVar.getInitValue();
|
||||
|
@ -504,22 +500,22 @@ public class Pass4CodeGeneration {
|
|||
String asmExportLibraryName = program.getAsmLibraryName();
|
||||
|
||||
if(var.isStruct()) {
|
||||
String typeVar = "SIZEOF_" + var.getType().getConstantFriendlyName();
|
||||
// First add all constants without data that can become constants in KickAsm
|
||||
for (Variable constantVar : scopeConstants) {
|
||||
if (!hasData(constantVar)) {
|
||||
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
||||
if (asmName != null && !added.contains(asmName)) {
|
||||
if (constantVar.getLocalName().equals(typeVar)) {
|
||||
// Use constant otherwise
|
||||
added.add(asmName);
|
||||
// Find the constant value calculation
|
||||
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
|
||||
addConstant(asmName, constantVar, asmConstant, asm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// String typeVar = "SIZEOF_" + var.getType().getConstantFriendlyName();
|
||||
// // First add all constants without data that can become constants in KickAsm
|
||||
// for (Variable constantVar : scopeConstants) {
|
||||
// if (!hasData(constantVar)) {
|
||||
// String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
||||
// if (asmName != null && !added.contains(asmName)) {
|
||||
// if (constantVar.getLocalName().equals(typeVar)) {
|
||||
// // Use constant otherwise
|
||||
// added.add(asmName);
|
||||
// // Find the constant value calculation
|
||||
// String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
|
||||
// addConstant(asmName, constantVar, asmConstant, asm);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,6 +542,7 @@ public class Pass4CodeGeneration {
|
|||
if (!useLabelForConst(scopeRef, constantVar)) {
|
||||
// Use constant for constant integers not referenced outside scope
|
||||
added.add(asmName);
|
||||
program.getAsmLibraryNamespaceSymbols().put(asmName, constantVar);
|
||||
// Find the constant value calculation
|
||||
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
|
||||
addConstant(asmName, constantVar, asmConstant, asm);
|
||||
|
@ -553,9 +550,12 @@ public class Pass4CodeGeneration {
|
|||
} else if (!(constantVar.getType() instanceof SymbolTypePointer)) {
|
||||
// Use constant otherwise
|
||||
added.add(asmName);
|
||||
program.getAsmLibraryNamespaceSymbols().put(asmName, constantVar);
|
||||
// Find the constant value calculation
|
||||
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
|
||||
addConstant(asmName, constantVar, asmConstant, asm);
|
||||
// constantVar.setAsmExportLibrary(exportAsmLibrary);
|
||||
addConstantLabelDecl(asmName, constantVar, asmConstant, asm);
|
||||
// addConstant(asmName, constantVar, asmConstant, asm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -569,6 +569,7 @@ public class Pass4CodeGeneration {
|
|||
if (constantVar.getType() instanceof SymbolTypePointer) {
|
||||
// Must use a label for pointers
|
||||
added.add(asmName);
|
||||
program.getAsmLibraryNamespaceSymbols().put(asmName, constantVar);
|
||||
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
|
||||
addConstantLabelDecl(asmName, constantVar, asmConstant, asm);
|
||||
} else if (isIntTypeInScope(constantVar)) {
|
||||
|
@ -576,6 +577,7 @@ public class Pass4CodeGeneration {
|
|||
if (useLabelForConst(scopeRef, constantVar)) {
|
||||
// Use label for integers referenced in other scope - to allow cross-scope referencing
|
||||
added.add(asmName);
|
||||
program.getAsmLibraryNamespaceSymbols().put(asmName, constantVar);
|
||||
// Add any comments
|
||||
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
|
||||
addConstantLabelDecl(asmName, constantVar, asmConstant, asm);
|
||||
|
@ -595,12 +597,14 @@ public class Pass4CodeGeneration {
|
|||
String asmName = scopeVar.getAsmName();
|
||||
if (asmName != null && !added.contains(asmName)) {
|
||||
added.add(asmName);
|
||||
program.getAsmLibraryNamespaceSymbols().put(asmName, scopeVar);
|
||||
addConstantLabelDecl(asmName, scopeVar, AsmFormat.getAsmNumber(registerZp.getZp()), asm);
|
||||
}
|
||||
} else if (Registers.RegisterType.MAIN_MEM.equals(register.getType()) && ((Registers.RegisterMainMem) register).getAddress() != null) {
|
||||
String asmName = scopeVar.getAsmName();
|
||||
if (asmName != null && !added.contains(asmName)) {
|
||||
added.add(asmName);
|
||||
program.getAsmLibraryNamespaceSymbols().put(asmName, scopeVar);
|
||||
// Add the label declaration
|
||||
Long address = ((Registers.RegisterMainMem) register).getAddress();
|
||||
addConstantLabelDecl(asmName, scopeVar, AsmFormat.getAsmNumber(address), asm);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#define __STDIO_FILECOUNT 4
|
||||
#endif
|
||||
|
||||
typedef struct file_handle_s {
|
||||
typedef struct {
|
||||
char filename[__STDIO_FILECOUNT*__STDIO_FILELEN];
|
||||
char channel[__STDIO_FILECOUNT];
|
||||
char device[__STDIO_FILECOUNT];
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#define CONIO_TEXTCOLOR_DEFAULT WHITE // The default text color
|
||||
#define CONIO_BACKCOLOR_DEFAULT BLUE // The default back color
|
||||
|
||||
typedef struct __cx16_conio_s {
|
||||
typedef struct {
|
||||
unsigned char cursor_x; ///< current cursor x-position
|
||||
unsigned char cursor_y; ///< current cursor y-position
|
||||
unsigned char layer;
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/* Testing an export library flight_lib.asm file generation.
|
||||
|
||||
The result of this compile should result in:
|
||||
- A new flight_lib.asm file created in the compiler output directory.
|
||||
- A new flight_lib_asm.h file created in the compiler output directory.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
// Register the compilation as an calc.asm export library output artefact.
|
||||
// There is no main() function!
|
||||
#pragma asm_library
|
||||
|
||||
// Register the exported procedures that should be included in the calc.asm export library.
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(flight_init)
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(flight_route, flight_distance)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
struct flight {
|
||||
char flightno;
|
||||
char direction;
|
||||
char distance;
|
||||
unsigned int x, y;
|
||||
};
|
||||
|
||||
struct flight flights[8];
|
||||
|
||||
void flight_init(char flightno) {
|
||||
flights[flightno].x = 0x8000;
|
||||
flights[flightno].y = 0x8000;
|
||||
}
|
||||
|
||||
void flight_route(char flightno, char direction) {
|
||||
flights[flightno].direction = direction;
|
||||
}
|
||||
|
||||
void flight_distance(char flightno, unsigned int distance) {
|
||||
flights[flightno].distance = distance;
|
||||
}
|
||||
|
||||
void flight_display() {
|
||||
|
||||
}
|
||||
|
||||
void flight_calculate() {
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
/* Here we use the flight_lib.asm library functions.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
// We include the flight_lib_asm.h generated C function prototype file.
|
||||
// This file contains the C function prototypes for import and usage.
|
||||
#include "flight_lib_asm.h"
|
||||
|
||||
void main() {
|
||||
flight_init(2);
|
||||
flight_route(2, 10);
|
||||
flight_distance(2, 0X2000);
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* Testing an export library flight_lib.asm file generation.
|
||||
|
||||
The result of this compile should result in:
|
||||
- A new flight_lib.asm file created in the compiler output directory.
|
||||
- A new flight_lib_asm.h file created in the compiler output directory.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
// Register the compilation as an calc.asm export library output artefact.
|
||||
// There is no main() function!
|
||||
#pragma asm_library
|
||||
|
||||
#pragma calling(__phicall)
|
||||
|
||||
struct flight {
|
||||
char flightno;
|
||||
char direction;
|
||||
char distance;
|
||||
unsigned int x, y;
|
||||
};
|
||||
|
||||
struct flight flights[8];
|
||||
|
||||
// Now with __asm_export directive!
|
||||
void __stackcall __asm_export flight_init(char flightno) {
|
||||
flights[flightno].x = 0x8000;
|
||||
flights[flightno].y = 0x8000;
|
||||
}
|
||||
|
||||
// Now with __asm_export directive!
|
||||
void __varcall __asm_export flight_route(char flightno, char direction) {
|
||||
flights[flightno].direction = direction;
|
||||
}
|
||||
|
||||
// Now with __asm_export directive!
|
||||
void __varcall __asm_export flight_distance(char flightno, unsigned int distance) {
|
||||
flights[flightno].distance = distance;
|
||||
}
|
||||
|
||||
void flight_display() {
|
||||
|
||||
}
|
||||
|
||||
void flight_calculate() {
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
/* Here we use the flight_lib.asm library functions.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
// We include the flight_lib_asm.h generated C function prototype file.
|
||||
// This file contains the C function prototypes for import and usage.
|
||||
#include "flight_lib_asm.h"
|
||||
|
||||
void main() {
|
||||
flight_init(2);
|
||||
flight_route(2, 10);
|
||||
flight_distance(2, 0X2000);
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* Testing an export library flight_lib.asm file generation.
|
||||
|
||||
The result of this compile should result in:
|
||||
- A new flight_lib.asm file created in the compiler output directory.
|
||||
- A new flight_lib_asm.h file created in the compiler output directory.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
// Register the compilation as an calc.asm export library output artefact.
|
||||
// There is no main() function!
|
||||
#pragma asm_library
|
||||
|
||||
#pragma calling(__phicall)
|
||||
#pragma asm_export(flight_init, flight_route, flight_distance)
|
||||
|
||||
struct flight {
|
||||
char flightno;
|
||||
char direction;
|
||||
char distance;
|
||||
unsigned int x, y;
|
||||
};
|
||||
|
||||
struct flight flights[8];
|
||||
|
||||
// Now with __asm_export directive!
|
||||
void __stackcall flight_init(char flightno) {
|
||||
flights[flightno].x = 0x8000;
|
||||
flights[flightno].y = 0x8000;
|
||||
}
|
||||
|
||||
// Now with __asm_export directive!
|
||||
void __varcall flight_route(char flightno, char direction) {
|
||||
flights[flightno].direction = direction;
|
||||
}
|
||||
|
||||
// Now with __asm_export directive!
|
||||
void __varcall flight_distance(char flightno, unsigned int distance) {
|
||||
flights[flightno].distance = distance;
|
||||
}
|
||||
|
||||
void flight_display() {
|
||||
|
||||
}
|
||||
|
||||
void flight_calculate() {
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
/* Here we use the flight_lib.asm library functions.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
// We include the flight_lib_asm.h generated C function prototype file.
|
||||
// This file contains the C function prototypes for import and usage.
|
||||
#include "flight_lib_asm.h"
|
||||
|
||||
void main() {
|
||||
flight_init(2);
|
||||
flight_route(2, 10);
|
||||
flight_distance(2, 0X2000);
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
/* Generate a library for printing. */
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(mem)
|
||||
#pragma struct_model(classic) // This is important or kickc messes up the parameters ...
|
||||
|
@ -23,7 +25,7 @@
|
|||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(cputc)
|
||||
|
||||
#pragma calling(__varcall)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
#include <conio.h>
|
||||
#include <printf.h>
|
|
@ -1,6 +1,5 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma struct_model(classic) // This is important or kickc messes up the parameters ...
|
||||
#pragma zp_reserve($0..$1f)
|
||||
|
||||
#include "printf_lib_asm.h"
|
||||
|
||||
|
@ -24,4 +23,4 @@ void main() {
|
|||
printf("signed char = %hhi to %hhi\n", (signed char)-((1<<7)), (signed char)((1<<7)-1));
|
||||
printf("pointer address = %p to %p\n", (char*)0, (char*)0xFFFF);
|
||||
printf("hexadecimal char = %03x\n", char_test);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Generate a calculation library that can add and subtract 2 chars.
|
||||
- Both plus and min are exported functions within the .asm library.
|
||||
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
|
||||
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus, min)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
char plus(char a, char b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
char min(char a, char b) {
|
||||
return a-b;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* Use the calculation library.
|
||||
Compile first calc_lib.c.
|
||||
Validate the .asm library calc_lib.asm.
|
||||
Validate the main program using the functions of calc_lib.asm.
|
||||
Notice the function calls into the calc_lib .namespace of calc_lib.asm.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "calc_lib_asm.h"
|
||||
|
||||
__export char r;
|
||||
|
||||
void main() {
|
||||
r = 10;
|
||||
r = plus(5,4);
|
||||
r = min(5,4);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus, min)
|
||||
|
||||
char plus(char a, char b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
char min(char a, char b) {
|
||||
return a-b;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "calc_asm.h"
|
||||
|
||||
__export char r; // Ensure that r does not get deleted by the optimizer by exporting it.
|
||||
|
||||
void main() {
|
||||
r = 10;
|
||||
r = plus(5,4);
|
||||
r = min(5,4);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(local_zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
|
||||
#pragma var_model(zp)
|
||||
|
||||
__export const char CONST1 = 20;
|
||||
__export const char CONST2 = 40;
|
||||
__export const char CONST3 = 60;
|
||||
|
||||
__export volatile char global1a;
|
||||
__export volatile int global2a;
|
||||
__export volatile long global3a;
|
||||
__export volatile char* global4a;
|
||||
__export volatile int* global5a;
|
||||
__export volatile long global6a;
|
||||
|
||||
__export volatile char global1b[256];
|
||||
__export volatile int global2b[256];
|
||||
__export volatile long global3b[256];
|
||||
|
||||
__export volatile char global1c[3] = {1,2,3};
|
||||
__export volatile char global2c[3] = {CONST1, CONST2, CONST3};
|
||||
|
||||
__export volatile char global1d[3] = {&global1a, &global2a, &global3a};
|
||||
__export volatile char global2d[3] = {(char*)0x4000, (char*)0x5000, (char*)0x6000};
|
||||
//__export char* global3d[3] = {"test1", "test2", "test3"};
|
|
@ -1,16 +1,11 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
struct printf_buffer_number;
|
||||
#include <calc_asm.h>
|
||||
|
||||
#include <global_lib_asm.h>
|
||||
|
||||
__export char r = 5; // Ensure that r does not get deleted by the optimizer by exporting it.
|
||||
|
||||
void main() {
|
||||
asm {sei}
|
||||
clrscr();
|
||||
r = 10;
|
||||
r = plus(r, 2);
|
||||
r = plus(r, 4);
|
||||
asm {cli}
|
||||
r = global1d[1];
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "struct_lib_types.h"
|
||||
|
||||
#include <struct_lib_asm.h>
|
||||
#include <print_lib_asm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void main() {
|
||||
|
||||
clrscr();
|
||||
|
||||
struct data data1 = {1,2,3};
|
||||
struct data data2 = {10,20,30};
|
||||
|
||||
printf("x = %u\n", get_f1(&data1));
|
||||
printf("y = %u\n", get_f2(&data2));
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(local_zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(get_f1, get_f2)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
#include "struct_lib_types.h"
|
||||
|
||||
char get_f1(struct data* d) {
|
||||
|
||||
return d->f1;
|
||||
}
|
||||
|
||||
char get_f2(struct data* d) {
|
||||
|
||||
return d->f2;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#include "struct_lib_types.h"
|
||||
|
||||
char get_f1(struct data* d);
|
||||
char get_f2(struct data* d);
|
|
@ -0,0 +1,5 @@
|
|||
struct data {
|
||||
char f1;
|
||||
char f2;
|
||||
char f3;
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "typedef_lib_types.h"
|
||||
|
||||
#include <typedef_lib_asm.h>
|
||||
#include <print_lib_asm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void main() {
|
||||
|
||||
clrscr();
|
||||
|
||||
fdata_t data1 = {1,2,3};
|
||||
fdata_t data2 = {10,20,30};
|
||||
|
||||
printf("f1, data1 = %u\n", get_f1(&data1));
|
||||
printf("f2, data2 = %u\n", get_f2(&data2));
|
||||
printf("f1, data2 = %u\n", get_f1(&data2));
|
||||
printf("f2, data1 = %u\n", get_f2(&data1));
|
||||
// TODO ...
|
||||
// printf("f1, data2 = %u\n", get_f1(&data));
|
||||
// printf("f2, data1 = %u\n", get_f2(&data));
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(local_zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "typedef_lib_types.h"
|
||||
|
||||
__export fdata_t data = {'a','b','c'};
|
||||
|
||||
char get_f1(fdata_t* f) {
|
||||
|
||||
return f->f1;
|
||||
}
|
||||
|
||||
char get_f2(fdata_t* f) {
|
||||
|
||||
return f->f2;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#include "typedef_lib_types.h"
|
||||
|
||||
char get_f1(fdata_t* f);
|
||||
char get_f2(fdata_t* f);
|
|
@ -0,0 +1,13 @@
|
|||
typedef struct {
|
||||
char f1;
|
||||
char f2;
|
||||
char f3;
|
||||
} fdata_t;
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned int uint16;
|
||||
typedef signed char sint8;
|
||||
typedef signed int sint16;
|
||||
typedef unsigned long uint32;
|
||||
typedef signed long sint32;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "typedef_lib_types.h"
|
||||
|
||||
#include <typedef_lib_asm.h>
|
||||
#include <print_lib_asm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void main() {
|
||||
|
||||
clrscr();
|
||||
|
||||
printf("get(1) = %s", get(1));
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(clrscr)
|
||||
#pragma asm_export(gotoxy)
|
||||
#pragma asm_export(wherex, wherey)
|
||||
#pragma asm_export(screensize, screensizex, screensizey, cputln )
|
||||
#pragma asm_export(cputcxy, cputs, cputsxy, textcolor, bgcolor, bordercolor )
|
||||
#pragma asm_export(kbhit, cursor, scroll )
|
||||
#pragma asm_export(screenlayer1, screenlayer2)
|
||||
#pragma asm_export(cpeekc, cpeekcxy)
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(printf_str)
|
||||
#pragma asm_export(printf_uint, printf_sint)
|
||||
#pragma asm_export(printf_ulong, printf_slong)
|
||||
#pragma asm_export(printf_uchar, printf_schar)
|
||||
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(cputc)
|
||||
|
||||
#pragma calling(__phicall)
|
||||
|
||||
#include <conio.h>
|
||||
#include <printf.h>
|
|
@ -0,0 +1,12 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(get)
|
||||
|
||||
#include "typedef_lib.h"
|
||||
|
||||
char* get(char n) {
|
||||
return soa.text[n];
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#include "typedef_lib_types.h"
|
||||
|
||||
__export soa_t soa = {
|
||||
{ "test", "test2" }
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
typedef struct {
|
||||
char *text[2];
|
||||
} soa_t;
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Generate a calculation library that:
|
||||
|
||||
- Add and subtract 2 chars, using the functions plus and min.
|
||||
These functions are exported and are called through zero-page.
|
||||
The compiler automatically compiles exported functions using the __varcall
|
||||
calling convention.
|
||||
|
||||
- Multiply a char by 2, through the multiply function.
|
||||
The multiply function is internally to the library, and therefore,
|
||||
will be optimized following the current calling convention.
|
||||
Internal functions following the __phicall calling convention,
|
||||
when compiled with uplift, the parameters to this function will be
|
||||
uplifted to A, X or Y registers, including local variables etc.
|
||||
|
||||
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus, min)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
// Compiled using __varcall calling convention.
|
||||
char plus(char a, char b) {
|
||||
char d = multiply(a);
|
||||
return a + b + d;
|
||||
}
|
||||
|
||||
// Compiled using __varcall calling convention.
|
||||
char min(char a, char b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
// Compiled using __phicall calling convention.
|
||||
char multiply(char d) {
|
||||
return d * 2;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "calc_asm.h"
|
||||
#include "calc_lib_asm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <printf.h>
|
|
@ -1,22 +0,0 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
|
||||
#pragma var_model(local_mem)
|
||||
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus, min)
|
||||
|
||||
char internal(char d) {
|
||||
return d * 2;
|
||||
}
|
||||
|
||||
char plus(char a, char b) {
|
||||
char d = internal(a);
|
||||
return a + b + d;
|
||||
}
|
||||
|
||||
char min(char a, char b) {
|
||||
return a - b;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Generate a calculation library that:
|
||||
|
||||
- Defines an exported library function plus_min to do some calculation.
|
||||
This function parameters are allocated on zero-page, following the __varcall
|
||||
calling convention.
|
||||
|
||||
- Define two internal functions plus and min.
|
||||
These functions are internally to the library, and therefore,
|
||||
will be optimized following the current calling convention.
|
||||
Internal functions following the __phicall calling convention,
|
||||
when compiled with uplift, the parameters to this function will be
|
||||
uplifted to A, X or Y registers, including local variables etc.
|
||||
|
||||
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
|
||||
*/
|
||||
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus_min)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
// Compiled using __varcall calling convention.
|
||||
char plus_min(char a, char p, char m) {
|
||||
char pr = plus(a,p);
|
||||
char mr = min(pr,m);
|
||||
return mr;
|
||||
}
|
||||
|
||||
// Compiled using __phicall calling convention.
|
||||
char plus(char a, char b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
// Compiled using __phicall calling convention.
|
||||
char min(char a, char b) {
|
||||
return a-b;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "calc_asm.h"
|
||||
#include "calc_lib_asm.h"
|
||||
|
||||
__export char r;
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma asm_export(plus_min)
|
||||
|
||||
char plus(char a, char b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
char min(char a, char b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
char plus_min(char a, char p, char m) {
|
||||
char pr = plus(a,p);
|
||||
char mr = min(pr,m);
|
||||
return mr;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Generate a calculation library that is implemented through main memory allocation:
|
||||
|
||||
- Defines an exported library function plus_min to do some calculation.
|
||||
This function parameters are allocated on main memory, following the __varcall
|
||||
calling convention.
|
||||
|
||||
- Define two internal functions plus and min.
|
||||
These functions are internally to the library, and therefore,
|
||||
will be optimized following the current calling convention.
|
||||
Internal functions following the __phicall calling convention,
|
||||
when compiled with uplift, the parameters to this function will be
|
||||
uplifted to A, X or Y registers, including local variables etc.
|
||||
|
||||
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(mem)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus_min)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
char plus(char a, char b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
char min(char a, char b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
char plus_min(char a, char p, char m) {
|
||||
char pr = plus(a,p);
|
||||
char mr = min(pr,m);
|
||||
return mr;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "calc_asm.h"
|
||||
#include "calc_lib_asm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <printf.h>
|
|
@ -1,21 +0,0 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(mem)
|
||||
|
||||
#pragma asm_library
|
||||
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus_min)
|
||||
|
||||
char plus(char a, char b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
char min(char a, char b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
char plus_min(char a, char p, char m) {
|
||||
char pr = plus(a,p);
|
||||
char mr = min(pr,m);
|
||||
return mr;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Generate a calculation library that is implemented through zero-page allocation:
|
||||
|
||||
- No function is exported using #pragma asm_export, so ALL functions are
|
||||
exported in the library!
|
||||
|
||||
- The 3 exported functions do some calculations.
|
||||
The function parameters are allocated on zero-page, following the __varcall
|
||||
calling convention.
|
||||
|
||||
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
|
||||
*/
|
||||
|
||||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus1, plus2, plus3)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
|
||||
char plus1(char d) {
|
||||
d = d + 1;
|
||||
return d;
|
||||
}
|
||||
|
||||
char plus2(char d) {
|
||||
d = d + 2;
|
||||
return plus1(d);
|
||||
}
|
||||
|
||||
char plus3(char d) {
|
||||
d = d + 3;
|
||||
return plus2(d);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
|
||||
char plus1(char d) {
|
||||
d = d + 1;
|
||||
return d;
|
||||
}
|
||||
|
||||
char plus2(char d) {
|
||||
d = d + 2;
|
||||
return plus1(d);
|
||||
}
|
||||
|
||||
char plus3(char d) {
|
||||
d = d + 3;
|
||||
return plus2(d);
|
||||
}
|
||||
|
||||
// char plus4(char d) {
|
||||
// return d+4;
|
||||
// }
|
||||
|
||||
// char plus5(char d) {
|
||||
// return d+5;
|
||||
// }
|
|
@ -2,9 +2,9 @@
|
|||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(plus, min, check)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
char plus(char a, char b) {
|
||||
return a+b;
|
|
@ -1,7 +1,7 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include "calc_asm.h"
|
||||
#include "calc_lib_asm.h"
|
||||
|
||||
__export char r; // Ensure that r does not get deleted by the optimizer by exporting it.
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include <plus_asm.h>
|
||||
#include <min_asm.h>
|
||||
#include <print_asm.h>
|
||||
#include <plus_lib_asm.h>
|
||||
#include <min_lib_asm.h>
|
||||
#include <print_lib_asm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
__export char r; // Ensure that r does not get deleted by the optimizer by exporting it.
|
||||
char r = 3;
|
||||
|
||||
void main() {
|
||||
r = plus(r, 2);
|
||||
r = min(r, 1);
|
||||
|
||||
clrscr();
|
||||
printf("r = %u", r);
|
||||
}
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
|
||||
#pragma var_model(zp)
|
||||
#pragma asm_export(get_x)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
struct data {
|
||||
char x1;
|
|
@ -3,20 +3,16 @@
|
|||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(get_y)
|
||||
#pragma calling(__phicall)
|
||||
|
||||
#pragma var_model(zp)
|
||||
|
||||
struct data {
|
||||
typedef struct {
|
||||
char y1;
|
||||
char y2;
|
||||
char y3;
|
||||
};
|
||||
} data_t;
|
||||
|
||||
struct data y = {128,129,130};
|
||||
|
||||
|
||||
|
||||
// The plus functions
|
||||
data_t y = {128,129,130};
|
||||
|
||||
char get_y(char i) {
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include <cx_asm.h>
|
||||
#include <cy_asm.h>
|
||||
#include <print_asm.h>
|
||||
#include <cx_lib_asm.h>
|
||||
#include <cy_lib_asm.h>
|
||||
#include <print_lib_asm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -14,5 +14,5 @@ void main() {
|
|||
clrscr();
|
||||
|
||||
printf("x = %u\n", get_x(1));
|
||||
printf("y = %u\n", get_y(1));
|
||||
printf("y = %u\n", get_y(2));
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#pragma asm_library
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(clrscr)
|
||||
#pragma asm_export(gotoxy)
|
||||
#pragma asm_export(wherex, wherey)
|
||||
#pragma asm_export(screensize, screensizex, screensizey, cputln )
|
||||
#pragma asm_export(cputcxy, cputs, cputsxy, textcolor, bgcolor, bordercolor )
|
||||
#pragma asm_export(kbhit, cursor, scroll )
|
||||
#pragma asm_export(screenlayer1, screenlayer2)
|
||||
#pragma asm_export(cpeekc, cpeekcxy)
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(printf_str)
|
||||
#pragma asm_export(printf_uint, printf_sint)
|
||||
#pragma asm_export(printf_ulong, printf_slong)
|
||||
#pragma asm_export(printf_uchar, printf_schar)
|
||||
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(cputc)
|
||||
|
||||
#pragma calling(__phicall)
|
||||
|
||||
#include <conio.h>
|
||||
#include <printf.h>
|
|
@ -1,10 +1,10 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include <print_asm.h>
|
||||
#include <print_lib_asm.h>
|
||||
|
||||
#include <plus_asm.h>
|
||||
#include <min_asm.h>
|
||||
#include <plus_lib_asm.h>
|
||||
#include <min_lib_asm.h>
|
||||
|
||||
#include <printf.h>
|
||||
|
||||
|
@ -14,7 +14,10 @@ void main() {
|
|||
clrscr();
|
||||
r = 10;
|
||||
r = plus(r, 2);
|
||||
r = min(r, 1);
|
||||
r = plus(r, 30);
|
||||
r = plus(r, 11);
|
||||
r = plus(r, min(r, 40));
|
||||
|
||||
printf("main r = %u\n", r);
|
||||
r = min(r, 1);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include <print_asm.h>
|
||||
#include <print_lib_asm.h>
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
|
@ -1,7 +1,7 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
|
||||
#include <print_asm.h>
|
||||
#include <print_lib_asm.h>
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
|
@ -1,37 +1,29 @@
|
|||
#pragma encoding(screencode_mixed)
|
||||
#pragma var_model(zp)
|
||||
#pragma struct_model(classic)
|
||||
|
||||
#pragma asm_library
|
||||
#pragma calling(__varcall)
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(cputc)
|
||||
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(clrscr)
|
||||
#pragma asm_export(gotoxy)
|
||||
#pragma asm_export(wherex, wherey)
|
||||
#pragma asm_export(screensize, screensizex, screensizey, cputln)
|
||||
#pragma asm_export(cputcxy, cputs, cputsxy, textcolor, bgcolor, bordercolor)
|
||||
#pragma asm_export(kbhit, cursor, scroll, cscroll)
|
||||
#pragma asm_export(screensize, screensizex, screensizey, cputln )
|
||||
#pragma asm_export(cputcxy, cputs, cputsxy, textcolor, bgcolor, bordercolor )
|
||||
#pragma asm_export(kbhit, cursor, scroll )
|
||||
#pragma asm_export(screenlayer1, screenlayer2)
|
||||
#pragma asm_export(cpeekc, cpeekcxy)
|
||||
#pragma asm_export(plus)
|
||||
|
||||
#pragma calling(__varcall)
|
||||
#pragma asm_export(printf_str)
|
||||
#pragma asm_export(printf_uint, printf_sint)
|
||||
#pragma asm_export(printf_ulong, printf_slong)
|
||||
#pragma asm_export(printf_uchar, printf_schar)
|
||||
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma asm_export(cputc)
|
||||
|
||||
#pragma calling(__phicall)
|
||||
|
||||
#include <conio.h>
|
||||
#include <stdlib.h>
|
||||
#include <printf.h>
|
||||
|
||||
|
||||
__export char color = 10;
|
||||
|
||||
char plus(char a, char p) {
|
||||
char r = a + p;
|
||||
color = r;
|
||||
printf("color = %02u\n", r);
|
||||
return r;
|
||||
}
|
||||
|
Loading…
Reference in New Issue