mirror of
https://github.com/irmen/prog8.git
synced 2024-09-10 09:54:32 +00:00
fix 16 bit inc dec
This commit is contained in:
parent
e30ba696db
commit
68a3b34374
@ -15,7 +15,7 @@ which aims to provide many conveniences over raw assembly code (even when using
|
|||||||
- option to automatically run the compiled program in the Vice emulator
|
- option to automatically run the compiled program in the Vice emulator
|
||||||
- modularity, symbol scoping, subroutines
|
- modularity, symbol scoping, subroutines
|
||||||
- subroutines have enforced input- and output parameter definitions
|
- subroutines have enforced input- and output parameter definitions
|
||||||
- automatic variable allocations
|
- automatic variable allocations, automatic string variables and string sharing
|
||||||
- various data types other than just bytes
|
- various data types other than just bytes
|
||||||
- automatic type conversions
|
- automatic type conversions
|
||||||
- floating point operations
|
- floating point operations
|
||||||
|
@ -423,13 +423,15 @@ class CodeGenerator:
|
|||||||
raise CodeError("invalid incr/decr register")
|
raise CodeError("invalid incr/decr register")
|
||||||
else:
|
else:
|
||||||
if stmt.what.register == 'A':
|
if stmt.what.register == 'A':
|
||||||
self.p("\t\tadc #{:d}".format(stmt.howmuch))
|
self.p("\t\tsec")
|
||||||
|
self.p("\t\tsbc #{:d}".format(stmt.howmuch))
|
||||||
elif stmt.what.register in REGISTER_BYTES:
|
elif stmt.what.register in REGISTER_BYTES:
|
||||||
if stmt.howmuch == 1:
|
if stmt.howmuch == 1:
|
||||||
self.p("\t\tde{:s}".format(stmt.what.register.lower()))
|
self.p("\t\tde{:s}".format(stmt.what.register.lower()))
|
||||||
else:
|
else:
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\tt{:s}a".format(stmt.what.register.lower()))
|
self.p("\t\tt{:s}a".format(stmt.what.register.lower()))
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc #{:d}".format(stmt.howmuch))
|
self.p("\t\tsbc #{:d}".format(stmt.howmuch))
|
||||||
self.p("\t\tta{:s}".format(stmt.what.register.lower()))
|
self.p("\t\tta{:s}".format(stmt.what.register.lower()))
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
@ -454,11 +456,11 @@ class CodeGenerator:
|
|||||||
self.p("\t\tclc")
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc #{:d}".format(stmt.howmuch))
|
self.p("\t\tadc #{:d}".format(stmt.howmuch))
|
||||||
else:
|
else:
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc #{:d}".format(stmt.howmuch))
|
self.p("\t\tsbc #{:d}".format(stmt.howmuch))
|
||||||
self.p("\t\tsta " + r_str)
|
self.p("\t\tsta " + r_str)
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
elif what.datatype == DataType.WORD:
|
elif what.datatype == DataType.WORD:
|
||||||
# @todo verify this 16-bit incr/decr asm code
|
|
||||||
if stmt.howmuch == 1:
|
if stmt.howmuch == 1:
|
||||||
if is_incr:
|
if is_incr:
|
||||||
self.p("\t\tinc " + r_str)
|
self.p("\t\tinc " + r_str)
|
||||||
@ -466,10 +468,12 @@ class CodeGenerator:
|
|||||||
self.p("\t\tinc {:s}+1".format(r_str))
|
self.p("\t\tinc {:s}+1".format(r_str))
|
||||||
self.p("+")
|
self.p("+")
|
||||||
else:
|
else:
|
||||||
self.p("\t\tdec " + r_str)
|
self.p("\t\tpha")
|
||||||
|
self.p("\t\tlda " + r_str)
|
||||||
self.p("\t\tbne +")
|
self.p("\t\tbne +")
|
||||||
self.p("\t\tdec {:s}+1".format(r_str))
|
self.p("\t\tdec {:s}+1".format(r_str))
|
||||||
self.p("+")
|
self.p("+\t\tdec " + r_str)
|
||||||
|
self.p("\t\tpla")
|
||||||
else:
|
else:
|
||||||
raise CodeError("cannot yet incr/decr 16 bit memory by more than 1") # @todo 16-bit incr/decr
|
raise CodeError("cannot yet incr/decr 16 bit memory by more than 1") # @todo 16-bit incr/decr
|
||||||
else:
|
else:
|
||||||
@ -917,18 +921,20 @@ class CodeGenerator:
|
|||||||
def _generate_aug_reg_mem(self, lvalue: ParseResult.RegisterValue, operator: str, rvalue: ParseResult.MemMappedValue) -> None:
|
def _generate_aug_reg_mem(self, lvalue: ParseResult.RegisterValue, operator: str, rvalue: ParseResult.MemMappedValue) -> None:
|
||||||
r_str = rvalue.name or Parser.to_hex(rvalue.address)
|
r_str = rvalue.name or Parser.to_hex(rvalue.address)
|
||||||
if operator == "+=":
|
if operator == "+=":
|
||||||
self.p("\t\tclc")
|
|
||||||
if lvalue.register == "A":
|
if lvalue.register == "A":
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc " + r_str)
|
self.p("\t\tadc " + r_str)
|
||||||
elif lvalue.register == "X":
|
elif lvalue.register == "X":
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttxa")
|
self.p("\t\ttxa")
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc " + r_str)
|
self.p("\t\tadc " + r_str)
|
||||||
self.p("\t\ttax")
|
self.p("\t\ttax")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
elif lvalue.register == "Y":
|
elif lvalue.register == "Y":
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttya")
|
self.p("\t\ttya")
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc " + r_str)
|
self.p("\t\tadc " + r_str)
|
||||||
self.p("\t\ttay")
|
self.p("\t\ttay")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
@ -936,16 +942,19 @@ class CodeGenerator:
|
|||||||
raise CodeError("unsupported register for aug assign", str(lvalue)) # @todo +=.word
|
raise CodeError("unsupported register for aug assign", str(lvalue)) # @todo +=.word
|
||||||
elif operator == "-=":
|
elif operator == "-=":
|
||||||
if lvalue.register == "A":
|
if lvalue.register == "A":
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc " + r_str)
|
self.p("\t\tsbc " + r_str)
|
||||||
elif lvalue.register == "X":
|
elif lvalue.register == "X":
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttxa")
|
self.p("\t\ttxa")
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc " + r_str)
|
self.p("\t\tsbc " + r_str)
|
||||||
self.p("\t\ttax")
|
self.p("\t\ttax")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
elif lvalue.register == "Y":
|
elif lvalue.register == "Y":
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttya")
|
self.p("\t\ttya")
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc " + r_str)
|
self.p("\t\tsbc " + r_str)
|
||||||
self.p("\t\ttay")
|
self.p("\t\ttay")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
@ -1010,18 +1019,20 @@ class CodeGenerator:
|
|||||||
def _generate_aug_reg_int(self, lvalue: ParseResult.RegisterValue, operator: str, rvalue: ParseResult.IntegerValue) -> None:
|
def _generate_aug_reg_int(self, lvalue: ParseResult.RegisterValue, operator: str, rvalue: ParseResult.IntegerValue) -> None:
|
||||||
r_str = rvalue.name or Parser.to_hex(rvalue.value)
|
r_str = rvalue.name or Parser.to_hex(rvalue.value)
|
||||||
if operator == "+=":
|
if operator == "+=":
|
||||||
self.p("\t\tclc")
|
|
||||||
if lvalue.register == "A":
|
if lvalue.register == "A":
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc #" + r_str)
|
self.p("\t\tadc #" + r_str)
|
||||||
elif lvalue.register == "X":
|
elif lvalue.register == "X":
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttxa")
|
self.p("\t\ttxa")
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc #" + r_str)
|
self.p("\t\tadc #" + r_str)
|
||||||
self.p("\t\ttax")
|
self.p("\t\ttax")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
elif lvalue.register == "Y":
|
elif lvalue.register == "Y":
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttya")
|
self.p("\t\ttya")
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc #" + r_str)
|
self.p("\t\tadc #" + r_str)
|
||||||
self.p("\t\ttay")
|
self.p("\t\ttay")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
@ -1029,16 +1040,19 @@ class CodeGenerator:
|
|||||||
raise CodeError("unsupported register for aug assign", str(lvalue)) # @todo +=.word
|
raise CodeError("unsupported register for aug assign", str(lvalue)) # @todo +=.word
|
||||||
elif operator == "-=":
|
elif operator == "-=":
|
||||||
if lvalue.register == "A":
|
if lvalue.register == "A":
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc #" + r_str)
|
self.p("\t\tsbc #" + r_str)
|
||||||
elif lvalue.register == "X":
|
elif lvalue.register == "X":
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttxa")
|
self.p("\t\ttxa")
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc #" + r_str)
|
self.p("\t\tsbc #" + r_str)
|
||||||
self.p("\t\ttax")
|
self.p("\t\ttax")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
elif lvalue.register == "Y":
|
elif lvalue.register == "Y":
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttya")
|
self.p("\t\ttya")
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc #" + r_str)
|
self.p("\t\tsbc #" + r_str)
|
||||||
self.p("\t\ttay")
|
self.p("\t\ttay")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
@ -1136,16 +1150,17 @@ class CodeGenerator:
|
|||||||
|
|
||||||
def _generate_aug_reg_reg(self, lvalue: ParseResult.RegisterValue, operator: str, rvalue: ParseResult.RegisterValue) -> None:
|
def _generate_aug_reg_reg(self, lvalue: ParseResult.RegisterValue, operator: str, rvalue: ParseResult.RegisterValue) -> None:
|
||||||
if operator == "+=":
|
if operator == "+=":
|
||||||
self.p("\t\tclc")
|
|
||||||
if rvalue.register not in REGISTER_BYTES:
|
if rvalue.register not in REGISTER_BYTES:
|
||||||
raise CodeError("unsupported rvalue register for aug assign", str(rvalue)) # @todo +=.word
|
raise CodeError("unsupported rvalue register for aug assign", str(rvalue)) # @todo +=.word
|
||||||
if lvalue.register == "A":
|
if lvalue.register == "A":
|
||||||
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
self.p("\t\tadc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
||||||
elif lvalue.register == "X":
|
elif lvalue.register == "X":
|
||||||
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttxa")
|
self.p("\t\ttxa")
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
self.p("\t\tadc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
||||||
self.p("\t\ttax")
|
self.p("\t\ttax")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
@ -1153,6 +1168,7 @@ class CodeGenerator:
|
|||||||
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttya")
|
self.p("\t\ttya")
|
||||||
|
self.p("\t\tclc")
|
||||||
self.p("\t\tadc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
self.p("\t\tadc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
||||||
self.p("\t\ttay")
|
self.p("\t\ttay")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
@ -1163,11 +1179,13 @@ class CodeGenerator:
|
|||||||
raise CodeError("unsupported rvalue register for aug assign", str(rvalue)) # @todo -=.word
|
raise CodeError("unsupported rvalue register for aug assign", str(rvalue)) # @todo -=.word
|
||||||
if lvalue.register == "A":
|
if lvalue.register == "A":
|
||||||
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
self.p("\t\tsbc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
||||||
elif lvalue.register == "X":
|
elif lvalue.register == "X":
|
||||||
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttxa")
|
self.p("\t\ttxa")
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
self.p("\t\tsbc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
||||||
self.p("\t\ttax")
|
self.p("\t\ttax")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
@ -1175,6 +1193,7 @@ class CodeGenerator:
|
|||||||
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
self.p("\t\tst{:s} {:s}".format(rvalue.register.lower(), Parser.to_hex(Zeropage.SCRATCH_B1)))
|
||||||
self.p("\t\tpha")
|
self.p("\t\tpha")
|
||||||
self.p("\t\ttya")
|
self.p("\t\ttya")
|
||||||
|
self.p("\t\tsec")
|
||||||
self.p("\t\tsbc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
self.p("\t\tsbc " + Parser.to_hex(Zeropage.SCRATCH_B1))
|
||||||
self.p("\t\ttay")
|
self.p("\t\ttay")
|
||||||
self.p("\t\tpla")
|
self.p("\t\tpla")
|
||||||
|
@ -333,6 +333,8 @@ sub GETADRAY () -> (AY, X?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; @todo optimize print_string()/ print_pstring() of a single character into a call to c64.CHROUT instead
|
||||||
|
|
||||||
sub print_string (address: XY) -> (A?, Y?) {
|
sub print_string (address: XY) -> (A?, Y?) {
|
||||||
; ---- print null terminated string from X/Y
|
; ---- print null terminated string from X/Y
|
||||||
asm {
|
asm {
|
||||||
|
@ -15,7 +15,7 @@ which aims to provide many conveniences over raw assembly code (even when using
|
|||||||
- option to automatically run the compiled program in the Vice emulator
|
- option to automatically run the compiled program in the Vice emulator
|
||||||
- modularity, symbol scoping, subroutines
|
- modularity, symbol scoping, subroutines
|
||||||
- subroutines have enforced input- and output parameter definitions
|
- subroutines have enforced input- and output parameter definitions
|
||||||
- automatic variable allocations
|
- automatic variable allocations, automatic string variables and string sharing
|
||||||
- various data types other than just bytes
|
- various data types other than just bytes
|
||||||
- automatic type conversions
|
- automatic type conversions
|
||||||
- floating point operations
|
- floating point operations
|
||||||
|
@ -11,7 +11,6 @@ import "c64lib"
|
|||||||
var attempts_left = 10
|
var attempts_left = 10
|
||||||
|
|
||||||
start
|
start
|
||||||
c64util.init_system()
|
|
||||||
A = c64.VMCSB
|
A = c64.VMCSB
|
||||||
A |= 2 ; @todo c64.VMCSB |= 2
|
A |= 2 ; @todo c64.VMCSB |= 2
|
||||||
c64.VMCSB = A
|
c64.VMCSB = A
|
||||||
@ -41,8 +40,10 @@ printloop
|
|||||||
c64util.print_string("\nYou have ")
|
c64util.print_string("\nYou have ")
|
||||||
c64util.print_byte_decimal(attempts_left)
|
c64util.print_byte_decimal(attempts_left)
|
||||||
c64util.print_string(" guess")
|
c64util.print_string(" guess")
|
||||||
|
|
||||||
|
; @todo comparison expression so we can do if attempts_left>0 ...
|
||||||
A = attempts_left
|
A = attempts_left
|
||||||
A -= 1 ; @todo wrong instruction adc
|
A --
|
||||||
if_zero A goto ask_guess
|
if_zero A goto ask_guess
|
||||||
c64util.print_string("es")
|
c64util.print_string("es")
|
||||||
ask_guess
|
ask_guess
|
||||||
@ -52,7 +53,7 @@ ask_guess
|
|||||||
[$22.word] = guess
|
[$22.word] = guess
|
||||||
c64.FREADSTR(A)
|
c64.FREADSTR(A)
|
||||||
AY = c64util.GETADRAY()
|
AY = c64util.GETADRAY()
|
||||||
A -= secretnumber
|
A -= secretnumber ; @todo condition so we can do if guess > secretnumber....
|
||||||
if_zero goto correct_guess
|
if_zero goto correct_guess
|
||||||
if_gt goto too_high
|
if_gt goto too_high
|
||||||
c64util.print_string("That is too ")
|
c64util.print_string("That is too ")
|
||||||
|
Loading…
Reference in New Issue
Block a user