mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
irq routine activated
This commit is contained in:
parent
904e317781
commit
8adbcb7a26
@ -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)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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++
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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')
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -220,6 +220,7 @@ enum class Opcode {
|
||||
// subroutine calling
|
||||
CALL,
|
||||
RETURN,
|
||||
RETURNFROMIRQ,
|
||||
SYSCALL,
|
||||
|
||||
// misc
|
||||
|
@ -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"
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user