git @ Cat's Eye Technologies SixtyPical / e74c7f2
Initial attempt at 16-bit compare. Not super well tested yet. Chris Pressey 3 years ago
7 changed file(s) with 128 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
287287
288288 copy <src-memory-location>, <dest-memory-location>
289289
290 Reads from src and writes to dest. Differs from `st` in that is able to
291 copy more general types of data (for example, vectors,) and it trashes the
292 `z` and `n` flags and the `a` register.
290 Reads from src and writes to dest. Differs from `ld` and `st` in that
291 it is able to copy more general types of data (for example, vectors,)
292 and it trashes the `z` and `n` flags and the `a` register.
293293
294294 * It is illegal if dest is read-only.
295295 * It is illegal if dest does not occur in the WRITES of the current routine.
394394
395395 Subtracts the contents of src from dest (without considering carry) but
396396 does not store the result anywhere, only sets the resulting flags.
397
398 * It is illegal if src OR dest is uninitialized.
399
400 Affects n, z, and c flags, requiring that they be in the WRITES,
401 and initializing them afterwards.
402
403 ### compare ###
404
405 compare <dest-memory-location>, <src-memory-location>
406
407 Subtracts the contents of src from dest, discarding the result
408 and only setting the resulting flags. Differs from `cmp` in
409 that it is able to work on more general types of data (notably,
410 words) and it trashes the `a` register.
397411
398412 * It is illegal if src OR dest is uninitialized.
399413
506506 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
507507 else:
508508 self.assert_type(TYPE_BYTE, src, dest)
509 context.set_written(FLAG_Z, FLAG_N, FLAG_C)
510 elif opcode == 'compare':
511 context.assert_meaningful(src, dest)
512 self.assert_type(TYPE_WORD, src, dest)
513 context.set_touched(REG_A)
514 context.set_unmeaningful(REG_A)
509515 context.set_written(FLAG_Z, FLAG_N, FLAG_C)
510516 elif opcode == 'and':
511517 if isinstance(src, IndexedRef):
324324 raise UnsupportedOpcodeError(instr)
325325 elif opcode == 'cmp':
326326 self.compile_cmp(instr, instr.src, instr.dest)
327 elif opcode == 'compare':
328 self.compile_compare(instr, instr.src, instr.dest)
327329 elif opcode in ('and', 'or', 'xor',):
328330 cls = {
329331 'and': AND,
404406 self.emitter.emit(cls(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
405407 else:
406408 self.emitter.emit(cls(Absolute(self.get_label(src.name))))
409
410 def compile_compare(self, instr, src, dest):
411 """`instr` is only for reporting purposes"""
412 if not isinstance(src, LocationRef) or not isinstance(dest, LocationRef):
413 raise UnsupportedOpcodeError(instr)
414 if src.type != TYPE_WORD or dest.type != TYPE_WORD:
415 raise UnsupportedOpcodeError(instr)
416
417 src_label = self.get_label(src.name)
418 dest_label = self.get_label(dest.name)
419 self.emitter.emit(LDA(Absolute(src_label)))
420 self.emitter.emit(CMP(Absolute(dest_label)))
421 end_label = Label('end_label')
422 self.emitter.emit(BNE(Relative(end_label)))
423 self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
424 self.emitter.emit(CMP(Absolute(Offset(dest_label, 1))))
425 self.emitter.resolve_label(end_label)
407426
408427 def compile_inc(self, instr, dest):
409428 """`instr` is only for reporting purposes"""
462462 dest = self.indlocexpr()
463463 instr = SingleOp(self.scanner.line_number, opcode=opcode, dest=dest, src=src)
464464 return instr
465 elif self.scanner.token in ("compare",):
466 opcode = self.scanner.token
467 self.scanner.scan()
468 dest = self.locexpr()
469 self.scanner.expect(',')
470 src = self.indexed_locexpr()
471 instr = SingleOp(self.scanner.line_number, opcode=opcode, dest=dest, src=src)
472 return instr
465473 elif self.scanner.consume("with"):
466474 self.scanner.expect("interrupts")
467475 self.scanner.expect("off")
11161116 | cmp a, 4
11171117 | }
11181118 ? UnmeaningfulReadError: a
1119
1120 ### compare ###
1121
1122 Some rudimentary tests for `compare`.
1123
1124 | word za
1125 | word zb
1126 |
1127 | define main routine
1128 | inputs za, zb
1129 | trashes a, z, c, n
1130 | {
1131 | compare za, zb
1132 | }
1133 = ok
1134
1135 | word za
1136 | word zb
1137 |
1138 | define main routine
1139 | inputs za, zb
1140 | trashes a, z, n
1141 | {
1142 | compare za, zb
1143 | }
1144 ? ForbiddenWriteError: c
1145
1146 | word za
1147 | word zb
1148 |
1149 | define main routine
1150 | inputs za, zb
1151 | trashes z, c, n
1152 | {
1153 | compare za, zb
1154 | }
1155 ? ForbiddenWriteError: a
1156
1157 | word za
1158 | word zb
1159 |
1160 | define main routine
1161 | inputs za
1162 | trashes z, c, n
1163 | {
1164 | compare za, zb
1165 | }
1166 ? UnmeaningfulReadError: zb
11191167
11201168 ### and ###
11211169
384384 = $081B DEC $081F,X
385385 = $081E RTS
386386
387 Compiling `compare`.
388
389 | word za @ 60001
390 | word zb : 3003
391 |
392 | define main routine
393 | inputs za, zb
394 | trashes a, z, c, n
395 | {
396 | compare za, zb
397 | }
398 = $080D LDA $081C
399 = $0810 CMP $EA61
400 = $0813 BNE $081B
401 = $0815 LDA $081D
402 = $0818 CMP $EA62
403 = $081B RTS
404 = $081C .byte $BB
405 = $081D .byte $0B
406
387407 Compiling `if`.
388408
389409 | define main routine
585585 | }
586586 = ok
587587
588 Comparison of words.
589
590 | word za
591 | word zb
592 |
593 | define main routine inputs za, zb {
594 | compare za, zb
595 | }
596 = ok
597
588598 Routines can be defined in a new style.
589599
590600 | typedef routine