mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
added some more missing assignment codegens (word * byte etc)
This commit is contained in:
parent
94c30fc21e
commit
59c0e6ae32
@ -1197,4 +1197,22 @@ $counterVar .byte 0""")
|
||||
val assembly = asm.assembly.trimEnd().trimStart('\n')
|
||||
assemblyLines.add(assembly)
|
||||
}
|
||||
|
||||
internal fun signExtendStackByte(valueDt: DataType) {
|
||||
// sign extend signed byte on stack to signed word
|
||||
when(valueDt) {
|
||||
DataType.UBYTE -> {
|
||||
out(" lda #0 | sta P8ESTACK_HI+1,x")
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
out("""
|
||||
lda P8ESTACK_LO+1,x
|
||||
ora #$7f
|
||||
bmi +
|
||||
lda #0
|
||||
+ sta P8ESTACK_HI+1,x""")
|
||||
}
|
||||
else -> throw AssemblyError("need byte type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1013,15 +1013,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
||||
DataType.BYTE -> {
|
||||
when(typecast.type) {
|
||||
DataType.UBYTE, DataType.BYTE -> {}
|
||||
DataType.UWORD, DataType.WORD -> {
|
||||
// sign extend
|
||||
asmgen.out("""
|
||||
lda P8ESTACK_LO+1,x
|
||||
ora #$7f
|
||||
bmi +
|
||||
lda #0
|
||||
+ sta P8ESTACK_HI+1,x""")
|
||||
}
|
||||
DataType.UWORD, DataType.WORD -> asmgen.signExtendStackByte(DataType.BYTE)
|
||||
DataType.FLOAT -> asmgen.out(" jsr floats.stack_b2float")
|
||||
in PassByReferenceDatatypes -> throw AssemblyError("cannot cast to a pass-by-reference datatype")
|
||||
else -> throw AssemblyError("weird type")
|
||||
|
@ -1031,6 +1031,68 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
asmgen.translateExpression(value)
|
||||
val valueDt = value.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
|
||||
fun multiplyWord() {
|
||||
asmgen.out("""
|
||||
lda P8ESTACK_LO+1,x
|
||||
ldy P8ESTACK_HI+1,x
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty 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
|
||||
""")
|
||||
}
|
||||
|
||||
fun divideWord() {
|
||||
if (dt == DataType.WORD) {
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
ldy $name+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
ldy P8ESTACK_HI+1,x
|
||||
jsr math.divmod_w_asm
|
||||
sta $name
|
||||
sty $name+1
|
||||
""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
ldy $name+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
ldy P8ESTACK_HI+1,x
|
||||
jsr math.divmod_uw_asm
|
||||
sta $name
|
||||
sty $name+1
|
||||
""")
|
||||
}
|
||||
}
|
||||
|
||||
fun remainderWord() {
|
||||
if(dt==DataType.WORD)
|
||||
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
ldy $name+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
ldy P8ESTACK_HI+1,x
|
||||
jsr math.divmod_uw_asm
|
||||
lda P8ZP_SCRATCH_W2
|
||||
sta $name
|
||||
lda P8ZP_SCRATCH_W2+1
|
||||
sta $name+1
|
||||
""")
|
||||
}
|
||||
|
||||
when(valueDt) {
|
||||
in ByteDatatypes -> {
|
||||
// the other variable is a BYTE type so optimize for that
|
||||
@ -1084,9 +1146,21 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
sbc P8ZP_SCRATCH_B1
|
||||
sta $name+1""")
|
||||
}
|
||||
"*" -> TODO("mul (u)word (u)byte")
|
||||
"/" -> TODO("div (u)word (u)byte")
|
||||
"%" -> TODO("(u)word remainder (u)byte")
|
||||
"*" -> {
|
||||
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
||||
asmgen.signExtendStackByte(valueDt)
|
||||
multiplyWord()
|
||||
}
|
||||
"/" -> {
|
||||
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
||||
asmgen.signExtendStackByte(valueDt)
|
||||
divideWord()
|
||||
}
|
||||
"%" -> {
|
||||
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
||||
asmgen.signExtendStackByte(valueDt)
|
||||
remainderWord()
|
||||
}
|
||||
"<<" -> {
|
||||
asmgen.translateExpression(value)
|
||||
asmgen.out("""
|
||||
@ -1137,65 +1211,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
// note: ** (power) operator requires floats.
|
||||
"+" -> asmgen.out(" lda $name | clc | adc P8ESTACK_LO+1,x | sta $name | lda $name+1 | adc P8ESTACK_HI+1,x | sta $name+1")
|
||||
"-" -> asmgen.out(" lda $name | sec | sbc P8ESTACK_LO+1,x | sta $name | lda $name+1 | sbc P8ESTACK_HI+1,x | sta $name+1")
|
||||
"*" -> {
|
||||
asmgen.out("""
|
||||
lda P8ESTACK_LO+1,x
|
||||
ldy P8ESTACK_HI+1,x
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty 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
|
||||
""")
|
||||
}
|
||||
"/" -> {
|
||||
if (dt == DataType.WORD) {
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
ldy $name+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
ldy P8ESTACK_HI+1,x
|
||||
jsr math.divmod_w_asm
|
||||
sta $name
|
||||
sty $name+1
|
||||
""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
ldy $name+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
ldy P8ESTACK_HI+1,x
|
||||
jsr math.divmod_uw_asm
|
||||
sta $name
|
||||
sty $name+1
|
||||
""")
|
||||
}
|
||||
}
|
||||
"%" -> {
|
||||
if(dt==DataType.WORD)
|
||||
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
ldy $name+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda P8ESTACK_LO+1,x
|
||||
ldy P8ESTACK_HI+1,x
|
||||
jsr math.divmod_uw_asm
|
||||
lda P8ZP_SCRATCH_W2
|
||||
sta $name
|
||||
lda P8ZP_SCRATCH_W2+1
|
||||
sta $name+1
|
||||
""")
|
||||
}
|
||||
"*" -> multiplyWord()
|
||||
"/" -> divideWord()
|
||||
"%" -> remainderWord()
|
||||
"<<", ">>" -> throw AssemblyError("shift by a word value not supported, max is a byte")
|
||||
"&" -> asmgen.out(" lda $name | and P8ESTACK_LO+1,x | sta $name | lda $name+1 | and P8ESTACK_HI+1,x | sta $name+1")
|
||||
"^" -> asmgen.out(" lda $name | eor P8ESTACK_LO+1,x | sta $name | lda $name+1 | eor P8ESTACK_HI+1,x | sta $name+1")
|
||||
|
@ -1,6 +1,4 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
@ -9,18 +7,11 @@ main {
|
||||
txt.print("\n--> TextElite conversion to Prog8 <--\n\n")
|
||||
|
||||
galaxy.init(1)
|
||||
txt.print("\nstart!!!!")
|
||||
galaxy.debug_seed()
|
||||
|
||||
galaxy.generate_planet(galaxy.numforLave)
|
||||
planet.display(false)
|
||||
|
||||
; repeat 5 {
|
||||
; planet.set_seed(rndw(), rndw())
|
||||
; planet.name = planet.random_name()
|
||||
; planet.display(false)
|
||||
; txt.chrout('\n')
|
||||
; }
|
||||
txt.print("\nEnter to exit: ")
|
||||
void c64.CHRIN()
|
||||
}
|
||||
|
||||
asmsub testX() {
|
||||
@ -42,11 +33,10 @@ _saveX .byte 0
|
||||
|
||||
galaxy {
|
||||
const uword GALSIZE = 256
|
||||
; seed for first galaxy:
|
||||
const uword base0 = $5A4A
|
||||
const uword base0 = $5A4A ; seeds for the first galaxy
|
||||
const uword base1 = $0248
|
||||
const uword base2 = $B753
|
||||
const ubyte numforLave = 7 ; Lave is 7th generated planet in galaxy one
|
||||
const ubyte numforLave = 7 ; Lave is 7th generated planet in galaxy one
|
||||
const ubyte numforZaonce = 129
|
||||
const ubyte numforDiso = 147
|
||||
const ubyte numforRied = 46
|
||||
@ -98,12 +88,39 @@ galaxy {
|
||||
txt.chrout('\n')
|
||||
}
|
||||
|
||||
sub generate_planet_properties() {
|
||||
; create the planet's characteristics
|
||||
planet.x = msb(seed[1])
|
||||
planet.y = msb(seed[0])
|
||||
planet.govtype = lsb(seed[1]) >> 3 & 7 ; bits 3,4 &5 of w1
|
||||
planet.economy = msb(seed[0]) & 7 ; bits 8,9 &A of w0
|
||||
if planet.govtype <= 1
|
||||
planet.economy = (planet.economy | 2)
|
||||
planet.techlevel = (msb(seed[1]) & 3) + (planet.economy ^ 7)
|
||||
planet.techlevel += planet.govtype >> 1
|
||||
if planet.govtype & 1
|
||||
planet.techlevel++
|
||||
planet.population = 4 * planet.techlevel + planet.economy
|
||||
planet.population += planet.govtype + 1
|
||||
planet.productivity = ((planet.economy ^ 7) + 3) * (planet.govtype + 4)
|
||||
planet.productivity *= planet.population * 8
|
||||
planet.radius = mkword((msb(seed[2]) & 15) + 11, planet.x)
|
||||
;planet.radius = 256 * (((seed[2] >> 8) & 15) + 11) + planet.x ; TODO why not the same answer??
|
||||
; TODO make this work: planet.goatsoup_seed = [seed[1] & $FF, seed[1] >> 8, seed[2] & $FF, seed[2] >> 8]
|
||||
planet.goatsoup_seed[0] = lsb(seed[1])
|
||||
planet.goatsoup_seed[1] = msb(seed[1])
|
||||
planet.goatsoup_seed[2] = lsb(seed[2])
|
||||
planet.goatsoup_seed[3] = msb(seed[2])
|
||||
}
|
||||
|
||||
sub generate_planet(ubyte planetnum) {
|
||||
ubyte pair1
|
||||
ubyte pair2
|
||||
ubyte pair3
|
||||
ubyte pair4
|
||||
repeat planetnum+1 {
|
||||
generate_planet_properties()
|
||||
|
||||
; Always four iterations of random number
|
||||
pair1 = (msb(seed[2]) & 31) * 2
|
||||
tweakseed()
|
||||
@ -115,20 +132,9 @@ galaxy {
|
||||
tweakseed()
|
||||
}
|
||||
|
||||
debug_seed()
|
||||
|
||||
txt.print("generating planet #")
|
||||
txt.print_ub(planetnum)
|
||||
txt.print("\npairs:")
|
||||
txt.print_ub(pair1)
|
||||
txt.chrout(',')
|
||||
txt.print_ub(pair2)
|
||||
txt.chrout(',')
|
||||
txt.print_ub(pair3)
|
||||
txt.chrout(',')
|
||||
txt.print_ub(pair4)
|
||||
txt.chrout('\n')
|
||||
; debug_seed()
|
||||
|
||||
; create the planet's name
|
||||
ubyte ni = 0
|
||||
if pairs[pair1] != '.' {
|
||||
planet.name[ni] = pairs[pair1]
|
||||
@ -241,8 +247,8 @@ planet {
|
||||
ubyte govtype
|
||||
ubyte techlevel
|
||||
ubyte population
|
||||
ubyte productivity
|
||||
ubyte radius
|
||||
uword productivity
|
||||
uword radius
|
||||
; todo: species
|
||||
|
||||
sub set_seed(uword s1, uword s2) {
|
||||
@ -404,9 +410,9 @@ planet {
|
||||
txt.print("\nTech Level: ")
|
||||
txt.print_ub(techlevel+1)
|
||||
txt.print("\nTurnover: ")
|
||||
txt.print_ub(productivity)
|
||||
txt.print("\nRadius:")
|
||||
txt.print_ub(radius)
|
||||
txt.print_uw(productivity)
|
||||
txt.print("\nRadius: ")
|
||||
txt.print_uw(radius)
|
||||
txt.print("\nPopulation: ")
|
||||
txt.print_ub(population >> 3)
|
||||
txt.print(" Billion\n")
|
||||
|
Loading…
Reference in New Issue
Block a user