From 476178ee7c64ef246372822f289b6718283e75e7 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Mon, 23 Dec 2019 17:16:46 -0500 Subject: [PATCH] zasm: parseExpr --> parseExprDE --- apps/zasm/avr.asm | 35 ++++++++++++---------- apps/zasm/directive.asm | 66 +++++++++++++++++++++-------------------- apps/zasm/instr.asm | 60 +++++++++++++++---------------------- 3 files changed, 77 insertions(+), 84 deletions(-) diff --git a/apps/zasm/avr.asm b/apps/zasm/avr.asm index 13aaa9e..2f559bd 100644 --- a/apps/zasm/avr.asm +++ b/apps/zasm/avr.asm @@ -643,14 +643,15 @@ _readK8: jr _readExpr _readDouble: - push ix - call parseExpr + push de + call parseExprDE jr nz, .end - push ix \ pop bc + ld b, d + ld c, e ; BC is already set. For good measure, let's set A to BC's MSB ld a, b .end: - pop ix + pop de ret _readk7: @@ -705,6 +706,7 @@ _readR4: ; read a rXX argument and return register number in A. ; Set Z for success. _readR5: + push de push ix ld a, (hl) call upcase @@ -713,43 +715,44 @@ _readR5: inc hl call parseDecimal jr nz, .end + push ix \ pop de ld a, 31 - call _IX2A + call _DE2A .end: pop ix + pop de ret -; Put IX's LSB into A and, additionally, ensure that the new value is <= +; Put DE's LSB into A and, additionally, ensure that the new value is <= ; than what was previously in A. ; Z for success. -_IX2A: - push ix \ pop hl - cp l - jp c, unsetZ ; A < L - ld a, h +_DE2A: + cp e + jp c, unsetZ ; A < E + ld a, d or a ret nz ; should be zero - ld a, l + ld a, e ; Z set from "or a" ret ; Read expr and return success only if result in under number given in A ; Z for success _readExpr: - push ix + push de push bc ld b, a - call parseExpr + call parseExprDE jr nz, .end ld a, b - call _IX2A + call _DE2A jr nz, .end or c ld c, a cp a ; ensure Z .end: pop bc - pop ix + pop de ret ; Parse one of the following: X, Y, Z, X+, Y+, Z+, -X, -Y, -Z. diff --git a/apps/zasm/directive.asm b/apps/zasm/directive.asm index 0b5da5d..303dea3 100644 --- a/apps/zasm/directive.asm +++ b/apps/zasm/directive.asm @@ -40,6 +40,7 @@ dirHandlers: .dw handleBIN handleDB: + push de push hl .loop: call readWord @@ -47,20 +48,21 @@ handleDB: ld hl, scratchpad call enterDoubleQuotes jr z, .stringLiteral - call parseExpr + call parseExprDE jr nz, .badarg - push ix \ pop hl - ld a, h + ld a, d or a ; cp 0 jr nz, .overflow ; not zero? overflow - ld a, l + ld a, e call ioPutB jr nz, .ioError .stopStrLit: call readComma jr z, .loop cp a ; ensure Z +.end: pop hl + pop de ret .ioError: ld a, SHELL_ERR_IO_ERROR @@ -74,9 +76,8 @@ handleDB: .overflow: ld a, ERR_OVFL .error: - call unsetZ - pop hl - ret + or a ; unset Z + jr .end .stringLiteral: ld a, (hl) @@ -89,24 +90,26 @@ handleDB: jr .stringLiteral handleDW: + push de push hl .loop: call readWord jr nz, .badfmt ld hl, scratchpad - call parseExpr + call parseExprDE jr nz, .badarg - push ix \ pop hl - ld a, l + ld a, e call ioPutB jr nz, .ioError - ld a, h + ld a, d call ioPutB jr nz, .ioError call readComma jr z, .loop cp a ; ensure Z +.end: pop hl + pop de ret .ioError: ld a, SHELL_ERR_IO_ERROR @@ -117,9 +120,8 @@ handleDW: .badarg: ld a, ERR_BAD_ARG .error: - call unsetZ - pop hl - ret + or a ; unset Z + jr .end handleEQU: call zasmIsLocalPass ; Are we in local pass? Then ignore all .equ. @@ -178,14 +180,17 @@ handleEQU: jp readWord handleORG: + push de call readWord jr nz, .badfmt - call parseExpr + call parseExprDE jr nz, .badarg - push ix \ pop hl + ex de, hl ld (DIREC_LASTVAL), hl call zasmSetOrg cp a ; ensure Z +.end: + pop de ret .badfmt: ld a, ERR_BAD_FMT @@ -193,31 +198,28 @@ handleORG: .badarg: ld a, ERR_BAD_ARG .error: - call unsetZ - ret + or a ; unset Z + jr .end handleFIL: call readWord jr nz, .badfmt - call parseExpr + call parseExprDE jr nz, .badarg - push bc ; --> lvl 1 - push ix \ pop bc - ld a, b + ld a, d cp 0xd0 jr nc, .overflow .loop: - ld a, b - or c + ld a, d + or e jr z, .loopend xor a call ioPutB jr nz, .ioError - dec bc + dec de jr .loop .loopend: cp a ; ensure Z - pop bc ; <-- lvl 1 ret .ioError: ld a, SHELL_ERR_IO_ERROR @@ -229,11 +231,11 @@ handleFIL: ld a, ERR_BAD_ARG jp unsetZ .overflow: - pop bc ; <-- lvl 1 ld a, ERR_OVFL jp unsetZ handleOUT: + push de push hl ; Read our expression call readWord @@ -241,12 +243,11 @@ handleOUT: call zasmIsFirstPass ; No .out during first pass jr z, .end ld hl, scratchpad - call parseExpr + call parseExprDE jr nz, .badarg - push ix \ pop hl - ld a, h + ld a, d out (ZASM_DEBUG_PORT), a - ld a, l + ld a, e out (ZASM_DEBUG_PORT), a jr .end .badfmt: @@ -255,9 +256,10 @@ handleOUT: .badarg: ld a, ERR_BAD_ARG .error: - call unsetZ + or a ; unset Z .end: pop hl + pop de ret handleINC: diff --git a/apps/zasm/instr.asm b/apps/zasm/instr.asm index 7e98f10..7cfdea5 100644 --- a/apps/zasm/instr.asm +++ b/apps/zasm/instr.asm @@ -146,7 +146,7 @@ parseIXY: ; any argspec (A == 0 means arg is empty). A return value of 0xff means an ; error. ; -; If the parsed argument is a number constant, 'N' is returned and IX contains +; If the parsed argument is a number constant, 'N' is returned and DE contains ; the value of that constant. parseArg: call strlen @@ -154,13 +154,8 @@ parseArg: ret z ; empty string? A already has our result: 0 push bc - push de push hl - ; We always initialize IX to zero so that non-numerical args end up with - ; a clean zero. - ld ix, 0 - ld de, argspecTbl ; DE now points the the "argspec char" part of the entry, but what ; we're comparing in the loop is the string next to it. Let's offset @@ -181,7 +176,7 @@ parseArg: ; (HL) has no parens call .maybeParseExpr jr nz, .nomatch - ; We have a proper number in no parens. Number in IX. + ; We have a proper number in no parens. Number in DE. ld a, 'N' jr .end .withParens: @@ -208,23 +203,20 @@ parseArg: .parseNumberInParens: call .maybeParseExpr jr nz, .nomatch - ; We have a proper number in parens. Number in IX - ; is '-' in B? if yes, we need to negate the low part of IX + ; We have a proper number in parens. Number in DE + ; is '-' in B? if yes, we need to negate the low part of DE ld a, b cp '-' - jr nz, .dontNegateIX - ; we need to negate the low part of IX + jr nz, .dontNegateDE + ; we need to negate the low part of DE ; TODO: when parsing routines properly support unary negative numbers, ; We could replace this complicated scheme below with a nice hack where ; we start parsing our displacement number at the '+' and '-' char. - ; HL isn't needed anymore and can be destroyed. - push ix \ pop hl - ld a, l + ld a, e neg - ld l, a - push hl \ pop ix -.dontNegateIX: + ld e, a +.dontNegateDE: ld a, c ; M, x, or y jr .end .nomatch: @@ -235,9 +227,13 @@ parseArg: ; found the matching argspec row. Our result is one byte left of DE. dec de ld a, (de) + + ; When we have non-numerical args, we set DE to zero to have a clean + ; result. + ld de, 0 + .end: pop hl - pop de pop bc ret @@ -247,9 +243,10 @@ parseArg: ; harmless, but in some cases it causes false failures. For example, ; a "-" operator can cause is to falsely overflow and generate ; truncation error. + ld de, 0 ; in first pass, return a clean zero call zasmIsFirstPass ret z - jp parseExpr + jp parseExprDE ; Returns, with Z, whether A is a groupId isGroupId: @@ -817,27 +814,18 @@ spitUpcode: ld (INS_UPCODE+2), a ret -; Parse argument in (HL) and place it in (DE) -; DE is not preserved +; Parse argument in (HL) and place it in (IX) ; Sets Z on success, reset on error. processArg: call parseArg cp 0xff jr z, .error - ld (de), a - ; When A is a number, IX is set with the value of that number. Because + ld (ix), a + ; When A is a number, DE is set with the value of that number. Because ; We don't use the space allocated to store those numbers in any other - ; occasion, we store IX there unconditonally, LSB first. - inc de - ex (sp), ix ; (SP) is kept in IX and will be restored - ex (sp), hl ; old HL is on (SP) - ld a, l - ld (de), a - inc de - ld a, h - ld (de), a - ex (sp), hl ; restore old HL from (SP) - ex (sp), ix ; restore old (SP) from IX + ; occasion, we store DE there unconditonally, LSB first. + ld (ix+1), e + ld (ix+2), d cp a ; ensure Z ret .error: @@ -860,14 +848,14 @@ parseInstruction: ld (INS_CURARG2), a call readWord jr nz, .nomorearg - ld de, INS_CURARG1 + ld ix, INS_CURARG1 call processArg jr nz, .end ; A is set to error, Z is unset call readComma jr nz, .nomorearg call readWord jr nz, .badfmt - ld de, INS_CURARG2 + ld ix, INS_CURARG2 call processArg jr nz, .end ; A is set to error, Z is unset .nomorearg: