irq routine activated

This commit is contained in:
Irmen de Jong 2018-12-26 04:51:21 +01:00
parent 904e317781
commit 8adbcb7a26
10 changed files with 77 additions and 213 deletions

View File

@ -44,7 +44,11 @@
}
rotate_vertices(irq.global_time as float / 30.0)
draw_edges()
c64scr.print_ub(X)
c64.CHROUT('\n')
draw_edges() ; @todo doesn't return from the loop...
c64scr.print_ub(X)
c64.CHROUT('\n')
}
}
}
@ -89,7 +93,8 @@
}
; draw all edges of the object
for uword edge in edges {
for uword edge in edges { ; @todo invalid loop code generated? (loop doesn't end?)
ubyte e_from = msb(edge)
ubyte e_to = lsb(edge)

View File

@ -1,43 +0,0 @@
%import c64utils
~ main {
sub start() {
str name = "????????????????????????????????????????"
str input = "??????????"
ubyte secretnumber = rnd() % 100
vm_write_str("Let's play a number guessing game!\n")
vm_write_str("Enter your name: ")
vm_input_str(name)
vm_write_str("\nHello, ")
vm_write_str(name)
vm_write_str(".\nI am thinking of a number from 1 to 100! You'll have to guess it!\n")
for ubyte attempts_left in 10 to 1 step -1 {
vm_write_str("\nYou have ")
vm_write_num(attempts_left)
vm_write_str(" guess")
if attempts_left>1
vm_write_str("es")
vm_write_str(" left. What is your next guess? ")
vm_input_str(input)
ubyte guess = c64utils.str2ubyte(input) ; @todo replace with proper stubs for these functions when executing on stackvm.
if guess==secretnumber {
vm_write_str("\nYou guessed it, impressive!\n")
vm_write_str("Thanks for playing.\n")
return
} else {
vm_write_str("That is too ")
if guess<secretnumber
vm_write_str("low!\n")
else
vm_write_str("high!\n")
}
}
vm_write_str("\nToo bad! My number was: ")
vm_write_num(secretnumber)
vm_write_str(".\n")
return
}
}

View File

@ -1,5 +1,6 @@
%import c64utils
;%option enable_floats
%option enable_floats
~ main {
@ -7,84 +8,41 @@
;c64scr.PLOT(screenx(x), screeny(y)) ; @todo fix argument calculation of parameters ???!!!
const uword width = 320
const uword height = 200
sub screenx(float x) -> word {
;return ((x/4.1* (width as float)) + 160.0) as word ;width // 2 ; @todo fix calculation
float wf = width
return (x/4.1* wf + wf / 2.0) as word
}
sub start() {
c64scr.print(" X=")
c64scr.print_ub(X)
c64.CHROUT('\n')
word w = c64utils.str2word("000")
c64scr.print_w(w)
c64.CHROUT('\n')
w = c64utils.str2word("1")
c64scr.print_w(w)
c64.CHROUT('\n')
w = c64utils.str2word("-15000")
c64scr.print_w(w)
c64.CHROUT('\n')
w = c64utils.str2word("15000")
c64scr.print_w(w)
c64.CHROUT('\n')
c64.CHROUT('\n')
uword uw = c64utils.str2uword("0")
c64scr.print_uw(uw)
c64.CHROUT('\n')
uw = c64utils.str2uword("1")
c64scr.print_uw(uw)
c64.CHROUT('\n')
uw = c64utils.str2uword("15000")
c64scr.print_uw(uw)
c64.CHROUT('\n')
uw = c64utils.str2uword("65522")
c64scr.print_uw(uw)
c64.CHROUT('\n')
c64.CHROUT('\n')
byte b = c64utils.str2byte("0")
c64scr.print_b(b)
c64.CHROUT('\n')
b=c64utils.str2byte("10")
c64scr.print_b(b)
c64.CHROUT('\n')
b=c64utils.str2byte("-10")
c64scr.print_b(b)
c64.CHROUT('\n')
b=c64utils.str2byte("-128")
c64scr.print_b(b)
c64.CHROUT('\n')
b=c64utils.str2byte("127")
c64scr.print_b(b)
c64.CHROUT('\n')
c64.CHROUT('\n')
ubyte ub = c64utils.str2ubyte("0")
c64scr.print_ub(ub)
c64.CHROUT('\n')
ub=c64utils.str2ubyte("10")
c64scr.print_ub(ub)
c64.CHROUT('\n')
ub=c64utils.str2ubyte("10")
c64scr.print_ub(ub)
c64.CHROUT('\n')
ub=c64utils.str2ubyte("128")
c64scr.print_ub(ub)
c64.CHROUT('\n')
ub=c64utils.str2ubyte("255")
c64scr.print_ub(ub)
c64.CHROUT('\n')
c64.CHROUT('\n')
c64scr.print(" X=")
c64scr.print_ub(X)
c64.CHROUT('\n')
}
}
~ irq {
sub irq() {
memory ubyte[256] screenarray = $0400
memory ubyte firstscreenchar = $0400
screenarray[0]++ ; @todo incorrect code generated?
firstscreenchar++ ; ... this is okay
c64.EXTCOL++
}
}

View File

@ -1,95 +0,0 @@
%import c64utils
%option enable_floats
~ main {
sub start() {
ubyte ub1
ubyte ub2
byte b1 = -99
byte b2
uword uw1
uword uw2
word w1 = -9999
word w2
float f1
float f2
float f3
ubyte[3] uba = [1,2,3]
byte[3] ba = [-1,0,3]
uword[3] uwa = [1000,200,0]
ubyte[3] uba0 = 0
byte[3] ba0 = 0
uword[3] uwa0 = 0
word[3] wa0 = -222
word[3] wa1 = [-1000.w,2000.w,3000.w]
word[3] wa2 = [1000,2000,3000]
float[3] fa0 = 0.0
float[3] fa1 = [-1000,44.555, 99.999]
float[3] fa2 = [-1000,44.555, 0]
str string = "hello"
str_p pstring = "hello1"
str_s sstring = "hello12"
str_ps psstring = "hello123"
c64.CHROUT('x')
c64scr.print_ub(X)
c64.CHROUT('\n')
; @todo implement max and min, AND FIX STACKPTR (X) ERRORS!
ub1 = max(uba)
c64scr.print_ub(ub1)
c64.CHROUT('\n')
b1 = max(ba)
c64scr.print_b(b1)
c64.CHROUT('\n')
uw1 = max(uwa)
c64scr.print_uw(uw1)
c64.CHROUT('\n')
w1 = max(wa0)
c64scr.print_w(w1)
c64.CHROUT('\n')
w1 = max(wa1)
c64scr.print_w(w1)
c64.CHROUT('\n')
w1 = max(wa2)
c64scr.print_w(w1)
c64.CHROUT('\n')
f1 = max(fa1)
c64flt.print_f(f1)
c64.CHROUT('\n')
c64.CHROUT('x')
c64scr.print_ub(X)
c64.CHROUT('\n')
ub1 = min(uba)
c64scr.print_ub(ub1)
c64.CHROUT('\n')
b1 = min(ba)
c64scr.print_b(b1)
c64.CHROUT('\n')
uw1 = min(uwa)
c64scr.print_uw(uw1)
c64.CHROUT('\n')
w1 = min(wa0)
c64scr.print_w(w1)
c64.CHROUT('\n')
w1 = min(wa1)
c64scr.print_w(w1)
c64.CHROUT('\n')
w1 = min(wa2)
c64scr.print_w(w1)
c64.CHROUT('\n')
f1 = min(fa1)
c64flt.print_f(f1)
c64.CHROUT('\n')
c64.CHROUT('x')
c64scr.print_ub(X)
c64.CHROUT('\n')
}
}

View File

@ -552,7 +552,7 @@ data class Label(val name: String, override val position: Position) : IStatement
}
class Return(var values: List<IExpression>, override val position: Position) : IStatement {
open class Return(var values: List<IExpression>, override val position: Position) : IStatement {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
@ -580,6 +580,16 @@ class Return(var values: List<IExpression>, override val position: Position) : I
}
}
class ReturnFromIrq(override val position: Position) : Return(emptyList(), position) {
override fun process(processor: IAstProcessor) = this
override fun toString(): String {
return "ReturnFromIrq(pos=$position)"
}
}
class Continue(override val position: Position) : IStatement {
override lateinit var parent: Node

View File

@ -237,8 +237,13 @@ class AstChecker(private val namespace: INameScope,
err("subroutine has result value(s) and thus must have at least one 'return' or 'goto' in it (or 'rts' / 'jmp' in case of %asm)")
}
// if there's no return statement, we add the implicit one at the end, but only if it's not a kernel routine.
if(subroutine.asmAddress==null)
subroutine.statements.add(Return(emptyList(), subroutine.position))
// @todo move this out of the astchecker
if(subroutine.asmAddress==null) {
if(subroutine.name=="irq" && subroutine.definingScope().name=="irq") {
subroutine.statements.add(ReturnFromIrq(subroutine.position))
} else
subroutine.statements.add(Return(emptyList(), subroutine.position))
}
}
}
@ -783,7 +788,7 @@ class AstChecker(private val namespace: INameScope,
}
else {
val dt = (target as VarDecl).datatype
if(dt !in NumericDatatypes)
if(dt !in NumericDatatypes && dt !in ArrayDatatypes)
checkResult.add(SyntaxError("can only increment or decrement a byte/float/word", postIncrDecr.position))
}
}

View File

@ -153,7 +153,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
override fun process(block: Block): IStatement {
prog.newBlock(block.scopedname, block.name, block.address)
processVariables(block) // @todo optimize initializations with same value: load the value only once (sort on initalization value, datatype ?)
prog.label(block.scopedname)
prog.label("block."+block.scopedname)
prog.line(block.position)
translate(block.statements)
return super.process(block)
@ -199,7 +199,6 @@ private class StatementTranslator(private val prog: IntermediateProgram,
generatedLabelSequenceNumber++
when (stmt) {
is Label -> translate(stmt)
is Return -> translate(stmt)
is VariableInitializationAssignment -> translate(stmt) // for initializing vars in a scope
is Assignment -> translate(stmt) // normal and augmented assignments
is PostIncrDecr -> translate(stmt)
@ -213,6 +212,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
is WhileLoop -> translate(stmt)
is RepeatLoop -> translate(stmt)
is AnonymousScope -> translate(stmt)
is ReturnFromIrq -> translate(stmt)
is Return -> translate(stmt)
is Directive, is VarDecl, is Subroutine -> {} // skip this, already processed these.
is InlineAssembly -> translate(stmt)
else -> TODO("translate statement $stmt to stackvm")
@ -1526,6 +1527,11 @@ private class StatementTranslator(private val prog: IntermediateProgram,
prog.instr(Opcode.RETURN)
}
private fun translate(stmt: ReturnFromIrq) {
prog.line(stmt.position)
prog.instr(Opcode.RETURNFROMIRQ)
}
private fun translate(stmt: Label) {
prog.label(stmt.scopedname)
}

View File

@ -220,6 +220,7 @@ enum class Opcode {
// subroutine calling
CALL,
RETURN,
RETURNFROMIRQ,
SYSCALL,
// misc

View File

@ -113,6 +113,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
var name = if (scoped.startsWith("${block.shortname}.")) {
blockLocal = true
scoped.substring(block.shortname.length+1)
} else if (scoped.startsWith("block.")) {
blockLocal = false
scoped
} else {
blockLocal = false
scoped
@ -176,6 +179,19 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
out("\tldx #\$ff\t; init estack pointer")
out("\tclc")
val irqBlock = program.blocks.singleOrNull { it.scopedname=="irq" }
val haveIrqSub = irqBlock?.instructions?.any { it is LabelInstr && it.name=="irq"}
if(haveIrqSub==true) {
out("\t; install custom irq vector")
out("\tsei")
out("\tlda #<irq.irq")
out("\tsta c64.CINV")
out("\tlda #>irq.irq")
out("\tsta c64.CINV+1")
out("\tcli")
}
out("\tjmp main.start\t; jump to program entrypoint")
out("")
@ -386,7 +402,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
private fun simpleInstr2Asm(ins: Instruction): String? {
// a label 'instruction' is simply translated into a asm label
if(ins is LabelInstr) {
if(ins.name==block.shortname)
if(ins.name.startsWith("block."))
return ""
return if(ins.name.startsWith("${block.shortname}."))
ins.name.substring(block.shortname.length+1)
@ -406,6 +422,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
Opcode.JUMP -> " jmp ${ins.callLabel}"
Opcode.CALL -> " jsr ${ins.callLabel}"
Opcode.RETURN -> " rts"
Opcode.RETURNFROMIRQ -> " jmp c64.IRQDFRT\t\t; continue with normal kernel irq routine"
Opcode.RSAVE -> {
// save cpu status flag and all registers A, X, Y.
// see http://6502.org/tutorials/register_preservation.html
@ -705,8 +722,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
sta ${(ESTACK_LO + 1).toHex()},x
"""
}
Opcode.ADD_W, Opcode.ADD_UW -> " jsr prog8_lib.add_word"
Opcode.SUB_W, Opcode.SUB_UW -> " jsr prog8_lib.sub_word"
Opcode.ADD_W, Opcode.ADD_UW -> " jsr prog8_lib.add_w"
Opcode.SUB_W, Opcode.SUB_UW -> " jsr prog8_lib.sub_w"
Opcode.MUL_B, Opcode.MUL_UB -> " jsr prog8_lib.mul_byte"
Opcode.MUL_W, Opcode.MUL_UW -> " jsr prog8_lib.mul_word"
Opcode.ADD_F -> " jsr prog8_lib.add_f"

View File

@ -751,7 +751,7 @@ class StackVm(private var traceOutputFile: String?) {
}
Opcode.CALL ->
callstack.push(ins.nextAlt)
Opcode.RETURN -> {
Opcode.RETURN, Opcode.RETURNFROMIRQ -> {
if(callstack.empty())
throw VmTerminationException("return instruction with empty call stack")
return callstack.pop()