@jhlagado/azm 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/README.md +239 -76
  2. package/dist/src/api-artifacts.d.ts +20 -0
  3. package/dist/src/api-artifacts.js +165 -0
  4. package/dist/src/api-compile.d.ts +8 -2
  5. package/dist/src/api-compile.js +55 -227
  6. package/dist/src/api-register-contracts.d.ts +9 -0
  7. package/dist/src/api-register-contracts.js +77 -0
  8. package/dist/src/api-tooling.d.ts +2 -2
  9. package/dist/src/api-tooling.js +1 -1
  10. package/dist/src/assembly/address-planning.d.ts +1 -2
  11. package/dist/src/assembly/address-planning.js +119 -218
  12. package/dist/src/assembly/address-symbols.d.ts +12 -0
  13. package/dist/src/assembly/address-symbols.js +118 -0
  14. package/dist/src/assembly/assemble-program.js +5 -0
  15. package/dist/src/assembly/fixup-emission.js +30 -48
  16. package/dist/src/assembly/import-visibility.d.ts +3 -0
  17. package/dist/src/assembly/import-visibility.js +204 -0
  18. package/dist/src/assembly/program-emission.js +163 -164
  19. package/dist/src/cli/artifact-files.d.ts +15 -0
  20. package/dist/src/cli/artifact-files.js +86 -0
  21. package/dist/src/cli/parse-args.d.ts +6 -5
  22. package/dist/src/cli/parse-args.js +162 -136
  23. package/dist/src/cli/run.js +4 -1
  24. package/dist/src/cli/usage.d.ts +1 -0
  25. package/dist/src/cli/usage.js +33 -0
  26. package/dist/src/cli/write-artifacts.js +18 -91
  27. package/dist/src/core/compile.js +51 -274
  28. package/dist/src/core/conditional-assembly.d.ts +6 -0
  29. package/dist/src/core/conditional-assembly.js +181 -0
  30. package/dist/src/expansion/op-constant-expression.d.ts +3 -0
  31. package/dist/src/expansion/op-constant-expression.js +52 -0
  32. package/dist/src/expansion/op-expand-selected.d.ts +5 -0
  33. package/dist/src/expansion/op-expand-selected.js +143 -0
  34. package/dist/src/expansion/op-expansion.d.ts +5 -53
  35. package/dist/src/expansion/op-expansion.js +85 -815
  36. package/dist/src/expansion/op-instruction-instantiation.d.ts +3 -0
  37. package/dist/src/expansion/op-instruction-instantiation.js +194 -0
  38. package/dist/src/expansion/op-local-labels.d.ts +8 -0
  39. package/dist/src/expansion/op-local-labels.js +166 -0
  40. package/dist/src/expansion/op-operand-splitting.d.ts +1 -0
  41. package/dist/src/expansion/op-operand-splitting.js +44 -0
  42. package/dist/src/expansion/op-operands.d.ts +53 -0
  43. package/dist/src/expansion/op-operands.js +66 -0
  44. package/dist/src/expansion/op-selection.d.ts +18 -0
  45. package/dist/src/expansion/op-selection.js +172 -0
  46. package/dist/src/index.d.ts +2 -1
  47. package/dist/src/index.js +1 -1
  48. package/dist/src/model/diagnostic.d.ts +4 -0
  49. package/dist/src/model/diagnostic.js +4 -0
  50. package/dist/src/node/source-host.js +40 -13
  51. package/dist/src/outputs/asm80-expression-evaluation.d.ts +10 -0
  52. package/dist/src/outputs/asm80-expression-evaluation.js +75 -0
  53. package/dist/src/outputs/asm80-expressions.d.ts +5 -0
  54. package/dist/src/outputs/asm80-expressions.js +47 -0
  55. package/dist/src/outputs/asm80-instruction-operands.d.ts +16 -0
  56. package/dist/src/outputs/asm80-instruction-operands.js +38 -0
  57. package/dist/src/outputs/asm80-instructions.d.ts +5 -0
  58. package/dist/src/outputs/asm80-instructions.js +272 -0
  59. package/dist/src/outputs/asm80-ld-operands.d.ts +10 -0
  60. package/dist/src/outputs/asm80-ld-operands.js +157 -0
  61. package/dist/src/outputs/asm80-strings.d.ts +4 -0
  62. package/dist/src/outputs/asm80-strings.js +14 -0
  63. package/dist/src/outputs/d8-files.d.ts +10 -0
  64. package/dist/src/outputs/d8-files.js +103 -0
  65. package/dist/src/outputs/d8-helpers.d.ts +21 -0
  66. package/dist/src/outputs/d8-helpers.js +136 -0
  67. package/dist/src/outputs/hex.js +26 -18
  68. package/dist/src/outputs/types.d.ts +16 -10
  69. package/dist/src/outputs/write-asm80.js +72 -597
  70. package/dist/src/outputs/write-d8.js +6 -216
  71. package/dist/src/register-contracts/accept-output.d.ts +2 -0
  72. package/dist/src/register-contracts/analyze-helpers.d.ts +29 -0
  73. package/dist/src/register-contracts/analyze-helpers.js +162 -0
  74. package/dist/src/{register-care → register-contracts}/analyze.d.ts +6 -6
  75. package/dist/src/register-contracts/analyze.js +73 -0
  76. package/dist/src/register-contracts/annotate.d.ts +11 -0
  77. package/dist/src/{register-care → register-contracts}/annotate.js +3 -3
  78. package/dist/src/register-contracts/annotations.d.ts +8 -0
  79. package/dist/src/{register-care → register-contracts}/annotations.js +3 -3
  80. package/dist/src/register-contracts/boundaryHints.d.ts +3 -0
  81. package/dist/src/register-contracts/boundaryHints.js +24 -0
  82. package/dist/src/register-contracts/carriers.d.ts +2 -0
  83. package/dist/src/register-contracts/constants.d.ts +4 -0
  84. package/dist/src/register-contracts/constants.js +51 -0
  85. package/dist/src/register-contracts/controlFlow.d.ts +5 -0
  86. package/dist/src/register-contracts/controlFlow.js +55 -0
  87. package/dist/src/register-contracts/fix.d.ts +11 -0
  88. package/dist/src/{register-care → register-contracts}/fix.js +47 -30
  89. package/dist/src/register-contracts/instruction-head.d.ts +2 -0
  90. package/dist/src/register-contracts/instruction-head.js +3 -0
  91. package/dist/src/register-contracts/instruction-operands.d.ts +3 -0
  92. package/dist/src/register-contracts/instruction-operands.js +101 -0
  93. package/dist/src/register-contracts/instruction-predicates.d.ts +6 -0
  94. package/dist/src/register-contracts/instruction-predicates.js +44 -0
  95. package/dist/src/register-contracts/interfaceContracts.d.ts +2 -0
  96. package/dist/src/register-contracts/interfaceContracts.js +68 -0
  97. package/dist/src/register-contracts/liveness.d.ts +3 -0
  98. package/dist/src/{register-care → register-contracts}/liveness.js +111 -79
  99. package/dist/src/register-contracts/operand-register-name.d.ts +2 -0
  100. package/dist/src/register-contracts/operand-register-name.js +13 -0
  101. package/dist/src/{register-care → register-contracts}/profiles.d.ts +5 -5
  102. package/dist/src/{register-care → register-contracts}/profiles.js +2 -2
  103. package/dist/src/register-contracts/programModel-boundaries.d.ts +6 -0
  104. package/dist/src/register-contracts/programModel-boundaries.js +64 -0
  105. package/dist/src/register-contracts/programModel-routines.d.ts +7 -0
  106. package/dist/src/register-contracts/programModel-routines.js +144 -0
  107. package/dist/src/register-contracts/programModel.d.ts +3 -0
  108. package/dist/src/register-contracts/programModel.js +14 -0
  109. package/dist/src/register-contracts/report.d.ts +5 -0
  110. package/dist/src/{register-care → register-contracts}/report.js +34 -17
  111. package/dist/src/register-contracts/routine-summaries.d.ts +6 -0
  112. package/dist/src/{register-care → register-contracts}/routine-summaries.js +11 -1
  113. package/dist/src/register-contracts/smartCommentBlocks.d.ts +5 -0
  114. package/dist/src/register-contracts/smartCommentBlocks.js +30 -0
  115. package/dist/src/register-contracts/smartCommentParsing.d.ts +3 -0
  116. package/dist/src/register-contracts/smartCommentParsing.js +80 -0
  117. package/dist/src/register-contracts/smartComments.d.ts +5 -0
  118. package/dist/src/register-contracts/smartComments.js +92 -0
  119. package/dist/src/register-contracts/summaries.d.ts +12 -0
  120. package/dist/src/{register-care → register-contracts}/summaries.js +7 -7
  121. package/dist/src/register-contracts/summary-boundary.d.ts +2 -0
  122. package/dist/src/register-contracts/summary-boundary.js +40 -0
  123. package/dist/src/register-contracts/summary-contract.d.ts +2 -0
  124. package/dist/src/register-contracts/summary-contract.js +45 -0
  125. package/dist/src/register-contracts/summary-result.d.ts +7 -0
  126. package/dist/src/register-contracts/summary-result.js +122 -0
  127. package/dist/src/register-contracts/summary-state.d.ts +23 -0
  128. package/dist/src/register-contracts/summary-state.js +88 -0
  129. package/dist/src/register-contracts/summary-token-transfer.d.ts +3 -0
  130. package/dist/src/register-contracts/summary-token-transfer.js +67 -0
  131. package/dist/src/register-contracts/summary.d.ts +3 -0
  132. package/dist/src/register-contracts/summary.js +266 -0
  133. package/dist/src/register-contracts/tooling.d.ts +57 -0
  134. package/dist/src/{register-care → register-contracts}/tooling.js +8 -6
  135. package/dist/src/register-contracts/types.d.ts +188 -0
  136. package/dist/src/semantics/binary-operators.d.ts +2 -0
  137. package/dist/src/semantics/binary-operators.js +15 -0
  138. package/dist/src/semantics/byte-functions.d.ts +2 -0
  139. package/dist/src/semantics/byte-functions.js +7 -0
  140. package/dist/src/semantics/constant-operator-types.d.ts +10 -0
  141. package/dist/src/semantics/constant-operator-types.js +1 -0
  142. package/dist/src/semantics/constant-operators.d.ts +3 -0
  143. package/dist/src/semantics/constant-operators.js +3 -0
  144. package/dist/src/semantics/diagnostics.d.ts +3 -0
  145. package/dist/src/semantics/diagnostics.js +10 -0
  146. package/dist/src/semantics/expression-evaluation.d.ts +11 -19
  147. package/dist/src/semantics/expression-evaluation.js +22 -334
  148. package/dist/src/semantics/layout-evaluation.d.ts +23 -0
  149. package/dist/src/semantics/layout-evaluation.js +202 -0
  150. package/dist/src/semantics/layout-format.d.ts +5 -0
  151. package/dist/src/semantics/layout-format.js +31 -0
  152. package/dist/src/semantics/layout-path.d.ts +24 -0
  153. package/dist/src/semantics/layout-path.js +58 -0
  154. package/dist/src/semantics/unary-operators.d.ts +2 -0
  155. package/dist/src/semantics/unary-operators.js +8 -0
  156. package/dist/src/source/line-comment-scanner.d.ts +1 -0
  157. package/dist/src/source/line-comment-scanner.js +51 -0
  158. package/dist/src/source/logical-lines.d.ts +3 -0
  159. package/dist/src/source/source-span.d.ts +2 -0
  160. package/dist/src/source/strip-line-comment.js +8 -44
  161. package/dist/src/syntax/directive-aliases.js +36 -22
  162. package/dist/src/syntax/expression-tokenizer.d.ts +30 -0
  163. package/dist/src/syntax/expression-tokenizer.js +310 -0
  164. package/dist/src/syntax/parse-directive-statement.d.ts +9 -0
  165. package/dist/src/syntax/parse-directive-statement.js +309 -0
  166. package/dist/src/syntax/parse-expression.d.ts +2 -2
  167. package/dist/src/syntax/parse-expression.js +7 -568
  168. package/dist/src/syntax/parse-layout-declarations.d.ts +9 -0
  169. package/dist/src/syntax/parse-layout-declarations.js +189 -0
  170. package/dist/src/syntax/parse-layout-expression.d.ts +5 -0
  171. package/dist/src/syntax/parse-layout-expression.js +175 -0
  172. package/dist/src/syntax/parse-line.js +21 -273
  173. package/dist/src/syntax/parse-token-expression.d.ts +3 -0
  174. package/dist/src/syntax/parse-token-expression.js +133 -0
  175. package/dist/src/tooling/api.js +1 -1
  176. package/dist/src/tooling/case-style.js +47 -30
  177. package/dist/src/z80/effect-groups.d.ts +38 -0
  178. package/dist/src/z80/effect-groups.js +265 -0
  179. package/dist/src/z80/effect-units.d.ts +18 -0
  180. package/dist/src/z80/effect-units.js +165 -0
  181. package/dist/src/z80/effects.d.ts +1 -1
  182. package/dist/src/z80/effects.js +94 -557
  183. package/dist/src/z80/encode-core.d.ts +2 -0
  184. package/dist/src/z80/encode-core.js +42 -0
  185. package/dist/src/z80/encode-ld-helpers.d.ts +25 -0
  186. package/dist/src/z80/encode-ld-helpers.js +172 -0
  187. package/dist/src/z80/encode-ld.d.ts +2 -0
  188. package/dist/src/z80/encode-ld.js +285 -0
  189. package/dist/src/z80/encode.js +190 -542
  190. package/dist/src/z80/ld-support.d.ts +3 -0
  191. package/dist/src/z80/ld-support.js +146 -0
  192. package/dist/src/z80/operand-split-state.d.ts +8 -0
  193. package/dist/src/z80/operand-split-state.js +46 -0
  194. package/dist/src/z80/operand-split.d.ts +1 -0
  195. package/dist/src/z80/operand-split.js +13 -0
  196. package/dist/src/z80/parse-basic.d.ts +4 -0
  197. package/dist/src/z80/parse-basic.js +39 -0
  198. package/dist/src/z80/parse-branch.d.ts +4 -0
  199. package/dist/src/z80/parse-branch.js +218 -0
  200. package/dist/src/z80/parse-conditions.d.ts +6 -0
  201. package/dist/src/z80/parse-conditions.js +10 -0
  202. package/dist/src/z80/parse-exchange.d.ts +2 -0
  203. package/dist/src/z80/parse-exchange.js +30 -0
  204. package/dist/src/z80/parse-instruction.js +224 -1010
  205. package/dist/src/z80/parse-io-control.d.ts +5 -0
  206. package/dist/src/z80/parse-io-control.js +108 -0
  207. package/dist/src/z80/parse-ld.d.ts +2 -0
  208. package/dist/src/z80/parse-ld.js +83 -0
  209. package/dist/src/z80/parse-operands.d.ts +41 -0
  210. package/dist/src/z80/parse-operands.js +259 -0
  211. package/docs/codebase/01-orientation-and-repository-layout.md +192 -0
  212. package/docs/codebase/02-source-loading-and-parsing.md +263 -0
  213. package/docs/codebase/03-assembly-and-z80-emission.md +251 -0
  214. package/docs/codebase/04-ops-and-register-contracts.md +237 -0
  215. package/docs/codebase/05-interfaces-and-output-artifacts.md +253 -0
  216. package/docs/codebase/06-verification-and-maintenance.md +202 -0
  217. package/docs/codebase/appendices/a-directory-file-reference.md +253 -0
  218. package/docs/codebase/appendices/b-compile-flow-reference.md +103 -0
  219. package/docs/codebase/appendices/c-public-surface-reference.md +106 -0
  220. package/docs/codebase/appendices/index.md +16 -0
  221. package/docs/codebase/index.md +46 -0
  222. package/package.json +2 -3
  223. package/dist/src/register-care/accept-output.d.ts +0 -2
  224. package/dist/src/register-care/analyze.js +0 -166
  225. package/dist/src/register-care/annotate.d.ts +0 -11
  226. package/dist/src/register-care/annotations.d.ts +0 -8
  227. package/dist/src/register-care/boundaryHints.d.ts +0 -3
  228. package/dist/src/register-care/boundaryHints.js +0 -80
  229. package/dist/src/register-care/carriers.d.ts +0 -2
  230. package/dist/src/register-care/controlFlow.d.ts +0 -5
  231. package/dist/src/register-care/controlFlow.js +0 -38
  232. package/dist/src/register-care/fix.d.ts +0 -11
  233. package/dist/src/register-care/instruction-shape.d.ts +0 -11
  234. package/dist/src/register-care/instruction-shape.js +0 -129
  235. package/dist/src/register-care/liveness.d.ts +0 -3
  236. package/dist/src/register-care/programModel.d.ts +0 -3
  237. package/dist/src/register-care/programModel.js +0 -266
  238. package/dist/src/register-care/report.d.ts +0 -5
  239. package/dist/src/register-care/routine-summaries.d.ts +0 -6
  240. package/dist/src/register-care/smartComments.d.ts +0 -5
  241. package/dist/src/register-care/smartComments.js +0 -243
  242. package/dist/src/register-care/summaries.d.ts +0 -12
  243. package/dist/src/register-care/summary.d.ts +0 -3
  244. package/dist/src/register-care/summary.js +0 -474
  245. package/dist/src/register-care/tooling.d.ts +0 -43
  246. package/dist/src/register-care/types.d.ts +0 -172
  247. package/docs/reference/cli.md +0 -151
  248. package/docs/reference/tooling-api.md +0 -316
  249. /package/dist/src/{register-care → register-contracts}/accept-output.js +0 -0
  250. /package/dist/src/{register-care → register-contracts}/carriers.js +0 -0
  251. /package/dist/src/{register-care → register-contracts}/sourceText.d.ts +0 -0
  252. /package/dist/src/{register-care → register-contracts}/sourceText.js +0 -0
  253. /package/dist/src/{register-care → register-contracts}/types.js +0 -0
@@ -0,0 +1,265 @@
1
+ import { BIT_FLAG_WRITES, FLAG_WRITES, INC_DEC_FLAG_WRITES, ROTATE_SHIFT_FLAG_WRITES, STACK_POINTER_UNITS, baseEffect, concatUnique, operandReads, operandWrites, reg16Units, reg8Units, regHalfUnits, unknownEffect, } from './effect-units.js';
2
+ export function callControl(target, conditional) {
3
+ return target === undefined
4
+ ? { kind: 'call', conditional }
5
+ : { kind: 'call', target, conditional };
6
+ }
7
+ export function rstControl(vector) {
8
+ return vector === undefined ? { kind: 'rst' } : { kind: 'rst', vector };
9
+ }
10
+ export function jumpControl(target, conditional) {
11
+ return target === undefined
12
+ ? { kind: 'jump', conditional }
13
+ : { kind: 'jump', target, conditional };
14
+ }
15
+ export function controlEffect(control, reads = []) {
16
+ return {
17
+ ...baseEffect(),
18
+ reads,
19
+ control,
20
+ };
21
+ }
22
+ export function stackControlEffect(control, reads = []) {
23
+ return {
24
+ ...controlEffect(control, reads),
25
+ writes: STACK_POINTER_UNITS,
26
+ stack: { kind: 'unknown' },
27
+ };
28
+ }
29
+ export function ldEffect(instruction) {
30
+ const srcReads = operandReads(instruction.source);
31
+ if (srcReads === undefined)
32
+ return unknownEffect();
33
+ const dstWrites = operandWrites(instruction.target);
34
+ if (instruction.target.kind === 'reg8' || instruction.target.kind === 'reg16') {
35
+ if (dstWrites === undefined)
36
+ return unknownEffect();
37
+ return {
38
+ ...baseEffect(),
39
+ reads: srcReads,
40
+ writes: dstWrites,
41
+ };
42
+ }
43
+ if (instruction.target.kind === 'reg-index16' ||
44
+ instruction.target.kind === 'reg-half-index') {
45
+ if (dstWrites === undefined)
46
+ return unknownEffect();
47
+ return {
48
+ ...baseEffect(),
49
+ reads: srcReads,
50
+ writes: dstWrites,
51
+ };
52
+ }
53
+ if (instruction.target.kind === 'reg-indirect' || instruction.target.kind === 'indexed') {
54
+ const dstReads = operandReads(instruction.target);
55
+ if (dstReads === undefined)
56
+ return unknownEffect();
57
+ return {
58
+ ...baseEffect(),
59
+ reads: concatUnique(dstReads, srcReads),
60
+ };
61
+ }
62
+ if (instruction.target.kind === 'mem-abs') {
63
+ return {
64
+ ...baseEffect(),
65
+ reads: srcReads,
66
+ };
67
+ }
68
+ return unknownEffect();
69
+ }
70
+ export function incDecEffect(instruction) {
71
+ const operand = instruction.operand;
72
+ if (operand.kind === 'reg8') {
73
+ const units = reg8Units(operand.register);
74
+ return {
75
+ ...baseEffect(),
76
+ reads: units,
77
+ writes: concatUnique(units, INC_DEC_FLAG_WRITES),
78
+ };
79
+ }
80
+ if (operand.kind === 'reg16') {
81
+ const units = reg16Units(operand.register);
82
+ return {
83
+ ...baseEffect(),
84
+ reads: units,
85
+ writes: units,
86
+ };
87
+ }
88
+ if (operand.kind === 'reg-half-index') {
89
+ const units = regHalfUnits(operand.register);
90
+ return {
91
+ ...baseEffect(),
92
+ reads: units,
93
+ writes: concatUnique(units, INC_DEC_FLAG_WRITES),
94
+ };
95
+ }
96
+ const reads = operandReads(operand);
97
+ if (reads === undefined)
98
+ return unknownEffect();
99
+ return {
100
+ ...baseEffect(),
101
+ reads,
102
+ writes: INC_DEC_FLAG_WRITES,
103
+ };
104
+ }
105
+ export function aluEffect(instruction) {
106
+ if (instruction.mnemonic === 'add' &&
107
+ 'target' in instruction &&
108
+ (instruction.target.kind === 'reg16' || instruction.target.kind === 'reg-index16')) {
109
+ return wideAluEffect(instruction, []);
110
+ }
111
+ if (instruction.mnemonic === 'adc' &&
112
+ 'target' in instruction &&
113
+ (instruction.target.kind === 'reg16' || instruction.target.kind === 'reg-index16')) {
114
+ return wideAluEffect(instruction, ['carry']);
115
+ }
116
+ if (instruction.mnemonic === 'sbc' &&
117
+ 'target' in instruction &&
118
+ (instruction.target.kind === 'reg16' || instruction.target.kind === 'reg-index16')) {
119
+ return wideAluEffect(instruction, ['carry']);
120
+ }
121
+ if (!('source' in instruction))
122
+ return unknownEffect();
123
+ const source = instruction.source;
124
+ const sourceReads = aluSourceReads(source);
125
+ const xorSelfZero = instruction.mnemonic === 'xor' &&
126
+ source.kind === 'reg8' &&
127
+ source.register === 'a';
128
+ const reads = xorSelfZero ? [] : concatUnique(['A'], sourceReads);
129
+ const carryReads = instruction.mnemonic === 'adc' || instruction.mnemonic === 'sbc' ? ['carry'] : [];
130
+ if (instruction.mnemonic === 'cp') {
131
+ return {
132
+ ...baseEffect(),
133
+ reads: concatUnique(reads, carryReads),
134
+ writes: FLAG_WRITES,
135
+ };
136
+ }
137
+ return {
138
+ ...baseEffect(),
139
+ reads: concatUnique(reads, carryReads),
140
+ writes: concatUnique(['A'], FLAG_WRITES),
141
+ };
142
+ }
143
+ export function pushEffect(register) {
144
+ const units = reg16Units(register);
145
+ return {
146
+ ...baseEffect(),
147
+ reads: units,
148
+ writes: STACK_POINTER_UNITS,
149
+ stack: { kind: 'push', units },
150
+ };
151
+ }
152
+ export function popEffect(register) {
153
+ const units = reg16Units(register);
154
+ return {
155
+ ...baseEffect(),
156
+ writes: concatUnique(units, STACK_POINTER_UNITS),
157
+ stack: { kind: 'pop', units },
158
+ };
159
+ }
160
+ export function rotateShiftEffect(instruction) {
161
+ const reads = operandReads(instruction.operand);
162
+ const writes = operandWrites(instruction.operand);
163
+ if (reads === undefined || writes === undefined)
164
+ return unknownEffect();
165
+ return {
166
+ ...baseEffect(),
167
+ reads,
168
+ writes: concatUnique(writes, ROTATE_SHIFT_FLAG_WRITES),
169
+ };
170
+ }
171
+ export function bitEffect(instruction) {
172
+ const reads = operandReads(instruction.operand);
173
+ if (reads === undefined)
174
+ return unknownEffect();
175
+ if (instruction.mnemonic === 'bit') {
176
+ return {
177
+ ...baseEffect(),
178
+ reads,
179
+ writes: BIT_FLAG_WRITES,
180
+ };
181
+ }
182
+ const writes = operandWrites(instruction.operand);
183
+ if (writes === undefined)
184
+ return unknownEffect();
185
+ return {
186
+ ...baseEffect(),
187
+ reads,
188
+ writes,
189
+ };
190
+ }
191
+ export function inEffect(instruction) {
192
+ const targetWrites = instruction.target?.kind === 'reg8' ? reg8Units(instruction.target.register) : undefined;
193
+ if (instruction.port.kind === 'imm') {
194
+ return {
195
+ ...baseEffect(),
196
+ reads: ['A'],
197
+ writes: targetWrites ?? [],
198
+ };
199
+ }
200
+ return {
201
+ ...baseEffect(),
202
+ reads: ['C'],
203
+ writes: concatUnique(targetWrites ?? [], BIT_FLAG_WRITES),
204
+ };
205
+ }
206
+ export function outEffect(instruction) {
207
+ const valueReads = instruction.source.kind === 'reg8' ? reg8Units(instruction.source.register) : [];
208
+ if (instruction.port.kind === 'c') {
209
+ return {
210
+ ...baseEffect(),
211
+ reads: concatUnique(['C'], valueReads),
212
+ };
213
+ }
214
+ return {
215
+ ...baseEffect(),
216
+ reads: valueReads,
217
+ };
218
+ }
219
+ export function blockTransferEffect() {
220
+ return {
221
+ ...baseEffect(),
222
+ reads: ['H', 'L', 'D', 'E', 'B', 'C'],
223
+ writes: ['H', 'L', 'D', 'E', 'B', 'C', 'halfCarry', 'parity'],
224
+ };
225
+ }
226
+ export function exEffect(instruction) {
227
+ if (instruction.form === 'de-hl') {
228
+ return {
229
+ ...baseEffect(),
230
+ reads: ['D', 'E', 'H', 'L'],
231
+ writes: ['D', 'E', 'H', 'L'],
232
+ };
233
+ }
234
+ return unknownEffect();
235
+ }
236
+ export function accumulatorRotateEffect(mnemonic) {
237
+ const reads = mnemonic === 'rla' || mnemonic === 'rra' ? ['A', 'carry'] : ['A'];
238
+ return {
239
+ ...baseEffect(),
240
+ reads,
241
+ writes: ['A', 'carry', 'halfCarry'],
242
+ };
243
+ }
244
+ function wideAluEffect(instruction, extraReads) {
245
+ const targetReads = operandReads(instruction.target);
246
+ const sourceReads = operandReads(instruction.source);
247
+ if (targetReads === undefined || sourceReads === undefined)
248
+ return unknownEffect();
249
+ return {
250
+ ...baseEffect(),
251
+ reads: concatUnique(targetReads, sourceReads, extraReads),
252
+ writes: concatUnique(operandWrites(instruction.target) ?? [], FLAG_WRITES),
253
+ };
254
+ }
255
+ function aluSourceReads(source) {
256
+ if (source.kind === 'reg8')
257
+ return reg8Units(source.register);
258
+ if (source.kind === 'reg16' || source.kind === 'reg-index16')
259
+ return reg16Units(source.register);
260
+ if (source.kind === 'reg-half-index')
261
+ return regHalfUnits(source.register);
262
+ if (source.kind === 'reg-indirect' || source.kind === 'indexed')
263
+ return operandReads(source) ?? [];
264
+ return [];
265
+ }
@@ -0,0 +1,18 @@
1
+ import type { Expression } from '../model/expression.js';
2
+ import type { InstructionEffect, RegisterContractsUnit } from '../register-contracts/types.js';
3
+ import type { Z80Condition, Z80Operand, Z80RelativeCondition } from './instruction.js';
4
+ export declare const FLAG_WRITES: RegisterContractsUnit[];
5
+ export declare const INC_DEC_FLAG_WRITES: RegisterContractsUnit[];
6
+ export declare const ROTATE_SHIFT_FLAG_WRITES: RegisterContractsUnit[];
7
+ export declare const BIT_FLAG_WRITES: RegisterContractsUnit[];
8
+ export declare const STACK_POINTER_UNITS: RegisterContractsUnit[];
9
+ export declare function baseEffect(): InstructionEffect;
10
+ export declare function unknownEffect(): InstructionEffect;
11
+ export declare function concatUnique(...groups: RegisterContractsUnit[][]): RegisterContractsUnit[];
12
+ export declare function reg8Units(raw: string): RegisterContractsUnit[];
13
+ export declare function reg16Units(raw: string): RegisterContractsUnit[];
14
+ export declare function regHalfUnits(raw: string): RegisterContractsUnit[];
15
+ export declare function expressionSymbol(expression: Expression): string | undefined;
16
+ export declare function operandReads(op: Z80Operand): RegisterContractsUnit[] | undefined;
17
+ export declare function operandWrites(op: Z80Operand): RegisterContractsUnit[] | undefined;
18
+ export declare function conditionFlagRead(condition: Z80Condition | Z80RelativeCondition): RegisterContractsUnit[];
@@ -0,0 +1,165 @@
1
+ export const FLAG_WRITES = ['sign', 'zero', 'halfCarry', 'parity', 'carry'];
2
+ export const INC_DEC_FLAG_WRITES = ['sign', 'zero', 'halfCarry', 'parity'];
3
+ export const ROTATE_SHIFT_FLAG_WRITES = [
4
+ 'sign',
5
+ 'zero',
6
+ 'halfCarry',
7
+ 'parity',
8
+ 'carry',
9
+ ];
10
+ export const BIT_FLAG_WRITES = ['sign', 'zero', 'halfCarry', 'parity'];
11
+ export const STACK_POINTER_UNITS = ['SPH', 'SPL'];
12
+ const UNKNOWN_UNITS = [
13
+ 'A',
14
+ 'B',
15
+ 'C',
16
+ 'D',
17
+ 'E',
18
+ 'H',
19
+ 'L',
20
+ 'IXH',
21
+ 'IXL',
22
+ 'IYH',
23
+ 'IYL',
24
+ 'SPH',
25
+ 'SPL',
26
+ 'carry',
27
+ 'zero',
28
+ 'sign',
29
+ 'parity',
30
+ 'halfCarry',
31
+ ];
32
+ export function baseEffect() {
33
+ return {
34
+ reads: [],
35
+ writes: [],
36
+ stack: { kind: 'none' },
37
+ control: { kind: 'fallthrough' },
38
+ };
39
+ }
40
+ export function unknownEffect() {
41
+ return {
42
+ reads: UNKNOWN_UNITS,
43
+ writes: UNKNOWN_UNITS,
44
+ stack: { kind: 'unknown' },
45
+ control: { kind: 'unknown' },
46
+ };
47
+ }
48
+ export function concatUnique(...groups) {
49
+ const out = [];
50
+ for (const group of groups) {
51
+ appendUnique(out, group);
52
+ }
53
+ return out;
54
+ }
55
+ export function reg8Units(raw) {
56
+ const reg = raw.toLowerCase();
57
+ if (reg === 'a')
58
+ return ['A'];
59
+ if (reg === 'b')
60
+ return ['B'];
61
+ if (reg === 'c')
62
+ return ['C'];
63
+ if (reg === 'd')
64
+ return ['D'];
65
+ if (reg === 'e')
66
+ return ['E'];
67
+ if (reg === 'h')
68
+ return ['H'];
69
+ if (reg === 'l')
70
+ return ['L'];
71
+ return [];
72
+ }
73
+ export function reg16Units(raw) {
74
+ const reg = raw.toLowerCase();
75
+ if (reg === 'bc')
76
+ return ['B', 'C'];
77
+ if (reg === 'de')
78
+ return ['D', 'E'];
79
+ if (reg === 'hl')
80
+ return ['H', 'L'];
81
+ if (reg === 'sp')
82
+ return ['SPH', 'SPL'];
83
+ if (reg === 'ix')
84
+ return ['IXH', 'IXL'];
85
+ if (reg === 'iy')
86
+ return ['IYH', 'IYL'];
87
+ if (reg === 'af')
88
+ return ['A', ...FLAG_WRITES];
89
+ return [];
90
+ }
91
+ export function regHalfUnits(raw) {
92
+ const reg = raw.toLowerCase();
93
+ if (reg === 'ixh')
94
+ return ['IXH'];
95
+ if (reg === 'ixl')
96
+ return ['IXL'];
97
+ if (reg === 'iyh')
98
+ return ['IYH'];
99
+ if (reg === 'iyl')
100
+ return ['IYL'];
101
+ return [];
102
+ }
103
+ export function expressionSymbol(expression) {
104
+ return expression.kind === 'symbol' ? expression.name : undefined;
105
+ }
106
+ export function operandReads(op) {
107
+ switch (op.kind) {
108
+ case 'reg8':
109
+ return reg8Units(op.register);
110
+ case 'reg16':
111
+ case 'reg-index16':
112
+ return reg16Units(op.register);
113
+ case 'reg-half-index':
114
+ return regHalfUnits(op.register);
115
+ case 'special8':
116
+ return [];
117
+ case 'reg-indirect':
118
+ return reg16Units(op.register);
119
+ case 'indexed':
120
+ return reg16Units(op.register);
121
+ case 'mem-abs':
122
+ case 'imm':
123
+ return [];
124
+ default:
125
+ return undefined;
126
+ }
127
+ }
128
+ export function operandWrites(op) {
129
+ switch (op.kind) {
130
+ case 'reg8':
131
+ return reg8Units(op.register);
132
+ case 'reg16':
133
+ return reg16Units(op.register);
134
+ case 'reg-index16':
135
+ return reg16Units(op.register);
136
+ case 'reg-half-index':
137
+ return regHalfUnits(op.register);
138
+ default:
139
+ return undefined;
140
+ }
141
+ }
142
+ export function conditionFlagRead(condition) {
143
+ switch (condition) {
144
+ case 'z':
145
+ case 'nz':
146
+ return ['zero'];
147
+ case 'c':
148
+ case 'nc':
149
+ return ['carry'];
150
+ case 'm':
151
+ case 'p':
152
+ return ['sign'];
153
+ case 'pe':
154
+ case 'po':
155
+ return ['parity'];
156
+ default:
157
+ return [];
158
+ }
159
+ }
160
+ function appendUnique(out, units) {
161
+ for (const unit of units) {
162
+ if (!out.includes(unit))
163
+ out.push(unit);
164
+ }
165
+ }
@@ -1,3 +1,3 @@
1
- import type { InstructionEffect } from '../register-care/types.js';
1
+ import type { InstructionEffect } from '../register-contracts/types.js';
2
2
  import type { Z80Instruction } from './instruction.js';
3
3
  export declare function getZ80InstructionEffect(instruction: Z80Instruction): InstructionEffect;