@jhlagado/azm 0.1.0
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.
- package/LICENSE +649 -0
- package/README.md +142 -0
- package/dist/src/analysis.d.ts +11 -0
- package/dist/src/analysis.js +41 -0
- package/dist/src/api-compile.d.ts +8 -0
- package/dist/src/api-compile.js +3 -0
- package/dist/src/api-tooling.d.ts +25 -0
- package/dist/src/api-tooling.js +21 -0
- package/dist/src/cli.d.ts +30 -0
- package/dist/src/cli.js +523 -0
- package/dist/src/compile.d.ts +10 -0
- package/dist/src/compile.js +175 -0
- package/dist/src/compileShared.d.ts +3 -0
- package/dist/src/compileShared.js +7 -0
- package/dist/src/diagnosticTypes.d.ts +77 -0
- package/dist/src/diagnosticTypes.js +53 -0
- package/dist/src/formats/index.d.ts +7 -0
- package/dist/src/formats/index.js +17 -0
- package/dist/src/formats/range.d.ts +17 -0
- package/dist/src/formats/range.js +45 -0
- package/dist/src/formats/types.d.ts +208 -0
- package/dist/src/formats/types.js +1 -0
- package/dist/src/formats/writeAsm80.d.ts +6 -0
- package/dist/src/formats/writeAsm80.js +86 -0
- package/dist/src/formats/writeBin.d.ts +7 -0
- package/dist/src/formats/writeBin.js +23 -0
- package/dist/src/formats/writeD8m.d.ts +9 -0
- package/dist/src/formats/writeD8m.js +239 -0
- package/dist/src/formats/writeHex.d.ts +9 -0
- package/dist/src/formats/writeHex.js +39 -0
- package/dist/src/formats/writeListing.d.ts +8 -0
- package/dist/src/formats/writeListing.js +83 -0
- package/dist/src/frontend/asm80/asmLine.d.ts +39 -0
- package/dist/src/frontend/asm80/asmLine.js +89 -0
- package/dist/src/frontend/asm80/parseAsmRawValues.d.ts +4 -0
- package/dist/src/frontend/asm80/parseAsmRawValues.js +94 -0
- package/dist/src/frontend/asm80/quoteScan.d.ts +10 -0
- package/dist/src/frontend/asm80/quoteScan.js +25 -0
- package/dist/src/frontend/ast.d.ts +376 -0
- package/dist/src/frontend/ast.js +1 -0
- package/dist/src/frontend/directiveAliases.d.ts +14 -0
- package/dist/src/frontend/directiveAliases.js +189 -0
- package/dist/src/frontend/grammarData.d.ts +14 -0
- package/dist/src/frontend/grammarData.js +65 -0
- package/dist/src/frontend/immExprUtils.d.ts +2 -0
- package/dist/src/frontend/immExprUtils.js +12 -0
- package/dist/src/frontend/parseAsmFlatDirectiveLine.d.ts +17 -0
- package/dist/src/frontend/parseAsmFlatDirectiveLine.js +187 -0
- package/dist/src/frontend/parseAsmInstruction.d.ts +3 -0
- package/dist/src/frontend/parseAsmInstruction.js +73 -0
- package/dist/src/frontend/parseAsmStatements.d.ts +6 -0
- package/dist/src/frontend/parseAsmStatements.js +16 -0
- package/dist/src/frontend/parseAsmStream.d.ts +10 -0
- package/dist/src/frontend/parseAsmStream.js +33 -0
- package/dist/src/frontend/parseAsmTopLevel.d.ts +18 -0
- package/dist/src/frontend/parseAsmTopLevel.js +34 -0
- package/dist/src/frontend/parseDiagnostics.d.ts +9 -0
- package/dist/src/frontend/parseDiagnostics.js +16 -0
- package/dist/src/frontend/parseEnum.d.ts +12 -0
- package/dist/src/frontend/parseEnum.js +70 -0
- package/dist/src/frontend/parseImm.d.ts +10 -0
- package/dist/src/frontend/parseImm.js +397 -0
- package/dist/src/frontend/parseLogicalLines.d.ts +11 -0
- package/dist/src/frontend/parseLogicalLines.js +94 -0
- package/dist/src/frontend/parseOp.d.ts +25 -0
- package/dist/src/frontend/parseOp.js +120 -0
- package/dist/src/frontend/parseOpHeader.d.ts +20 -0
- package/dist/src/frontend/parseOpHeader.js +32 -0
- package/dist/src/frontend/parseOperands.d.ts +4 -0
- package/dist/src/frontend/parseOperands.js +290 -0
- package/dist/src/frontend/parseParams.d.ts +6 -0
- package/dist/src/frontend/parseParams.js +62 -0
- package/dist/src/frontend/parseParserRecovery.d.ts +12 -0
- package/dist/src/frontend/parseParserRecovery.js +17 -0
- package/dist/src/frontend/parseParserShared.d.ts +2 -0
- package/dist/src/frontend/parseParserShared.js +8 -0
- package/dist/src/frontend/parseRawDataDirectiveStart.d.ts +1 -0
- package/dist/src/frontend/parseRawDataDirectiveStart.js +3 -0
- package/dist/src/frontend/parseRawDataDirectives.d.ts +7 -0
- package/dist/src/frontend/parseRawDataDirectives.js +142 -0
- package/dist/src/frontend/parseRecordFieldDecl.d.ts +34 -0
- package/dist/src/frontend/parseRecordFieldDecl.js +177 -0
- package/dist/src/frontend/parseSourceItemDispatch.d.ts +46 -0
- package/dist/src/frontend/parseSourceItemDispatch.js +53 -0
- package/dist/src/frontend/parseSourceItemTable.d.ts +16 -0
- package/dist/src/frontend/parseSourceItemTable.js +68 -0
- package/dist/src/frontend/parseTopLevelCommon.d.ts +11 -0
- package/dist/src/frontend/parseTopLevelCommon.js +50 -0
- package/dist/src/frontend/parseTypes.d.ts +24 -0
- package/dist/src/frontend/parseTypes.js +77 -0
- package/dist/src/frontend/parser.d.ts +11 -0
- package/dist/src/frontend/parser.js +88 -0
- package/dist/src/frontend/source.d.ts +28 -0
- package/dist/src/frontend/source.js +58 -0
- package/dist/src/frontend/sourceExtensions.d.ts +2 -0
- package/dist/src/frontend/sourceExtensions.js +6 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +2 -0
- package/dist/src/lintCaseStyle.d.ts +4 -0
- package/dist/src/lintCaseStyle.js +129 -0
- package/dist/src/lowering/asmDirectiveLowering.d.ts +4 -0
- package/dist/src/lowering/asmDirectiveLowering.js +229 -0
- package/dist/src/lowering/asmDirectiveTraversal.d.ts +47 -0
- package/dist/src/lowering/asmDirectiveTraversal.js +52 -0
- package/dist/src/lowering/asmEquResolution.d.ts +8 -0
- package/dist/src/lowering/asmEquResolution.js +69 -0
- package/dist/src/lowering/asmInstructionLdHelpers.d.ts +15 -0
- package/dist/src/lowering/asmInstructionLdHelpers.js +102 -0
- package/dist/src/lowering/asmInstructionLowering.d.ts +5 -0
- package/dist/src/lowering/asmInstructionLowering.js +54 -0
- package/dist/src/lowering/asmInstructionStream.d.ts +46 -0
- package/dist/src/lowering/asmInstructionStream.js +51 -0
- package/dist/src/lowering/asmLoweringBranchCall.d.ts +43 -0
- package/dist/src/lowering/asmLoweringBranchCall.js +254 -0
- package/dist/src/lowering/asmLoweringHost.d.ts +23 -0
- package/dist/src/lowering/asmLoweringHost.js +1 -0
- package/dist/src/lowering/asmLoweringLd.d.ts +28 -0
- package/dist/src/lowering/asmLoweringLd.js +144 -0
- package/dist/src/lowering/asmRangeLowering.d.ts +17 -0
- package/dist/src/lowering/asmRangeLowering.js +39 -0
- package/dist/src/lowering/asmRawDataLowering.d.ts +16 -0
- package/dist/src/lowering/asmRawDataLowering.js +209 -0
- package/dist/src/lowering/asmSourceEmitter.d.ts +4 -0
- package/dist/src/lowering/asmSourceEmitter.js +9 -0
- package/dist/src/lowering/asmSourceInstructionLowering.d.ts +4 -0
- package/dist/src/lowering/asmSourceInstructionLowering.js +14 -0
- package/dist/src/lowering/asmUtils.d.ts +13 -0
- package/dist/src/lowering/asmUtils.js +105 -0
- package/dist/src/lowering/assemblerFlowSetup.d.ts +54 -0
- package/dist/src/lowering/assemblerFlowSetup.js +128 -0
- package/dist/src/lowering/assemblerLoweringContext.d.ts +151 -0
- package/dist/src/lowering/assemblerLoweringContext.js +16 -0
- package/dist/src/lowering/assemblerLoweringContextSplit.d.ts +7 -0
- package/dist/src/lowering/assemblerLoweringContextSplit.js +75 -0
- package/dist/src/lowering/assemblerLoweringPhases.d.ts +66 -0
- package/dist/src/lowering/assemblerLoweringPhases.js +166 -0
- package/dist/src/lowering/bytePlacement.d.ts +7 -0
- package/dist/src/lowering/bytePlacement.js +37 -0
- package/dist/src/lowering/capabilities.d.ts +67 -0
- package/dist/src/lowering/capabilities.js +1 -0
- package/dist/src/lowering/eaResolution.d.ts +58 -0
- package/dist/src/lowering/eaResolution.js +159 -0
- package/dist/src/lowering/emissionCore.d.ts +17 -0
- package/dist/src/lowering/emissionCore.js +21 -0
- package/dist/src/lowering/emit.d.ts +17 -0
- package/dist/src/lowering/emit.js +46 -0
- package/dist/src/lowering/emitContextBuilder.d.ts +63 -0
- package/dist/src/lowering/emitContextBuilder.js +41 -0
- package/dist/src/lowering/emitFinalization.d.ts +61 -0
- package/dist/src/lowering/emitFinalization.js +66 -0
- package/dist/src/lowering/emitFinalizationSetup.d.ts +19 -0
- package/dist/src/lowering/emitFinalizationSetup.js +26 -0
- package/dist/src/lowering/emitPhase1BuildProgramLoweringContext.d.ts +7 -0
- package/dist/src/lowering/emitPhase1BuildProgramLoweringContext.js +119 -0
- package/dist/src/lowering/emitPhase1Helpers.d.ts +4 -0
- package/dist/src/lowering/emitPhase1Helpers.js +12 -0
- package/dist/src/lowering/emitPhase1Types.d.ts +21 -0
- package/dist/src/lowering/emitPhase1Types.js +1 -0
- package/dist/src/lowering/emitPhase1WirePipeline.d.ts +70 -0
- package/dist/src/lowering/emitPhase1WirePipeline.js +203 -0
- package/dist/src/lowering/emitPhase1Workspace.d.ts +82 -0
- package/dist/src/lowering/emitPhase1Workspace.js +55 -0
- package/dist/src/lowering/emitPipeline.d.ts +121 -0
- package/dist/src/lowering/emitPipeline.js +57 -0
- package/dist/src/lowering/emitProgramContext.d.ts +39 -0
- package/dist/src/lowering/emitProgramContext.js +29 -0
- package/dist/src/lowering/emitState.d.ts +90 -0
- package/dist/src/lowering/emitState.js +124 -0
- package/dist/src/lowering/fixupBaseResolution.d.ts +7 -0
- package/dist/src/lowering/fixupBaseResolution.js +23 -0
- package/dist/src/lowering/fixupEmission.d.ts +64 -0
- package/dist/src/lowering/fixupEmission.js +199 -0
- package/dist/src/lowering/immMath.d.ts +2 -0
- package/dist/src/lowering/immMath.js +34 -0
- package/dist/src/lowering/inputAssets.d.ts +7 -0
- package/dist/src/lowering/inputAssets.js +106 -0
- package/dist/src/lowering/ldEncoding.d.ts +15 -0
- package/dist/src/lowering/ldEncoding.js +12 -0
- package/dist/src/lowering/ldEncodingRegMemHelpers.d.ts +5 -0
- package/dist/src/lowering/ldEncodingRegMemHelpers.js +124 -0
- package/dist/src/lowering/ldFormSelection.d.ts +26 -0
- package/dist/src/lowering/ldFormSelection.js +92 -0
- package/dist/src/lowering/ldLowering.d.ts +7 -0
- package/dist/src/lowering/ldLowering.js +13 -0
- package/dist/src/lowering/loweredAsmByteEmission.d.ts +23 -0
- package/dist/src/lowering/loweredAsmByteEmission.js +185 -0
- package/dist/src/lowering/loweredAsmPlacement.d.ts +13 -0
- package/dist/src/lowering/loweredAsmPlacement.js +86 -0
- package/dist/src/lowering/loweredAsmStreamRecording.d.ts +27 -0
- package/dist/src/lowering/loweredAsmStreamRecording.js +215 -0
- package/dist/src/lowering/loweredAsmTypes.d.ts +202 -0
- package/dist/src/lowering/loweredAsmTypes.js +1 -0
- package/dist/src/lowering/loweredFormat.d.ts +3 -0
- package/dist/src/lowering/loweredFormat.js +26 -0
- package/dist/src/lowering/loweredItemSize.d.ts +4 -0
- package/dist/src/lowering/loweredItemSize.js +17 -0
- package/dist/src/lowering/loweringDiagnostics.d.ts +9 -0
- package/dist/src/lowering/loweringDiagnostics.js +55 -0
- package/dist/src/lowering/loweringTypes.d.ts +27 -0
- package/dist/src/lowering/loweringTypes.js +1 -0
- package/dist/src/lowering/opCandidateRegistry.d.ts +9 -0
- package/dist/src/lowering/opCandidateRegistry.js +9 -0
- package/dist/src/lowering/opExpansionExecution.d.ts +15 -0
- package/dist/src/lowering/opExpansionExecution.js +45 -0
- package/dist/src/lowering/opExpansionOrchestration.d.ts +15 -0
- package/dist/src/lowering/opExpansionOrchestration.js +88 -0
- package/dist/src/lowering/opExpansionStream.d.ts +12 -0
- package/dist/src/lowering/opExpansionStream.js +176 -0
- package/dist/src/lowering/opMatching.d.ts +52 -0
- package/dist/src/lowering/opMatching.js +355 -0
- package/dist/src/lowering/opSubstitution.d.ts +13 -0
- package/dist/src/lowering/opSubstitution.js +175 -0
- package/dist/src/lowering/prescanTypes.d.ts +7 -0
- package/dist/src/lowering/prescanTypes.js +1 -0
- package/dist/src/lowering/programLowering.d.ts +144 -0
- package/dist/src/lowering/programLowering.js +2 -0
- package/dist/src/lowering/programLoweringDeclarations.d.ts +5 -0
- package/dist/src/lowering/programLoweringDeclarations.js +5 -0
- package/dist/src/lowering/programLoweringFinalize.d.ts +18 -0
- package/dist/src/lowering/programLoweringFinalize.js +115 -0
- package/dist/src/lowering/programLoweringTraversal.d.ts +2 -0
- package/dist/src/lowering/programLoweringTraversal.js +93 -0
- package/dist/src/lowering/programPrescan.d.ts +3 -0
- package/dist/src/lowering/programPrescan.js +37 -0
- package/dist/src/lowering/traceFormat.d.ts +13 -0
- package/dist/src/lowering/traceFormat.js +211 -0
- package/dist/src/pathCompare.d.ts +3 -0
- package/dist/src/pathCompare.js +26 -0
- package/dist/src/pipeline.d.ts +78 -0
- package/dist/src/pipeline.js +1 -0
- package/dist/src/registerCare/analyze.d.ts +24 -0
- package/dist/src/registerCare/analyze.js +327 -0
- package/dist/src/registerCare/annotate.d.ts +11 -0
- package/dist/src/registerCare/annotate.js +76 -0
- package/dist/src/registerCare/boundaryHints.d.ts +2 -0
- package/dist/src/registerCare/boundaryHints.js +10 -0
- package/dist/src/registerCare/carriers.d.ts +4 -0
- package/dist/src/registerCare/carriers.js +78 -0
- package/dist/src/registerCare/controlFlow.d.ts +5 -0
- package/dist/src/registerCare/controlFlow.js +35 -0
- package/dist/src/registerCare/fix.d.ts +11 -0
- package/dist/src/registerCare/fix.js +119 -0
- package/dist/src/registerCare/liveness.d.ts +7 -0
- package/dist/src/registerCare/liveness.js +227 -0
- package/dist/src/registerCare/profiles.d.ts +11 -0
- package/dist/src/registerCare/profiles.js +45 -0
- package/dist/src/registerCare/programModel.d.ts +3 -0
- package/dist/src/registerCare/programModel.js +181 -0
- package/dist/src/registerCare/report.d.ts +5 -0
- package/dist/src/registerCare/report.js +139 -0
- package/dist/src/registerCare/smartComments.d.ts +5 -0
- package/dist/src/registerCare/smartComments.js +247 -0
- package/dist/src/registerCare/sourceText.d.ts +8 -0
- package/dist/src/registerCare/sourceText.js +15 -0
- package/dist/src/registerCare/summary.d.ts +3 -0
- package/dist/src/registerCare/summary.js +492 -0
- package/dist/src/registerCare/tooling.d.ts +42 -0
- package/dist/src/registerCare/tooling.js +50 -0
- package/dist/src/registerCare/types.d.ts +154 -0
- package/dist/src/registerCare/types.js +1 -0
- package/dist/src/semantics/declVisitor.d.ts +5 -0
- package/dist/src/semantics/declVisitor.js +11 -0
- package/dist/src/semantics/env.d.ts +28 -0
- package/dist/src/semantics/env.js +432 -0
- package/dist/src/semantics/layout.d.ts +21 -0
- package/dist/src/semantics/layout.js +226 -0
- package/dist/src/semantics/layoutCastFold.d.ts +22 -0
- package/dist/src/semantics/layoutCastFold.js +118 -0
- package/dist/src/semantics/semanticsDiagnostics.d.ts +2 -0
- package/dist/src/semantics/semanticsDiagnostics.js +4 -0
- package/dist/src/semantics/typeQueries.d.ts +31 -0
- package/dist/src/semantics/typeQueries.js +124 -0
- package/dist/src/sourceIncludeExpansion.d.ts +17 -0
- package/dist/src/sourceIncludeExpansion.js +124 -0
- package/dist/src/sourceIncludePaths.d.ts +1 -0
- package/dist/src/sourceIncludePaths.js +12 -0
- package/dist/src/sourceLoader.d.ts +15 -0
- package/dist/src/sourceLoader.js +118 -0
- package/dist/src/z80/effects.d.ts +3 -0
- package/dist/src/z80/effects.js +516 -0
- package/dist/src/z80/encode.d.ts +10 -0
- package/dist/src/z80/encode.js +412 -0
- package/dist/src/z80/encodeAlu.d.ts +7 -0
- package/dist/src/z80/encodeAlu.js +219 -0
- package/dist/src/z80/encodeBitOps.d.ts +7 -0
- package/dist/src/z80/encodeBitOps.js +123 -0
- package/dist/src/z80/encodeContext.d.ts +29 -0
- package/dist/src/z80/encodeContext.js +1 -0
- package/dist/src/z80/encodeControl.d.ts +26 -0
- package/dist/src/z80/encodeControl.js +180 -0
- package/dist/src/z80/encodeCoreOps.d.ts +7 -0
- package/dist/src/z80/encodeCoreOps.js +131 -0
- package/dist/src/z80/encodeIo.d.ts +9 -0
- package/dist/src/z80/encodeIo.js +128 -0
- package/dist/src/z80/encodeLd.d.ts +13 -0
- package/dist/src/z80/encodeLd.js +273 -0
- package/dist/src/z80/encoderRegistry.d.ts +13 -0
- package/dist/src/z80/encoderRegistry.js +169 -0
- package/docs/reference/cli.md +134 -0
- package/docs/reference/tooling-api.md +248 -0
- package/package.json +98 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
export function encodeLdInstruction(node, env, diagnostics, ctx) {
|
|
2
|
+
const { diag, regName, immValue, indexedReg8, reg8Code, fitsImm8, fitsImm16 } = ctx;
|
|
3
|
+
const ops = node.operands;
|
|
4
|
+
if (ops.length !== 2) {
|
|
5
|
+
diag(diagnostics, node, `ld expects two operands`);
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
const dst = regName(ops[0]);
|
|
9
|
+
const src = regName(ops[1]);
|
|
10
|
+
if (dst === 'I' && src === 'A')
|
|
11
|
+
return Uint8Array.of(0xed, 0x47);
|
|
12
|
+
if (dst === 'A' && src === 'I')
|
|
13
|
+
return Uint8Array.of(0xed, 0x57);
|
|
14
|
+
if (dst === 'R' && src === 'A')
|
|
15
|
+
return Uint8Array.of(0xed, 0x4f);
|
|
16
|
+
if (dst === 'A' && src === 'R')
|
|
17
|
+
return Uint8Array.of(0xed, 0x5f);
|
|
18
|
+
const r = regName(ops[0]);
|
|
19
|
+
const n = immValue(ops[1], env);
|
|
20
|
+
if (n !== undefined && r) {
|
|
21
|
+
const indexedDst = indexedReg8(ops[0]);
|
|
22
|
+
if (indexedDst) {
|
|
23
|
+
if (!fitsImm8(n)) {
|
|
24
|
+
diag(diagnostics, node, `ld ${indexedDst.display}, n expects imm8`);
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return Uint8Array.of(indexedDst.prefix, 0x06 + (indexedDst.code << 3), n & 0xff);
|
|
28
|
+
}
|
|
29
|
+
const r8 = reg8Code(r);
|
|
30
|
+
if (r8 !== undefined) {
|
|
31
|
+
if (!fitsImm8(n)) {
|
|
32
|
+
diag(diagnostics, node, `ld ${r}, n expects imm8`);
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return Uint8Array.of(0x06 + (r8 << 3), n & 0xff);
|
|
36
|
+
}
|
|
37
|
+
if (r === 'BC' || r === 'DE' || r === 'HL' || r === 'SP') {
|
|
38
|
+
if (!fitsImm16(n)) {
|
|
39
|
+
diag(diagnostics, node, `ld ${r}, nn expects imm16`);
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const op = r === 'BC' ? 0x01 : r === 'DE' ? 0x11 : r === 'HL' ? 0x21 : 0x31;
|
|
43
|
+
return Uint8Array.of(op, n & 0xff, (n >> 8) & 0xff);
|
|
44
|
+
}
|
|
45
|
+
if (r === 'IX' || r === 'IY') {
|
|
46
|
+
if (!fitsImm16(n)) {
|
|
47
|
+
diag(diagnostics, node, `ld ${r}, nn expects imm16`);
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
const prefix = r === 'IX' ? 0xdd : 0xfd;
|
|
51
|
+
return Uint8Array.of(prefix, 0x21, n & 0xff, (n >> 8) & 0xff);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const indexedDst = indexedReg8(ops[0]);
|
|
55
|
+
const indexedSrc = indexedReg8(ops[1]);
|
|
56
|
+
if ((indexedDst || indexedSrc) && ops[0].kind !== 'Mem' && ops[1].kind !== 'Mem') {
|
|
57
|
+
const prefix = indexedDst?.prefix ?? indexedSrc?.prefix;
|
|
58
|
+
if ((indexedDst && indexedDst.prefix !== prefix) ||
|
|
59
|
+
(indexedSrc && indexedSrc.prefix !== prefix)) {
|
|
60
|
+
diag(diagnostics, node, `ld between IX* and IY* byte registers is not supported`);
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
if ((indexedDst && !indexedSrc && ctx.isPlainHLReg8(src)) ||
|
|
64
|
+
(indexedSrc && !indexedDst && ctx.isPlainHLReg8(dst))) {
|
|
65
|
+
diag(diagnostics, node, `ld with IX*/IY* does not support plain H/L counterpart operands`);
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const d = indexedDst ? indexedDst.code : dst ? reg8Code(dst) : undefined;
|
|
69
|
+
const s = indexedSrc ? indexedSrc.code : src ? reg8Code(src) : undefined;
|
|
70
|
+
if (prefix === undefined || d === undefined || s === undefined) {
|
|
71
|
+
diag(diagnostics, node, `ld with IX*/IY* byte registers expects reg8 operands`);
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
return Uint8Array.of(prefix, 0x40 + (d << 3) + s);
|
|
75
|
+
}
|
|
76
|
+
const srcAbs16 = ctx.memAbs16(ops[1], env);
|
|
77
|
+
if (srcAbs16 !== undefined) {
|
|
78
|
+
if (srcAbs16 < 0 || srcAbs16 > 0xffff) {
|
|
79
|
+
diag(diagnostics, node, `ld rr, (nn) expects abs16 address`);
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
if (dst === 'A')
|
|
83
|
+
return Uint8Array.of(0x3a, srcAbs16 & 0xff, (srcAbs16 >> 8) & 0xff);
|
|
84
|
+
if (dst === 'HL')
|
|
85
|
+
return Uint8Array.of(0x2a, srcAbs16 & 0xff, (srcAbs16 >> 8) & 0xff);
|
|
86
|
+
if (dst === 'BC')
|
|
87
|
+
return Uint8Array.of(0xed, 0x4b, srcAbs16 & 0xff, (srcAbs16 >> 8) & 0xff);
|
|
88
|
+
if (dst === 'DE')
|
|
89
|
+
return Uint8Array.of(0xed, 0x5b, srcAbs16 & 0xff, (srcAbs16 >> 8) & 0xff);
|
|
90
|
+
if (dst === 'SP')
|
|
91
|
+
return Uint8Array.of(0xed, 0x7b, srcAbs16 & 0xff, (srcAbs16 >> 8) & 0xff);
|
|
92
|
+
if (dst === 'IX')
|
|
93
|
+
return Uint8Array.of(0xdd, 0x2a, srcAbs16 & 0xff, (srcAbs16 >> 8) & 0xff);
|
|
94
|
+
if (dst === 'IY')
|
|
95
|
+
return Uint8Array.of(0xfd, 0x2a, srcAbs16 & 0xff, (srcAbs16 >> 8) & 0xff);
|
|
96
|
+
}
|
|
97
|
+
const dstAbs16 = ctx.memAbs16(ops[0], env);
|
|
98
|
+
if (dstAbs16 !== undefined) {
|
|
99
|
+
if (dstAbs16 < 0 || dstAbs16 > 0xffff) {
|
|
100
|
+
diag(diagnostics, node, `ld (nn), rr expects abs16 address`);
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
if (src === 'A')
|
|
104
|
+
return Uint8Array.of(0x32, dstAbs16 & 0xff, (dstAbs16 >> 8) & 0xff);
|
|
105
|
+
if (src === 'HL')
|
|
106
|
+
return Uint8Array.of(0x22, dstAbs16 & 0xff, (dstAbs16 >> 8) & 0xff);
|
|
107
|
+
if (src === 'BC')
|
|
108
|
+
return Uint8Array.of(0xed, 0x43, dstAbs16 & 0xff, (dstAbs16 >> 8) & 0xff);
|
|
109
|
+
if (src === 'DE')
|
|
110
|
+
return Uint8Array.of(0xed, 0x53, dstAbs16 & 0xff, (dstAbs16 >> 8) & 0xff);
|
|
111
|
+
if (src === 'SP')
|
|
112
|
+
return Uint8Array.of(0xed, 0x73, dstAbs16 & 0xff, (dstAbs16 >> 8) & 0xff);
|
|
113
|
+
if (src === 'IX')
|
|
114
|
+
return Uint8Array.of(0xdd, 0x22, dstAbs16 & 0xff, (dstAbs16 >> 8) & 0xff);
|
|
115
|
+
if (src === 'IY')
|
|
116
|
+
return Uint8Array.of(0xfd, 0x22, dstAbs16 & 0xff, (dstAbs16 >> 8) & 0xff);
|
|
117
|
+
}
|
|
118
|
+
if (dst && src) {
|
|
119
|
+
const d = reg8Code(dst);
|
|
120
|
+
const s = reg8Code(src);
|
|
121
|
+
if (d !== undefined && s !== undefined) {
|
|
122
|
+
return Uint8Array.of(0x40 + (d << 3) + s);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const indexedDstMem = indexedReg8(ops[0]);
|
|
126
|
+
if (indexedDstMem && ops[1].kind === 'Mem') {
|
|
127
|
+
const idx = ctx.memIndexed(ops[1], env);
|
|
128
|
+
if (!idx) {
|
|
129
|
+
diag(diagnostics, node, `ld ${indexedDstMem.display}, source expects (${indexedDstMem.display.startsWith('IX') ? 'ix' : 'iy'}+disp)`);
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
if (idx.prefix !== indexedDstMem.prefix) {
|
|
133
|
+
diag(diagnostics, node, `ld ${indexedDstMem.display}, source index base must match destination family`);
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
const disp = idx.disp;
|
|
137
|
+
if (disp < -128 || disp > 127) {
|
|
138
|
+
diag(diagnostics, node, `ld ${indexedDstMem.display}, (${indexedDstMem.display.startsWith('IX') ? 'ix' : 'iy'}+disp) expects disp8`);
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
return Uint8Array.of(indexedDstMem.prefix, 0x46 + (indexedDstMem.code << 3), disp & 0xff);
|
|
142
|
+
}
|
|
143
|
+
if (dst) {
|
|
144
|
+
const d = reg8Code(dst);
|
|
145
|
+
if (d !== undefined && ops[1].kind === 'Mem') {
|
|
146
|
+
const mem = ops[1];
|
|
147
|
+
if (mem.expr.kind === 'EaName' && mem.expr.name.toUpperCase() === 'HL') {
|
|
148
|
+
return Uint8Array.of(0x46 + (d << 3));
|
|
149
|
+
}
|
|
150
|
+
const idx = ctx.memIndexed(mem, env);
|
|
151
|
+
if (idx) {
|
|
152
|
+
const disp = idx.disp;
|
|
153
|
+
if (disp < -128 || disp > 127) {
|
|
154
|
+
diag(diagnostics, node, `ld ${dst}, (ix/iy+disp) expects disp8`);
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
return Uint8Array.of(idx.prefix, 0x46 + (d << 3), disp & 0xff);
|
|
158
|
+
}
|
|
159
|
+
if (dst.toUpperCase() === 'A' && mem.expr.kind === 'EaName') {
|
|
160
|
+
const ea = mem.expr.name.toUpperCase();
|
|
161
|
+
if (ea === 'BC')
|
|
162
|
+
return Uint8Array.of(0x0a);
|
|
163
|
+
if (ea === 'DE')
|
|
164
|
+
return Uint8Array.of(0x1a);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (ops[0].kind === 'Mem') {
|
|
169
|
+
const mem = ops[0];
|
|
170
|
+
const indexedSrcMem = indexedReg8(ops[1]);
|
|
171
|
+
if (indexedSrcMem) {
|
|
172
|
+
const idx = ctx.memIndexed(mem, env);
|
|
173
|
+
if (!idx) {
|
|
174
|
+
diag(diagnostics, node, `ld destination expects (${indexedSrcMem.display.startsWith('IX') ? 'ix' : 'iy'}+disp) for source ${indexedSrcMem.display}`);
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
if (idx.prefix !== indexedSrcMem.prefix) {
|
|
178
|
+
diag(diagnostics, node, `ld destination index base must match source ${indexedSrcMem.display} family`);
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
const disp = idx.disp;
|
|
182
|
+
if (disp < -128 || disp > 127) {
|
|
183
|
+
diag(diagnostics, node, `ld (${indexedSrcMem.display.startsWith('IX') ? 'ix' : 'iy'}+disp), ${indexedSrcMem.display} expects disp8`);
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
return Uint8Array.of(idx.prefix, 0x70 + indexedSrcMem.code, disp & 0xff);
|
|
187
|
+
}
|
|
188
|
+
if (mem.expr.kind === 'EaName' && mem.expr.name.toUpperCase() === 'HL' && src) {
|
|
189
|
+
const s = reg8Code(src);
|
|
190
|
+
if (s !== undefined)
|
|
191
|
+
return Uint8Array.of(0x70 + s);
|
|
192
|
+
}
|
|
193
|
+
const idx = src ? ctx.memIndexed(mem, env) : undefined;
|
|
194
|
+
if (idx && src) {
|
|
195
|
+
const s = reg8Code(src);
|
|
196
|
+
if (s !== undefined) {
|
|
197
|
+
const disp = idx.disp;
|
|
198
|
+
if (disp < -128 || disp > 127) {
|
|
199
|
+
diag(diagnostics, node, `ld (ix/iy+disp), ${src} expects disp8`);
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
return Uint8Array.of(idx.prefix, 0x70 + s, disp & 0xff);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (mem.expr.kind === 'EaName' && src?.toUpperCase() === 'A') {
|
|
206
|
+
const ea = mem.expr.name.toUpperCase();
|
|
207
|
+
if (ea === 'BC')
|
|
208
|
+
return Uint8Array.of(0x02);
|
|
209
|
+
if (ea === 'DE')
|
|
210
|
+
return Uint8Array.of(0x12);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (ctx.isMemHL(ops[0]) && n !== undefined) {
|
|
214
|
+
if (!fitsImm8(n)) {
|
|
215
|
+
diag(diagnostics, node, `ld (hl), n expects imm8`);
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
return Uint8Array.of(0x36, n & 0xff);
|
|
219
|
+
}
|
|
220
|
+
if (n !== undefined) {
|
|
221
|
+
const idx = ctx.memIndexed(ops[0], env);
|
|
222
|
+
if (idx) {
|
|
223
|
+
if (!fitsImm8(n)) {
|
|
224
|
+
diag(diagnostics, node, `ld (ix/iy+disp), n expects imm8`);
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
const disp = idx.disp;
|
|
228
|
+
if (disp < -128 || disp > 127) {
|
|
229
|
+
diag(diagnostics, node, `ld (ix/iy+disp), n expects disp8`);
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
return Uint8Array.of(idx.prefix, 0x36, disp & 0xff, n & 0xff);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (r === 'SP' && src) {
|
|
236
|
+
if (src === 'HL')
|
|
237
|
+
return Uint8Array.of(0xf9);
|
|
238
|
+
if (src === 'IX')
|
|
239
|
+
return Uint8Array.of(0xdd, 0xf9);
|
|
240
|
+
if (src === 'IY')
|
|
241
|
+
return Uint8Array.of(0xfd, 0xf9);
|
|
242
|
+
}
|
|
243
|
+
if (ops[0].kind === 'Mem' && ops[1].kind === 'Mem') {
|
|
244
|
+
diag(diagnostics, node, `ld does not support memory-to-memory transfers`);
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
if (dst !== undefined &&
|
|
248
|
+
dst !== 'A' &&
|
|
249
|
+
(ctx.isMemRegName(ops[1], 'BC') || ctx.isMemRegName(ops[1], 'DE'))) {
|
|
250
|
+
diag(diagnostics, node, `ld r8, (bc/de) supports destination A only`);
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
if (src !== undefined &&
|
|
254
|
+
src !== 'A' &&
|
|
255
|
+
(ctx.isMemRegName(ops[0], 'BC') || ctx.isMemRegName(ops[0], 'DE'))) {
|
|
256
|
+
diag(diagnostics, node, `ld (bc/de), r8 supports source A only`);
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
if (dst === 'AF' || src === 'AF') {
|
|
260
|
+
diag(diagnostics, node, `ld does not support AF in this form`);
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
if (ctx.isReg16TransferName(dst) && ctx.isReg16TransferName(src)) {
|
|
264
|
+
if (dst === 'SP') {
|
|
265
|
+
diag(diagnostics, node, `ld SP, rr supports HL/IX/IY only`);
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
diag(diagnostics, node, `ld rr, rr supports SP <- HL/IX/IY only`);
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
diag(diagnostics, node, `ld expects a supported register/memory/immediate transfer form`);
|
|
272
|
+
return undefined;
|
|
273
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type EncoderFamily = 'control' | 'alu' | 'io' | 'ld' | 'core' | 'bit';
|
|
2
|
+
type EncoderFallbackMode = 'none' | 'standard' | 'arity-short-circuit';
|
|
3
|
+
type EncoderRegistryEntry = {
|
|
4
|
+
kind: 'zero';
|
|
5
|
+
bytes: Uint8Array;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'family';
|
|
8
|
+
family: EncoderFamily;
|
|
9
|
+
fallback: EncoderFallbackMode;
|
|
10
|
+
arityDiagnostic: (head: string, operandCount: number) => string | undefined;
|
|
11
|
+
};
|
|
12
|
+
export declare function getEncoderRegistryEntry(head: string): EncoderRegistryEntry | undefined;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
function expectOneOrTwoWithA(head, operandCount) {
|
|
2
|
+
if (operandCount === 1 || operandCount === 2)
|
|
3
|
+
return undefined;
|
|
4
|
+
return `${head} expects one operand, or two with destination A`;
|
|
5
|
+
}
|
|
6
|
+
function expectOneOrTwoWithAOrHl(head, operandCount) {
|
|
7
|
+
if (operandCount === 1 || operandCount === 2)
|
|
8
|
+
return undefined;
|
|
9
|
+
return `${head} expects one operand, two with destination A, or HL,rr form`;
|
|
10
|
+
}
|
|
11
|
+
function expectOne(head, operandCount) {
|
|
12
|
+
if (operandCount === 1)
|
|
13
|
+
return undefined;
|
|
14
|
+
return `${head} expects one operand`;
|
|
15
|
+
}
|
|
16
|
+
function expectTwo(head, operandCount) {
|
|
17
|
+
if (operandCount === 2)
|
|
18
|
+
return undefined;
|
|
19
|
+
return `${head} expects two operands`;
|
|
20
|
+
}
|
|
21
|
+
function expectTwoOrThreeIndexedToReg8(head, operandCount) {
|
|
22
|
+
if (operandCount === 2 || operandCount === 3)
|
|
23
|
+
return undefined;
|
|
24
|
+
return `${head} expects two operands, or three with indexed source + reg8 destination`;
|
|
25
|
+
}
|
|
26
|
+
function expectOneOrTwoIndexedToReg8(head, operandCount) {
|
|
27
|
+
if (operandCount === 1 || operandCount === 2)
|
|
28
|
+
return undefined;
|
|
29
|
+
return `${head} expects one operand, or two with indexed source + reg8 destination`;
|
|
30
|
+
}
|
|
31
|
+
function expectTwoOps(head, operandCount) {
|
|
32
|
+
if (operandCount === 2)
|
|
33
|
+
return undefined;
|
|
34
|
+
return `${head} expects two operands`;
|
|
35
|
+
}
|
|
36
|
+
const identityArity = (_head, _operandCount) => undefined;
|
|
37
|
+
const FAMILY_SPECS = [
|
|
38
|
+
{
|
|
39
|
+
heads: ['ret', 'call', 'djnz', 'jp', 'jr'],
|
|
40
|
+
family: 'control',
|
|
41
|
+
fallback: 'none',
|
|
42
|
+
arityDiagnostic: identityArity,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
heads: ['add', 'sub', 'cp', 'and', 'or', 'xor', 'adc', 'sbc'],
|
|
46
|
+
family: 'alu',
|
|
47
|
+
fallback: 'standard',
|
|
48
|
+
arityDiagnostic: (head, operandCount) => {
|
|
49
|
+
switch (head) {
|
|
50
|
+
case 'add':
|
|
51
|
+
return expectTwoOps(head, operandCount);
|
|
52
|
+
case 'sub':
|
|
53
|
+
case 'cp':
|
|
54
|
+
case 'and':
|
|
55
|
+
case 'or':
|
|
56
|
+
case 'xor':
|
|
57
|
+
return expectOneOrTwoWithA(head, operandCount);
|
|
58
|
+
case 'adc':
|
|
59
|
+
case 'sbc':
|
|
60
|
+
return expectOneOrTwoWithAOrHl(head, operandCount);
|
|
61
|
+
default:
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
heads: ['rst', 'im', 'in', 'out'],
|
|
68
|
+
family: 'io',
|
|
69
|
+
fallback: 'standard',
|
|
70
|
+
arityDiagnostic: identityArity,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
heads: ['ld'],
|
|
74
|
+
family: 'ld',
|
|
75
|
+
fallback: 'none',
|
|
76
|
+
arityDiagnostic: identityArity,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
heads: ['inc', 'dec', 'push', 'pop', 'ex'],
|
|
80
|
+
family: 'core',
|
|
81
|
+
fallback: 'standard',
|
|
82
|
+
arityDiagnostic: (head, operandCount) => {
|
|
83
|
+
if (head === 'ex')
|
|
84
|
+
return expectTwo(head, operandCount);
|
|
85
|
+
return expectOne(head, operandCount);
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
heads: ['bit', 'res', 'set', 'rl', 'rr', 'sla', 'sra', 'srl', 'sll', 'rlc', 'rrc'],
|
|
90
|
+
family: 'bit',
|
|
91
|
+
fallback: 'arity-short-circuit',
|
|
92
|
+
arityDiagnostic: (head, operandCount) => {
|
|
93
|
+
switch (head) {
|
|
94
|
+
case 'bit':
|
|
95
|
+
return expectTwo(head, operandCount);
|
|
96
|
+
case 'res':
|
|
97
|
+
case 'set':
|
|
98
|
+
return expectTwoOrThreeIndexedToReg8(head, operandCount);
|
|
99
|
+
case 'rl':
|
|
100
|
+
case 'rr':
|
|
101
|
+
case 'sla':
|
|
102
|
+
case 'sra':
|
|
103
|
+
case 'srl':
|
|
104
|
+
case 'sll':
|
|
105
|
+
case 'rlc':
|
|
106
|
+
case 'rrc':
|
|
107
|
+
return expectOneOrTwoIndexedToReg8(head, operandCount);
|
|
108
|
+
default:
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
const ZERO_OPCODE_REGISTRY = {
|
|
115
|
+
nop: Uint8Array.of(0x00),
|
|
116
|
+
halt: Uint8Array.of(0x76),
|
|
117
|
+
di: Uint8Array.of(0xf3),
|
|
118
|
+
ei: Uint8Array.of(0xfb),
|
|
119
|
+
scf: Uint8Array.of(0x37),
|
|
120
|
+
ccf: Uint8Array.of(0x3f),
|
|
121
|
+
cpl: Uint8Array.of(0x2f),
|
|
122
|
+
daa: Uint8Array.of(0x27),
|
|
123
|
+
rlca: Uint8Array.of(0x07),
|
|
124
|
+
rrca: Uint8Array.of(0x0f),
|
|
125
|
+
rla: Uint8Array.of(0x17),
|
|
126
|
+
rra: Uint8Array.of(0x1f),
|
|
127
|
+
exx: Uint8Array.of(0xd9),
|
|
128
|
+
reti: Uint8Array.of(0xed, 0x4d),
|
|
129
|
+
retn: Uint8Array.of(0xed, 0x45),
|
|
130
|
+
neg: Uint8Array.of(0xed, 0x44),
|
|
131
|
+
rrd: Uint8Array.of(0xed, 0x67),
|
|
132
|
+
rld: Uint8Array.of(0xed, 0x6f),
|
|
133
|
+
ldi: Uint8Array.of(0xed, 0xa0),
|
|
134
|
+
ldir: Uint8Array.of(0xed, 0xb0),
|
|
135
|
+
ldd: Uint8Array.of(0xed, 0xa8),
|
|
136
|
+
lddr: Uint8Array.of(0xed, 0xb8),
|
|
137
|
+
cpi: Uint8Array.of(0xed, 0xa1),
|
|
138
|
+
cpir: Uint8Array.of(0xed, 0xb1),
|
|
139
|
+
cpd: Uint8Array.of(0xed, 0xa9),
|
|
140
|
+
cpdr: Uint8Array.of(0xed, 0xb9),
|
|
141
|
+
ini: Uint8Array.of(0xed, 0xa2),
|
|
142
|
+
inir: Uint8Array.of(0xed, 0xb2),
|
|
143
|
+
ind: Uint8Array.of(0xed, 0xaa),
|
|
144
|
+
indr: Uint8Array.of(0xed, 0xba),
|
|
145
|
+
outi: Uint8Array.of(0xed, 0xa3),
|
|
146
|
+
otir: Uint8Array.of(0xed, 0xb3),
|
|
147
|
+
outd: Uint8Array.of(0xed, 0xab),
|
|
148
|
+
otdr: Uint8Array.of(0xed, 0xbb),
|
|
149
|
+
};
|
|
150
|
+
const ENCODER_REGISTRY = new Map();
|
|
151
|
+
for (const [head, bytes] of Object.entries(ZERO_OPCODE_REGISTRY)) {
|
|
152
|
+
ENCODER_REGISTRY.set(head, {
|
|
153
|
+
kind: 'zero',
|
|
154
|
+
bytes,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
for (const spec of FAMILY_SPECS) {
|
|
158
|
+
for (const head of spec.heads) {
|
|
159
|
+
ENCODER_REGISTRY.set(head, {
|
|
160
|
+
kind: 'family',
|
|
161
|
+
family: spec.family,
|
|
162
|
+
fallback: spec.fallback,
|
|
163
|
+
arityDiagnostic: spec.arityDiagnostic,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
export function getEncoderRegistryEntry(head) {
|
|
168
|
+
return ENCODER_REGISTRY.get(head.toLowerCase());
|
|
169
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# AZM CLI Reference
|
|
2
|
+
|
|
3
|
+
Status: active user reference
|
|
4
|
+
|
|
5
|
+
The `azm` command assembles `.asm` and `.z80` source files and writes the
|
|
6
|
+
requested object artifacts.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
azm [options] <entry.asm|entry.z80>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The entry file must be the final argument. AZM source uses `.asm` or `.z80`.
|
|
13
|
+
Register-care interface files use `.asmi`; they are loaded with `--interface`
|
|
14
|
+
and are not compile entries.
|
|
15
|
+
|
|
16
|
+
## Basic Use
|
|
17
|
+
|
|
18
|
+
Build the default artifact set next to the source file:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
azm program.asm
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Write a specific primary output:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
azm --type bin --output build/program.bin program.asm
|
|
28
|
+
azm --type hex --output build/program.hex program.asm
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Add include search paths:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
azm -I include -I vendor program.asm
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Load project directive aliases:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
azm --aliases azm.aliases.json program.asm
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Output Artifacts
|
|
44
|
+
|
|
45
|
+
By default AZM writes the primary output plus useful side artifacts using the
|
|
46
|
+
same base path.
|
|
47
|
+
|
|
48
|
+
| Artifact | Meaning |
|
|
49
|
+
| -------------- | -------------------------------- |
|
|
50
|
+
| `.hex` | Intel HEX output |
|
|
51
|
+
| `.bin` | flat binary output |
|
|
52
|
+
| `.lst` | listing with bytes and symbols |
|
|
53
|
+
| `.d8.json` | Debug80 map |
|
|
54
|
+
| `.z80` | lowered assembler source |
|
|
55
|
+
| `.regcare.txt` | register-care report |
|
|
56
|
+
| `.asmi` | inferred register-care interface |
|
|
57
|
+
|
|
58
|
+
Disable standard artifacts when they are not needed:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
azm --nolist --nod8m program.asm
|
|
62
|
+
azm --nobin --nohex --reg-report --rc audit program.asm
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Options
|
|
66
|
+
|
|
67
|
+
| Option | Meaning |
|
|
68
|
+
| --------------------------------------------- | -------------------------------------------------------------------- |
|
|
69
|
+
| `-o, --output <file>` | Primary output path. The extension must match `--type`. |
|
|
70
|
+
| `-t, --type <hex\|bin>` | Primary output type. Default: `hex`. |
|
|
71
|
+
| `-n, --nolist` | Do not write `.lst`. |
|
|
72
|
+
| `--nobin` | Do not write `.bin`. |
|
|
73
|
+
| `--nohex` | Do not write `.hex`. |
|
|
74
|
+
| `--nod8m` | Do not write `.d8.json`. |
|
|
75
|
+
| `--asm80` | Write lowered assembler source as `.z80`. |
|
|
76
|
+
| `--case-style <mode>` | Lint opcode/register case: `off`, `upper`, `lower`, or `consistent`. |
|
|
77
|
+
| `--rc, --register-care <mode>` | Register-care mode: `off`, `audit`, `warn`, `error`, or `strict`. |
|
|
78
|
+
| `--reg-report, --emit-register-report` | Write `.regcare.txt`. |
|
|
79
|
+
| `--reg-interface, --emit-register-interface` | Write inferred `.asmi` interface. |
|
|
80
|
+
| `--contracts, --annotate-register-contracts` | Update AZMDoc contract comments in source. |
|
|
81
|
+
| `--fix` | Apply conservative register-care source fixes and update contracts. |
|
|
82
|
+
| `--accept-out <routine:carrier>` | Promote an inferred output candidate while annotating. |
|
|
83
|
+
| `--interface <file>` | Load external register-care contracts from `.asmi`. Repeatable. |
|
|
84
|
+
| `--reg-profile, --register-profile <profile>` | Register-care profile. Currently `mon3`. |
|
|
85
|
+
| `--aliases <file>` | Load project directive alias JSON. Repeatable. |
|
|
86
|
+
| `-I, --include <dir>` | Add an include search path. Repeatable. |
|
|
87
|
+
| `-V, --version` | Print package version. |
|
|
88
|
+
| `-h, --help` | Print CLI help. |
|
|
89
|
+
|
|
90
|
+
## Register-Care Examples
|
|
91
|
+
|
|
92
|
+
Audit inferred contracts without failing the build:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
azm --rc audit --reg-report program.asm
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Treat contract conflicts as build failures:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
azm --rc error program.asm
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Generate compact AZMDoc blocks in source:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
azm --contracts --rc audit program.asm
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Load external contracts for monitor/library routines:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
azm --rc error --interface mon3.asmi program.asm
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## `.asmi` Interfaces
|
|
117
|
+
|
|
118
|
+
External register-care interfaces are plain metadata files:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
extern MON_PRINT_CHAR
|
|
122
|
+
in A
|
|
123
|
+
clobbers A
|
|
124
|
+
end
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Use `.asmi` for these files so they are clearly distinct from assembler source.
|
|
128
|
+
|
|
129
|
+
## Exit Behavior
|
|
130
|
+
|
|
131
|
+
The CLI exits with a non-zero status when parsing, semantic checks, register-care
|
|
132
|
+
mode, lowering, or artifact writing reports an error. Diagnostics are printed
|
|
133
|
+
with file, line, column, severity, and diagnostic ID where that information is
|
|
134
|
+
available.
|