;;; -*- TI-Asm -*- ;;; ;;; Mimas - Assembly language IDE for the TI-83 Plus ;;; ;;; Copyright (C) 2010 Benjamin Moody ;;; ;;; This program is free software: you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation; either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program. If not, see . ;; FormatExpr: ;; ;; Convert an expression into an ASCII string. Note that if the ;; expression is too complicated to fit in the buffer, it will ;; generally be silently truncated. ;; ;; Input: ;; - IX = expression pointer ;; - C = expression byte count + 1 ;; - B = level of parenthesization for binary operators (0 = never; ;; FFh = always) ;; - formatTemplate, (iy + asm_Flag3) = 1 to allow X_ARGVAL ;; expressions to refer to template arguments ;; ;; Output: ;; - String inserted into the editTextBuffer at the current cursor ;; position ;; - IX and C updated ;; - Carry flag set if expression incomplete ;; ;; Destroys: ;; - AF, B, DE, HL ;; - OP1-OP6 FormatExprDefault: ld b,0 FormatExpr: dec c scf ret z ld a,(ix) inc ix ld h,a add a,a jq c,FormatExpr_Dec6OrOperator ;; 0xxxxxxx add a,a jr c,FormatExpr_Constant ;; 00xxxxxx xxxxxxxx: symbol value dec c scf ret z ld l,(ix) inc ix call GetProgramSymbolInfo call c,Error_Bytecode call ProgramOffsetToAddress FormatExpr_Symbol: push bc ld de,OP1 push de call SymbolStringToRAM ld e,b ld d,0 ;; check if symbol will fit in buffer -- assuming worst case ;; of 50% compression ld hl,(editCursor) push hl add hl,de add hl,de ld de,(editTail) sbc hl,de pop de pop hl jr nc,FormatExpr_Invalid call UnpackSymbolString pop bc ld (editCursor),de or a ret FormatExpr_Invalid: pop bc ld hl,3F3Fh jq_ FormatExpr_TwoChars FormatExpr_Constant: ;; 01xxxxxx add a,a jq c,FormatExpr_WordConstant ;; 010xxxxx add a,a jr c,FormatExpr_ByteConstant ;; 0100xxxx: special constant ld hl,5043h jr z,FormatExpr_TwoChars ld hl,LPCStr cp low(X_LOADPC * 16) jq z,TextBufInsertString ld hl,5B42h cp low(X_PREV_ANON * 16) jr z,FormatExpr_TwoChars cp low(X_NEXT_ANON * 16) call nz,Error_Bytecode ld l,46h FormatExpr_TwoChars: ld a,h call TextBufInsertChar ld a,l jq_ TextBufInsertChar FormatExpr_ByteConstant: ;; 0101xxxx xxxxxxxx: byte constant dec c scf ret z ld l,(ix) inc ix ld a,h cp X_ENUM8 jr nc,FormatExpr_Enum8 ld h,0 and 0Fh ; X_DEC8 jr z,FormatExpr_Dec dec a ; X_HEX8 jr z,FormatExpr_Hex8 dec a ; X_OCT8 jr z,FormatExpr_Oct8 dec a ; X_BIN8 jr z,FormatExpr_Bin8 dec a ; X_CHAR jr z,FormatExpr_Char jr FormatExpr_Hex8 FormatExpr_Enum8: push bc call EnumValueToName pop bc jq z,TextBufInsertSymbolString FormatExpr_Hex8: TextBufInsertPrefixedHex8: ld a,'$' call TextBufInsertChar FormatExpr_Hex8_L: ld a,l jq_ TextBufInsertHex8 FormatExpr_Dec_Recurse: ld a,h or l ret z FormatExpr_Dec: BCALL _DivHLBy10 push af call FormatExpr_Dec_Recurse pop af add a,'0' FormatExpr_SingleChar: jq_ TextBufInsertChar FormatExpr_Oct8: ld a,'@' call TextBufInsertChar push bc ld h,l srl h rr l ld b,3 FormatExpr_Oct_Loop: ld a,'0' / 8 add hl,hl rla add hl,hl rla add hl,hl rla call TextBufInsertChar djnz FormatExpr_Oct_Loop pop bc ret FormatExpr_Bin8: ld a,'%' call TextBufInsertChar FormatExpr_Bin8_L: ld a,l jq_ TextBufInsertBin8 FormatExpr_Char: ld a,Lapostrophe call TextBufInsertChar ld a,l call TextBufInsertQuotedChar ld a,Lapostrophe jr FormatExpr_SingleChar FormatExpr_Dec6: ld a,h and 3Fh ld l,a ld h,0 jr FormatExpr_Dec FormatExpr_WordConstant: add a,a call c,Error_Bytecode ;; 0110xxxx xxxxxxxx xxxxxxxx: word constant dec c scf ret z dec c ret z ld a,h ld l,(ix) inc ix ld h,(ix) inc ix and 0Fh ; X_DEC16 jr z,FormatExpr_Dec dec a ; X_HEX16 jr z,FormatExpr_Hex16 dec a ; X_OCT16 jr z,FormatExpr_Oct16 dec a ; X_BIN16 jr z,FormatExpr_Bin16 dec a ; X_ROMCALL jr z,FormatExpr_ROMCall dec a ; X_SYSADDR jr nz,FormatExpr_Hex16 push bc call SysAddressToName pop bc jq z,TextBufInsertSymbolString FormatExpr_Hex16: ld a,'$' call TextBufInsertChar TextBufInsertHex16: ld a,h call TextBufInsertHex8 jq_ FormatExpr_Hex8_L FormatExpr_Oct16: ld a,'@' call TextBufInsertChar ld a,'0' / 2 add hl,hl rla call TextBufInsertChar push bc ld b,5 jr FormatExpr_Oct_Loop FormatExpr_Bin16: ld a,'%' call TextBufInsertChar ld a,h call TextBufInsertBin8 jr FormatExpr_Bin8_L FormatExpr_ROMCall: push bc call ROMCallAddressToName pop bc jr nz,FormatExpr_Hex16 ld a,'_' call TextBufInsertChar jq_ TextBufInsertSymbolString FormatExpr_Dec6OrOperator: ;; 1xxxxxxx add a,a jr c,FormatExpr_Dec6 ;; 10xxxxxx add a,a jq c,FormatExpr_Binary ;; 100xxxxx add a,a call nc,Error_Bytecode ;; 1001xxxx : unary operator ld a,h and 0Fh ld h,'l' jr z,FormatExpr_UnaryLSBMSB dec a ld h,'m' jr z,FormatExpr_UnaryLSBMSB dec a ld h,Lneg jq z,FormatExpr_UnaryOpChar dec a ld h,'~' jr z,FormatExpr_UnaryOpChar dec a ld h,'!' jr z,FormatExpr_UnaryOpChar dec a jr z,FormatExpr_UnaryParen dec a jr z,FormatExpr_UnaryRegValue dec a call nz,Error_Bytecode bit formatTemplate,(iy + asm_Flag3) call z,Error_Bytecode ;; template argument dec c scf ret z ld a,(ix) inc ix cp X_DEC6 call c,Error_Bytecode and 3 add a,a add a,low(formatArgPtr0) ld l,a ld h,high(formatArgPtr0) ; call LdHLInd ld a,(hl) inc hl ld h,(hl) ld l,a res formatTemplate,(iy + asm_Flag3) push ix push bc call StackCheck push hl pop ix ld c,64 call FormatExpr pop bc pop ix set formatTemplate,(iy + asm_Flag3) or a ret FormatExpr_UnaryOpChar: ld a,h call TextBufInsertChar ld b,0FFh jq_ FormatExpr FormatExpr_UnaryLSBMSB: ld a,h call TextBufInsertChar ld hl,7362h call FormatExpr_TwoChars ld b,-1 FormatExpr_UnaryParen: ld a,'(' call TextBufInsertChar ld b,0 FormatExpr_OperatorArgAndParen: call StackCheck call FormatExpr ret c ld a,')' jq_ TextBufInsertChar FormatExpr_UnaryRegValue: ;; register # dec c scf ret z ld a,(ix) inc ix cp X_DEC6 jr nc,FormatExpr_RegNameLiteral cp X_ARGVAL call nz,Error_Bytecode ;; FIXME: clean this up to make it more general; perhaps fix ;; EvalExpr so it can be used at all times, not just while ;; assembling. Also note this partly duplicates code above ;; (..._TemplateSubst) bit formatTemplate,(iy + asm_Flag3) call z,Error_Bytecode dec c scf ret z ld a,(ix) inc ix cp 0C0h call c,Error_Bytecode and 3 add a,a add a,low(formatArgPtr0) ld l,a ld h,high(formatArgPtr0) ; call LdHLInd ld a,(hl) inc hl ld h,(hl) ld l,a ld a,(hl) cp X_DEC6 call c,Error_Bytecode FormatExpr_RegNameLiteral: push bc ld hl,regNameStrings ld bc,regNameStringsSize cpir pop bc call nz,Error_Bytecode jq_ TextBufInsertString FormatExpr_Binary: ;; 101xxxxx : binary operator ld a,h add a,a add a,low(binaryOperatorParenTable - 2 * X_BINARY) ld e,a ld d,high(binaryOperatorParenTable) ld a,(de) ld l,a ; L = this operator's paren class and b jr z,FormatExpr_Binary_NoParen ld a,'(' call TextBufInsertChar or a FormatExpr_Binary_NoParen: ;; zero flag clear if this operator is using parentheses push af inc de ld a,(de) ld b,a ; B = paren mask for left child or l ld l,a ; L = paren mask for right child push hl call StackCheck call FormatExpr pop hl jr c,FormatExpr_Binary_Error ld a,h cp X_OR + 1 call nc,Error_Bytecode cp X_LSHIFT ld d,'<' jr z,FormatExpr_BinaryShift cp X_RSHIFT ld d,'>' jr z,FormatExpr_BinaryShift add a,low(binaryOperatorCharTable - X_BINARY) ld e,a ld d,high(binaryOperatorCharTable) ld a,(de) jr FormatExpr_BinaryFinish FormatExpr_BinaryShift: ld a,d call TextBufInsertChar FormatExpr_BinaryFinish: call TextBufInsertChar ld b,l pop af jq z,FormatExpr jq_ FormatExpr_OperatorArgAndParen FormatExpr_Binary_Error: pop af scf ret