From 5a6078df4d44ef1d5622373b7d921e3225575876 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Thu, 9 May 2019 22:14:11 -0400 Subject: [PATCH] zasm: add support for hex literals --- apps/zasm/literal.asm | 67 +++++++++++++++++++++++++++++++++++---- apps/zasm/tests/test1.asm | 3 +- tools/emul/zasm_glue.asm | 1 + tools/emul/zasm_user.asm | 1 + 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/apps/zasm/literal.asm b/apps/zasm/literal.asm index 54acbce..9457375 100644 --- a/apps/zasm/literal.asm +++ b/apps/zasm/literal.asm @@ -2,7 +2,7 @@ ; result in A. ; ; On success, the carry flag is reset. On error, it is set. -parseDecimal: +parseDecimalDigit: ; First, let's see if we have an easy 0-9 case cp '0' ret c ; if < '0', we have a problem @@ -12,10 +12,9 @@ parseDecimal: ccf ; invert C flag ret -; Parses the string at (HL) and returns the 16-bit value in IX. -; As soon as the number doesn't fit 16-bit any more, parsing stops and the -; number is invalid. If the number is valid, Z is set, otherwise, unset. -parseNumber: +; Parse string at (HL) as a decimal value and return value in IX under the +; same conditions as parseNumber. +parseDecimal: push hl push de push bc @@ -25,7 +24,7 @@ parseNumber: ld a, (hl) cp 0 jr z, .end ; success! - call parseDecimal + call parseDecimalDigit jr c, .error ; Now, let's add A to IX. First, multiply by 10. @@ -58,3 +57,59 @@ parseNumber: pop de pop hl ret + + +; Parse string at (HL) as a hexadecimal value and return value in IX under the +; same conditions as parseNumber. +parseHexadecimal: + push hl + xor a + ld ixh, a + inc hl ; get rid of "0x" + inc hl + call strlen + cp 3 + jr c, .single + cp 5 + jr c, .double + ; too long, error + jr .error +.double: + call JUMP_PARSEHEXPAIR ; moves HL to last char of pair + jr c, .error + inc hl ; now HL is on first char of next pair + ld ixh, a +.single: + call JUMP_PARSEHEXPAIR + jr c, .error + ld ixl, a + cp a ; ensure Z + jr .end +.error: + call JUMP_UNSETZ +.end: + pop hl + ret + +; Sets Z if (HL) has a '0x' or '0X' prefix. +hasHexPrefix: + ld a, (hl) + cp '0' + ret nz + push hl + inc hl + ld a, (hl) + cp 'x' + jr z, .end + cp 'X' +.end: + pop hl + ret + +; Parses the string at (HL) and returns the 16-bit value in IX. +; As soon as the number doesn't fit 16-bit any more, parsing stops and the +; number is invalid. If the number is valid, Z is set, otherwise, unset. +parseNumber: + call hasHexPrefix + jr z, parseHexadecimal + jr parseDecimal diff --git a/apps/zasm/tests/test1.asm b/apps/zasm/tests/test1.asm index db6c334..b746383 100644 --- a/apps/zasm/tests/test1.asm +++ b/apps/zasm/tests/test1.asm @@ -5,7 +5,8 @@ label1: ; comment .db 42 label2: - .dw 42 + .dw 0x42 .dw 3742 + .dw 0x3742 ld a, (label1) ld hl, label2 diff --git a/tools/emul/zasm_glue.asm b/tools/emul/zasm_glue.asm index d273cca..0258d15 100644 --- a/tools/emul/zasm_glue.asm +++ b/tools/emul/zasm_glue.asm @@ -12,6 +12,7 @@ jp upcase jp unsetZ jp intoDE jp findchar +jp parseHexPair init: di diff --git a/tools/emul/zasm_user.asm b/tools/emul/zasm_user.asm index 871cd47..6913d4d 100644 --- a/tools/emul/zasm_user.asm +++ b/tools/emul/zasm_user.asm @@ -6,6 +6,7 @@ JUMP_UPCASE .equ 0x0b JUMP_UNSETZ .equ 0x0e JUMP_INTODE .equ 0x11 JUMP_FINDCHAR .equ 0x14 +JUMP_PARSEHEXPAIR .equ 0x17 .equ USER_CODE 0x4000 .equ RAMSTART 0x6000