1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-06-01 12:41:30 +00:00

Initial attempt at 16-bit compare. Not super well tested yet.

This commit is contained in:
Chris Pressey 2018-11-23 22:09:28 +00:00
parent 0429e4bd90
commit e74c7f2b31
7 changed files with 128 additions and 3 deletions

View File

@ -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>

View File

@ -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)

View File

@ -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:

View File

@ -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")

View File

@ -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`.

View File

@ -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

View File

@ -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