git @ Cat's Eye Technologies SixtyPical / 75449d7
Merge pull request #18 from catseye/more-modes-on-add-and-sub More modes on add and sub Chris Pressey authored 2 years ago GitHub committed 2 years ago
6 changed file(s) with 254 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
1414 * `cmp` instruction can now perform a 16-bit unsigned comparison
1515 of `word` memory locations and `word` literals (at the cost of
1616 trashing the `a` register.)
17 * `add` (resp. `sub`) now support adding (resp. subtracting) a
18 byte location or a byte literal from a byte location.
1719 * Fixed pathological memory use in the lexical scanner - should
1820 be much less inefficient now when parsing large source files.
1921 * Reorganized the examples in `eg/rudiments/` to make them
332332
333333 Adds the contents of src to dest and stores the result in dest.
334334
335 * It is illegal if src OR dest OR c is uninitialized.
335 * It is illegal if src OR dest OR `c` is uninitialized.
336336 * It is illegal if dest is read-only.
337 * It is illegal if dest is `x` or `y`.
337338 * It is illegal if dest does not occur in the WRITES of the current routine.
338339
339340 Affects n, z, c, and v flags, requiring that they be in the WRITES,
344345 In addition, if dest is of `word` type, then src must also be of `word`
345346 type, and in this case this instruction trashes the `a` register.
346347
348 In fact, this instruction trashes the `a` register in all cases except
349 when the dest is `a`.
350
347351 NOTE: If dest is a pointer, the addition does not check if the result of
348352 the pointer arithmetic continues to be valid (within a buffer) or not.
349353
366370
367371 Subtracts the contents of src from dest and stores the result in dest.
368372
369 * It is illegal if src OR dest OR c is uninitialized.
373 * It is illegal if src OR dest OR `c` is uninitialized.
370374 * It is illegal if dest is read-only.
375 * It is illegal if dest is `x` or `y`.
371376 * It is illegal if dest does not occur in the WRITES of the current routine.
372377
373378 Affects n, z, c, and v flags, requiring that they be in the WRITES,
377382
378383 In addition, if dest is of `word` type, then src must also be of `word`
379384 type, and in this case this instruction trashes the `a` register.
385
386 In fact, this instruction trashes the `a` register in all cases except
387 when the dest is `a`.
380388
381389 ### dec ###
382390
532532 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
533533 elif src.type == TYPE_BYTE:
534534 self.assert_type(TYPE_BYTE, src, dest)
535 if dest != REG_A:
536 context.set_touched(REG_A)
537 context.set_unmeaningful(REG_A)
535538 else:
536539 self.assert_type(TYPE_WORD, src)
537540 if dest.type == TYPE_WORD:
550553 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
551554 elif src.type == TYPE_BYTE:
552555 self.assert_type(TYPE_BYTE, src, dest)
556 if dest != REG_A:
557 context.set_touched(REG_A)
558 context.set_unmeaningful(REG_A)
553559 else:
554560 self.assert_type(TYPE_WORD, src, dest)
555561 context.set_touched(REG_A)
243243 raise UnsupportedOpcodeError(instr)
244244 self.emitter.emit(op_cls(operand))
245245 elif opcode == 'add':
246 if dest == REG_X or dest == REG_Y:
247 raise UnsupportedOpcodeError(instr)
246248 if dest == REG_A:
247249 if isinstance(src, ConstantRef):
248250 self.emitter.emit(ADC(Immediate(Byte(src.value))))
250252 self.emitter.emit(ADC(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
251253 else:
252254 self.emitter.emit(ADC(Absolute(self.get_label(src.name))))
255 elif isinstance(dest, LocationRef) and src.type == TYPE_BYTE and dest.type == TYPE_BYTE:
256 if isinstance(src, ConstantRef):
257 dest_label = self.get_label(dest.name)
258 self.emitter.emit(LDA(Absolute(dest_label)))
259 self.emitter.emit(ADC(Immediate(Byte(src.low_byte()))))
260 self.emitter.emit(STA(Absolute(dest_label)))
261 elif isinstance(src, LocationRef):
262 src_label = self.get_label(src.name)
263 dest_label = self.get_label(dest.name)
264 self.emitter.emit(LDA(Absolute(dest_label)))
265 self.emitter.emit(ADC(Absolute(src_label)))
266 self.emitter.emit(STA(Absolute(dest_label)))
267 else:
268 raise UnsupportedOpcodeError(instr)
253269 elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
254270 if isinstance(src, ConstantRef):
255271 dest_label = self.get_label(dest.name)
293309 else:
294310 raise UnsupportedOpcodeError(instr)
295311 elif opcode == 'sub':
312 if dest == REG_X or dest == REG_Y:
313 raise UnsupportedOpcodeError(instr)
296314 if dest == REG_A:
297315 if isinstance(src, ConstantRef):
298316 self.emitter.emit(SBC(Immediate(Byte(src.value))))
300318 self.emitter.emit(SBC(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
301319 else:
302320 self.emitter.emit(SBC(Absolute(self.get_label(src.name))))
321 elif isinstance(dest, LocationRef) and src.type == TYPE_BYTE and dest.type == TYPE_BYTE:
322 if isinstance(src, ConstantRef):
323 dest_label = self.get_label(dest.name)
324 self.emitter.emit(LDA(Absolute(dest_label)))
325 self.emitter.emit(SBC(Immediate(Byte(src.low_byte()))))
326 self.emitter.emit(STA(Absolute(dest_label)))
327 elif isinstance(src, LocationRef):
328 src_label = self.get_label(src.name)
329 dest_label = self.get_label(dest.name)
330 self.emitter.emit(LDA(Absolute(dest_label)))
331 self.emitter.emit(SBC(Absolute(src_label)))
332 self.emitter.emit(STA(Absolute(dest_label)))
333 else:
334 raise UnsupportedOpcodeError(instr)
303335 elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
304336 if isinstance(src, ConstantRef):
305337 dest_label = self.get_label(dest.name)
851851 | }
852852 ? ForbiddenWriteError: a
853853
854 You can `add` a byte constant to a byte memory location.
855
856 | byte lives
857 | define main routine
858 | inputs a, lives
859 | outputs lives
860 | trashes a, c, z, v, n
861 | {
862 | st off, c
863 | add lives, 3
864 | }
865 = ok
866
867 `add`ing a byte constant to a byte memory location trashes `a`.
868
869 | byte lives
870 | define main routine
871 | inputs a, lives
872 | outputs a, lives
873 | trashes c, z, v, n
874 | {
875 | st off, c
876 | add lives, 3
877 | }
878 ? UnmeaningfulOutputError: a
879
880 You can `add` a byte memory location to another byte memory location.
881 This trashes `a`.
882
883 | byte lives
884 | byte extra
885 | define main routine
886 | inputs a, lives, extra
887 | outputs lives
888 | trashes a, c, z, v, n
889 | {
890 | st off, c
891 | add lives, extra
892 | }
893 = ok
894
895 | byte lives
896 | byte extra
897 | define main routine
898 | inputs a, lives, extra
899 | outputs a, lives
900 | trashes c, z, v, n
901 | {
902 | st off, c
903 | add lives, extra
904 | }
905 ? UnmeaningfulOutputError: a
906
854907 You can `add` a word constant to a word memory location.
855908
856909 | word score
9941047 | sub a, 0
9951048 | }
9961049 ? ForbiddenWriteError: a
1050
1051 You can `sub` a byte constant from a byte memory location.
1052
1053 | byte lives
1054 | define main routine
1055 | inputs a, lives
1056 | outputs lives
1057 | trashes a, c, z, v, n
1058 | {
1059 | st on, c
1060 | sub lives, 3
1061 | }
1062 = ok
1063
1064 `sub`ing a byte constant from a byte memory location trashes `a`.
1065
1066 | byte lives
1067 | define main routine
1068 | inputs a, lives
1069 | outputs a, lives
1070 | trashes c, z, v, n
1071 | {
1072 | st on, c
1073 | sub lives, 3
1074 | }
1075 ? UnmeaningfulOutputError: a
1076
1077 You can `sub` a byte memory location from another byte memory location.
1078 This trashes `a`.
1079
1080 | byte lives
1081 | byte extra
1082 | define main routine
1083 | inputs a, lives, extra
1084 | outputs lives
1085 | trashes a, c, z, v, n
1086 | {
1087 | st on, c
1088 | sub lives, extra
1089 | }
1090 = ok
1091
1092 | byte lives
1093 | byte extra
1094 | define main routine
1095 | inputs a, lives, extra
1096 | outputs a, lives
1097 | trashes c, z, v, n
1098 | {
1099 | st on, c
1100 | sub lives, extra
1101 | }
1102 ? UnmeaningfulOutputError: a
9971103
9981104 You can `sub` a word constant from a word memory location.
9991105
10241024 = $0842 JMP ($0846)
10251025 = $0845 RTS
10261026
1027 ### add, sub
1028
1029 Various modes of `add`.
1030
1031 | byte lives
1032 | byte extra
1033 | word score
1034 | word bonus
1035 | define main routine
1036 | inputs lives, score, extra, bonus
1037 | outputs lives, score
1038 | trashes a, x, y, c, z, v, n
1039 | {
1040 | ld a, 0
1041 | ld x, 0
1042 | ld y, 0
1043 | st off, c
1044 | add a, 7
1045 | add a, lives
1046 | add lives, 2
1047 | add lives, extra
1048 | add score, 1999
1049 | add score, bonus
1050 | }
1051 = $080D LDA #$00
1052 = $080F LDX #$00
1053 = $0811 LDY #$00
1054 = $0813 CLC
1055 = $0814 ADC #$07
1056 = $0816 ADC $084D
1057 = $0819 LDA $084D
1058 = $081C ADC #$02
1059 = $081E STA $084D
1060 = $0821 LDA $084D
1061 = $0824 ADC $084E
1062 = $0827 STA $084D
1063 = $082A LDA $084F
1064 = $082D ADC #$CF
1065 = $082F STA $084F
1066 = $0832 LDA $0850
1067 = $0835 ADC #$07
1068 = $0837 STA $0850
1069 = $083A LDA $084F
1070 = $083D ADC $0851
1071 = $0840 STA $084F
1072 = $0843 LDA $0850
1073 = $0846 ADC $0852
1074 = $0849 STA $0850
1075 = $084C RTS
1076
1077 Various modes of `sub`.
1078
1079 | byte lives
1080 | byte extra
1081 | word score
1082 | word bonus
1083 | define main routine
1084 | inputs lives, score, extra, bonus
1085 | outputs lives, score
1086 | trashes a, x, y, c, z, v, n
1087 | {
1088 | ld a, 0
1089 | ld x, 0
1090 | ld y, 0
1091 | st on, c
1092 | sub a, 7
1093 | sub a, lives
1094 | sub lives, 2
1095 | sub lives, extra
1096 | sub score, 1999
1097 | sub score, bonus
1098 | }
1099 = $080D LDA #$00
1100 = $080F LDX #$00
1101 = $0811 LDY #$00
1102 = $0813 SEC
1103 = $0814 SBC #$07
1104 = $0816 SBC $084D
1105 = $0819 LDA $084D
1106 = $081C SBC #$02
1107 = $081E STA $084D
1108 = $0821 LDA $084D
1109 = $0824 SBC $084E
1110 = $0827 STA $084D
1111 = $082A LDA $084F
1112 = $082D SBC #$CF
1113 = $082F STA $084F
1114 = $0832 LDA $0850
1115 = $0835 SBC #$07
1116 = $0837 STA $0850
1117 = $083A LDA $084F
1118 = $083D SBC $0851
1119 = $0840 STA $084F
1120 = $0843 LDA $0850
1121 = $0846 SBC $0852
1122 = $0849 STA $0850
1123 = $084C RTS
1124
10271125 ### word operations
10281126
10291127 Adding a constant word to a word memory location.