mult fixes

This commit is contained in:
Irmen de Jong 2020-09-20 00:17:33 +02:00
parent dfa1d5e398
commit 2201765366
10 changed files with 161 additions and 82 deletions

View File

@ -12,6 +12,10 @@
txt {
const ubyte DEFAULT_WIDTH = 40
const ubyte DEFAULT_HEIGHT = 25
asmsub clear_screen() {
%asm {{
lda #' '

View File

@ -11,6 +11,10 @@
txt {
const ubyte DEFAULT_WIDTH = 80
const ubyte DEFAULT_HEIGHT = 60
sub clear_screen() {
c64.CHROUT(147) ; clear screen (spaces)
}

View File

@ -58,6 +58,7 @@ multiply_words .proc
; input: A/Y = first 16-bit number, P8ZP_SCRATCH_W1 in ZP = second 16-bit number
; output: multiply_words.result 4-bytes/32-bits product, LSB order (low-to-high)
; clobbers: A
; TODO find a faster 16*16 -> 16 bits multiplication routine
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1

View File

@ -744,7 +744,8 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun accept(visitor: AstWalker, parent: Node)= visitor.visit(this, parent)
override fun referencesIdentifiers(vararg name: String): Boolean = nameInSource.last() in name
override fun referencesIdentifiers(vararg name: String): Boolean =
nameInSource.size==name.size && nameInSource.toTypedArray().contentEquals(name)
override fun inferType(program: Program): InferredTypes.InferredType {
return when (val targetStmt = targetStatement(program.namespace)) {

View File

@ -693,26 +693,36 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
if(value in asmgen.optimizedWordMultiplications) {
asmgen.out(" lda $name | ldy $name+1 | jsr math.mul_word_$value | sta $name | sty $name+1")
} else {
TODO("var uword mul litval $value")
asmgen.out("""
lda $name
sta P8ZP_SCRATCH_W1
lda $name+1
sta P8ZP_SCRATCH_W1+1
lda #<$value
ldy #>$value
jsr math.multiply_words
lda math.multiply_words.result
sta $name
lda math.multiply_words.result+1
sta $name+1""")
}
} else {
if(value.absoluteValue in asmgen.optimizedWordMultiplications) {
asmgen.out(" lda $name | ldy $name+1 | jsr math.mul_word_$value | sta $name | sty $name+1")
} else {
// TODO don't use stack here
// TODO does this work for signed words?
// TODO does this work for signed words? if so the uword/word distinction can be removed altogether
asmgen.out("""
lda $name
sta P8ZP_SCRATCH_W1
lda $name+1
sta P8ZP_SCRATCH_W1+1
lda #<$value
ldy #>$value
jsr math.multiply_words
lda math.multiply_words.result
sta $name
lda math.multiply_words.result+1
sta $name+1""")
lda $name
sta P8ZP_SCRATCH_W1
lda $name+1
sta P8ZP_SCRATCH_W1+1
lda #<$value
ldy #>$value
jsr math.multiply_words
lda math.multiply_words.result
sta $name
lda math.multiply_words.result+1
sta $name+1""")
}
}
}
@ -827,7 +837,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
val valueDt = ident.targetVarDecl(program.namespace)!!.datatype
when (valueDt) {
in ByteDatatypes -> {
// the other variable is a BYTE type so optimize for that TODO does this even occur?
// the other variable is a BYTE type so optimize for that
when (operator) {
// note: ** (power) operator requires floats.
"+" -> asmgen.out("""
@ -846,9 +856,23 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
bcs +
dec $name+1
+ """)
"*" -> TODO("mul word*byte")
"/" -> TODO("div word/byte")
"%" -> TODO("word remainder byte")
"*" -> {
// TODO use a more efficient 16 *8 -> 16 multiplication routine
asmgen.out("""
lda $otherName
sta P8ZP_SCRATCH_W1
lda #0
sta P8ZP_SCRATCH_W1+1
lda $name
ldy $name+1
jsr math.multiply_words
lda math.multiply_words.result
sta $name
lda math.multiply_words.result+1
sta $name+1""")
}
"/" -> TODO("div wordvar/bytevar")
"%" -> TODO("word remainder bytevar")
"<<" -> {
asmgen.out("""
ldy $otherName
@ -876,9 +900,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
bne -""")
}
}
"&" -> TODO("bitand word byte")
"^" -> TODO("bitxor word byte")
"|" -> TODO("bitor word byte")
"&" -> TODO("bitand wordvar bytevar")
"^" -> TODO("bitxor wordvar bytevar")
"|" -> TODO("bitor wordvar bytevar")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}

View File

@ -0,0 +1,63 @@
%target cx16
%import cx16textio
%import conv
%zeropage basicsafe
; The classic number guessing game.
main {
sub start() {
str name = "????????????????????????????????????????"
str input = "??????????"
ubyte secretnumber = rnd() % 99 + 1 ; random number 1..100
ubyte attempts_left
txt.lowercase()
txt.print("Please introduce yourself: ")
void txt.input_chars(name)
txt.print("\n\nHello, ")
txt.print(name)
txt.print(".\nLet's play a number guessing game.\nI am thinking of a number from 1 to 100!You'll have to guess it!\n")
for attempts_left in 10 downto 1 {
txt.print("\nYou have ")
txt.print_ub(attempts_left)
txt.print(" guess")
if attempts_left>1
txt.print("es")
txt.print(" left.\nWhat is your next guess? ")
void txt.input_chars(input)
ubyte guess = lsb(conv.str2uword(input))
if guess==secretnumber {
ending(true)
return
} else {
txt.print("\n\nThat is too ")
if guess<secretnumber
txt.print("low!\n")
else
txt.print("high!\n")
}
}
ending(false)
return
sub ending(ubyte success) {
if success
txt.print("\n\nYou guessed it, impressive!\n")
else {
txt.print("\nToo bad! My number was: ")
txt.print_ub(secretnumber)
txt.print(".\n")
}
txt.print("Thanks for playing, ")
txt.print(name)
txt.print(".\n")
}
}
}

View File

@ -1,12 +1,10 @@
%target cx16
%import cx16lib
%import cx16textio
%zeropage basicsafe
main {
; TODO this code is identical to the c64 one except the import
const uword width = 79
const uword height = 59
main {
struct Ball {
uword anglex
@ -19,12 +17,12 @@ main {
Ball ball
repeat {
ubyte x = msb(sin8u(msb(ball.anglex)) as uword * width)
ubyte y = msb(cos8u(msb(ball.angley)) as uword * height)
ubyte x = msb(sin8u(msb(ball.anglex)) as uword * txt.DEFAULT_WIDTH)
ubyte y = msb(cos8u(msb(ball.angley)) as uword * txt.DEFAULT_HEIGHT)
txt.setcc(x, y, 81, ball.color)
ball.anglex+=266
ball.angley+=215
ball.anglex+=366
ball.angley+=291
ball.color++
}
}

View File

@ -1,5 +1,4 @@
%import c64textio
%import c64lib
%import conv
%zeropage basicsafe

View File

@ -1,10 +1,10 @@
%import c64textio
%zeropage basicsafe
; TODO this code is identical to the commanderx16 one except the import
main {
const uword width = 40
const uword height = 25
struct Ball {
uword anglex
uword angley
@ -16,12 +16,12 @@ main {
Ball ball
repeat {
ubyte x = msb(sin8u(msb(ball.anglex)) as uword * width)
ubyte y = msb(cos8u(msb(ball.angley)) as uword * height)
ubyte x = msb(sin8u(msb(ball.anglex)) as uword * txt.DEFAULT_WIDTH)
ubyte y = msb(cos8u(msb(ball.angley)) as uword * txt.DEFAULT_HEIGHT)
txt.setcc(x, y, 81, ball.color)
ball.anglex+=800
ball.angley+=947
ball.anglex+=366
ball.angley+=291
ball.color++
}
}

View File

@ -12,53 +12,38 @@ main {
sub start() {
txt.lowercase()
txt.print("Hello there")
uword ww
ubyte bb=44
ww = bb*($0032)
txt.print_uw(ww)
const uword cvalue = 155
const uword cvalue2 = 5555
uword wvalue = 155
uword wvalue2 = 5555
txt.setchr(5, 5, '*')
txt.setchr(6, 5, '*')
txt.setchr(7, 5, '*')
txt.setchr(7, 6, '+')
txt.setchr(7, 7, '+')
txt.setclr(5, 5, 1)
txt.setclr(6, 5, 2)
txt.setclr(7, 5, 3)
txt.setclr(7, 6, 4)
txt.setclr(7, 7, 5)
txt.plot(15,10)
txt.chrout('!')
txt.print_ub(txt.getchr(4,5))
txt.chrout(',')
txt.print_ub(txt.getchr(5,5))
txt.chrout(',')
txt.print_ub(txt.getchr(6,5))
txt.chrout(',')
txt.print_ub(txt.getchr(7,5))
txt.chrout(',')
txt.print_ub(txt.getchr(8,5))
; TODO ALL multiplications below should yield a word result
uword x
ubyte bb = 9
x = bb * cvalue ; TODO wrong result, must be word
txt.print_uw(x)
txt.chrout('\n')
txt.print_ub(txt.getclr(4,5))
txt.chrout(',')
txt.print_ub(txt.getclr(5,5))
txt.chrout(',')
txt.print_ub(txt.getclr(6,5))
txt.chrout(',')
txt.print_ub(txt.getclr(7,5))
txt.chrout(',')
txt.print_ub(txt.getclr(8,5))
x = bb * cvalue2
txt.print_uw(x)
txt.chrout('\n')
x = bb * wvalue
txt.print_uw(x)
txt.chrout('\n')
x = bb * wvalue2
txt.print_uw(x)
txt.chrout('\n')
txt.print("width:")
txt.print_ub(txt.width())
txt.print(" height:")
txt.print_ub(txt.height())
x = cvalue * bb ; TODO wrong result, must be word
txt.print_uw(x)
txt.chrout('\n')
x = cvalue2 * bb
txt.print_uw(x)
txt.chrout('\n')
x = wvalue * bb
txt.print_uw(x)
txt.chrout('\n')
x = wvalue2 * bb
txt.print_uw(x)
txt.chrout('\n')
}
}