mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-02-07 04:30:35 +00:00
Initial attempt at 16-bit compare. Not super well tested yet.
This commit is contained in:
parent
0429e4bd90
commit
e74c7f2b31
@ -288,9 +288,9 @@ this mode is used.
|
||||
|
||||
copy <src-memory-location>, <dest-memory-location>
|
||||
|
||||
Reads from src and writes to dest. Differs from `st` in that is able to
|
||||
copy more general types of data (for example, vectors,) and it trashes the
|
||||
`z` and `n` flags and the `a` register.
|
||||
Reads from src and writes to dest. Differs from `ld` and `st` in that
|
||||
it is able to copy more general types of data (for example, vectors,)
|
||||
and it trashes the `z` and `n` flags and the `a` register.
|
||||
|
||||
* It is illegal if dest is read-only.
|
||||
* It is illegal if dest does not occur in the WRITES of the current routine.
|
||||
@ -401,6 +401,20 @@ does not store the result anywhere, only sets the resulting flags.
|
||||
Affects n, z, and c flags, requiring that they be in the WRITES,
|
||||
and initializing them afterwards.
|
||||
|
||||
### compare ###
|
||||
|
||||
compare <dest-memory-location>, <src-memory-location>
|
||||
|
||||
Subtracts the contents of src from dest, discarding the result
|
||||
and only setting the resulting flags. Differs from `cmp` in
|
||||
that it is able to work on more general types of data (notably,
|
||||
words) and it trashes the `a` register.
|
||||
|
||||
* It is illegal if src OR dest is uninitialized.
|
||||
|
||||
Affects n, z, and c flags, requiring that they be in the WRITES,
|
||||
and initializing them afterwards.
|
||||
|
||||
### and, or, xor ###
|
||||
|
||||
and <dest-memory-location>, <src-memory-location>
|
||||
|
@ -508,6 +508,12 @@ class Analyzer(object):
|
||||
else:
|
||||
self.assert_type(TYPE_BYTE, src, dest)
|
||||
context.set_written(FLAG_Z, FLAG_N, FLAG_C)
|
||||
elif opcode == 'compare':
|
||||
context.assert_meaningful(src, dest)
|
||||
self.assert_type(TYPE_WORD, src, dest)
|
||||
context.set_touched(REG_A)
|
||||
context.set_unmeaningful(REG_A)
|
||||
context.set_written(FLAG_Z, FLAG_N, FLAG_C)
|
||||
elif opcode == 'and':
|
||||
if isinstance(src, IndexedRef):
|
||||
context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
|
||||
|
@ -325,6 +325,8 @@ class Compiler(object):
|
||||
raise UnsupportedOpcodeError(instr)
|
||||
elif opcode == 'cmp':
|
||||
self.compile_cmp(instr, instr.src, instr.dest)
|
||||
elif opcode == 'compare':
|
||||
self.compile_compare(instr, instr.src, instr.dest)
|
||||
elif opcode in ('and', 'or', 'xor',):
|
||||
cls = {
|
||||
'and': AND,
|
||||
@ -406,6 +408,23 @@ class Compiler(object):
|
||||
else:
|
||||
self.emitter.emit(cls(Absolute(self.get_label(src.name))))
|
||||
|
||||
def compile_compare(self, instr, src, dest):
|
||||
"""`instr` is only for reporting purposes"""
|
||||
if not isinstance(src, LocationRef) or not isinstance(dest, LocationRef):
|
||||
raise UnsupportedOpcodeError(instr)
|
||||
if src.type != TYPE_WORD or dest.type != TYPE_WORD:
|
||||
raise UnsupportedOpcodeError(instr)
|
||||
|
||||
src_label = self.get_label(src.name)
|
||||
dest_label = self.get_label(dest.name)
|
||||
self.emitter.emit(LDA(Absolute(src_label)))
|
||||
self.emitter.emit(CMP(Absolute(dest_label)))
|
||||
end_label = Label('end_label')
|
||||
self.emitter.emit(BNE(Relative(end_label)))
|
||||
self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
|
||||
self.emitter.emit(CMP(Absolute(Offset(dest_label, 1))))
|
||||
self.emitter.resolve_label(end_label)
|
||||
|
||||
def compile_inc(self, instr, dest):
|
||||
"""`instr` is only for reporting purposes"""
|
||||
if dest == REG_X:
|
||||
|
@ -463,6 +463,14 @@ class Parser(object):
|
||||
dest = self.indlocexpr()
|
||||
instr = SingleOp(self.scanner.line_number, opcode=opcode, dest=dest, src=src)
|
||||
return instr
|
||||
elif self.scanner.token in ("compare",):
|
||||
opcode = self.scanner.token
|
||||
self.scanner.scan()
|
||||
dest = self.locexpr()
|
||||
self.scanner.expect(',')
|
||||
src = self.indexed_locexpr()
|
||||
instr = SingleOp(self.scanner.line_number, opcode=opcode, dest=dest, src=src)
|
||||
return instr
|
||||
elif self.scanner.consume("with"):
|
||||
self.scanner.expect("interrupts")
|
||||
self.scanner.expect("off")
|
||||
|
@ -1118,6 +1118,54 @@ Some rudimentary tests for `cmp`.
|
||||
| }
|
||||
? UnmeaningfulReadError: a
|
||||
|
||||
### compare ###
|
||||
|
||||
Some rudimentary tests for `compare`.
|
||||
|
||||
| word za
|
||||
| word zb
|
||||
|
|
||||
| define main routine
|
||||
| inputs za, zb
|
||||
| trashes a, z, c, n
|
||||
| {
|
||||
| compare za, zb
|
||||
| }
|
||||
= ok
|
||||
|
||||
| word za
|
||||
| word zb
|
||||
|
|
||||
| define main routine
|
||||
| inputs za, zb
|
||||
| trashes a, z, n
|
||||
| {
|
||||
| compare za, zb
|
||||
| }
|
||||
? ForbiddenWriteError: c
|
||||
|
||||
| word za
|
||||
| word zb
|
||||
|
|
||||
| define main routine
|
||||
| inputs za, zb
|
||||
| trashes z, c, n
|
||||
| {
|
||||
| compare za, zb
|
||||
| }
|
||||
? ForbiddenWriteError: a
|
||||
|
||||
| word za
|
||||
| word zb
|
||||
|
|
||||
| define main routine
|
||||
| inputs za
|
||||
| trashes z, c, n
|
||||
| {
|
||||
| compare za, zb
|
||||
| }
|
||||
? UnmeaningfulReadError: zb
|
||||
|
||||
### and ###
|
||||
|
||||
Some rudimentary tests for `and`.
|
||||
|
@ -385,6 +385,26 @@ Some instructions on tables. (3/3)
|
||||
= $081B DEC $081F,X
|
||||
= $081E RTS
|
||||
|
||||
Compiling `compare`.
|
||||
|
||||
| word za @ 60001
|
||||
| word zb : 3003
|
||||
|
|
||||
| define main routine
|
||||
| inputs za, zb
|
||||
| trashes a, z, c, n
|
||||
| {
|
||||
| compare za, zb
|
||||
| }
|
||||
= $080D LDA $081C
|
||||
= $0810 CMP $EA61
|
||||
= $0813 BNE $081B
|
||||
= $0815 LDA $081D
|
||||
= $0818 CMP $EA62
|
||||
= $081B RTS
|
||||
= $081C .byte $BB
|
||||
= $081D .byte $0B
|
||||
|
||||
Compiling `if`.
|
||||
|
||||
| define main routine
|
||||
|
@ -586,6 +586,16 @@ Buffers and pointers.
|
||||
| }
|
||||
= ok
|
||||
|
||||
Comparison of words.
|
||||
|
||||
| word za
|
||||
| word zb
|
||||
|
|
||||
| define main routine inputs za, zb {
|
||||
| compare za, zb
|
||||
| }
|
||||
= ok
|
||||
|
||||
Routines can be defined in a new style.
|
||||
|
||||
| typedef routine
|
||||
|
Loading…
x
Reference in New Issue
Block a user