mirror of
https://github.com/irmen/prog8.git
synced 2025-02-02 04:30:46 +00:00
mult fixes
This commit is contained in:
parent
dfa1d5e398
commit
2201765366
@ -12,6 +12,10 @@
|
||||
|
||||
txt {
|
||||
|
||||
const ubyte DEFAULT_WIDTH = 40
|
||||
const ubyte DEFAULT_HEIGHT = 25
|
||||
|
||||
|
||||
asmsub clear_screen() {
|
||||
%asm {{
|
||||
lda #' '
|
||||
|
@ -11,6 +11,10 @@
|
||||
|
||||
txt {
|
||||
|
||||
const ubyte DEFAULT_WIDTH = 80
|
||||
const ubyte DEFAULT_HEIGHT = 60
|
||||
|
||||
|
||||
sub clear_screen() {
|
||||
c64.CHROUT(147) ; clear screen (spaces)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
63
examples/cx16/numbergame.p8
Normal file
63
examples/cx16/numbergame.p8
Normal 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")
|
||||
}
|
||||
}
|
||||
}
|
@ -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++
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
%import c64textio
|
||||
%import c64lib
|
||||
%import conv
|
||||
%zeropage basicsafe
|
||||
|
||||
|
@ -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++
|
||||
}
|
||||
}
|
||||
|
@ -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')
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user