diff --git a/apps/zasm/main.asm b/apps/zasm/main.asm index 0a8d5d4..b7412cc 100644 --- a/apps/zasm/main.asm +++ b/apps/zasm/main.asm @@ -26,6 +26,7 @@ ; unsetZ ; intoDE ; intoHL +; writeHLinDE ; findchar ; parseHex ; parseHexPair diff --git a/apps/zasm/symbol.asm b/apps/zasm/symbol.asm index c3233e9..a986ec1 100644 --- a/apps/zasm/symbol.asm +++ b/apps/zasm/symbol.asm @@ -107,35 +107,32 @@ symIsLabelLocal: cp (hl) ret -; Place HL at the end of (SYM_CTX_NAMES) end (that is, at the point where we have two -; consecutive null chars. We return the index of that new name in A. +; Place HL at the end of (SYM_CTX_NAMES) end (that is, at the point where we +; have two consecutive null chars and DE at the corresponding position in +; SYM_CTX_VALUES). ; If we're within bounds, Z is set, otherwise unset. symNamesEnd: - push bc - push de + push ix - ld b, 0 + ld ix, (SYM_CTX_VALUES) ld hl, (SYM_CTX_NAMES) ld de, (SYM_CTX_NAMESEND) .loop: call _symNext jr nz, .success ; We've reached the end of the chain. + inc ix + inc ix ; Are we out of bounds? call cpHLDE - jr nc, .outOfBounds ; HL >= DE - djnz .loop - ; exhausted djnz? out of bounds -.outOfBounds: + jr c, .loop ; HL < DE + ; out of bounds call unsetZ jr .end .success: - ; Our index is 0 - B (if B is, for example 0xfd, A is 0x3) - xor a - sub b + push ix \ pop de ; our values pos goes in DE cp a ; ensure Z .end: - pop de - pop bc + pop ix ret ; Register label in (HL) (minus the ending ":") into the symbol registry and @@ -143,19 +140,16 @@ symNamesEnd: ; If successful, Z is set and A is the symbol index. Otherwise, Z is unset and ; A is an error code (SYM_ERR_*). symRegister: - push hl - push bc - push de + push hl ; will be used during processing. it's the symbol to add + push de ; will be used during processing. it's our value. ; First, let's get our strlen call strlen ld c, a ; save that strlen for later - ex de, hl ; symbol to add is now in DE call symNamesEnd jr nz, .error - ; A is our index. Save it - ex af, af' + ; Is our new name going to make us go out of bounds? push hl push de @@ -167,40 +161,33 @@ symRegister: pop hl jr nc, .error ; HL >= DE - ; HL point to where we want to add the string - ex de, hl ; symbol to add in HL, dest in DE + ; Success. At this point, we have: + ; HL -> where we want to add the string + ; DE -> where the value goes + ; SP -> value to register + ; SP+2 -> string to register + + ; Let's start with the value. + push hl \ pop ix ; save HL for later + pop hl ; value to register + call writeHLinDE ; write value where it goes. + + ; Good! now, the string. + pop hl ; string to register + push ix \ pop de ; string destination ; Copy HL into DE until we reach null char - ; C already have our strlen (minus null char). Let's prepare BC for - ; a LDIR. - inc c ; include null char - ld b, 0 - ldir ; copy C chars from HL to DE + call strcpyM ; We need to add a second null char to indicate the end of the name - ; list. DE is already correctly placed. - xor a + ; list. DE is already correctly placed, A is already zero ld (de), a - ; I'd say we're pretty good just about now. What we need to do is to - ; save the value in our original DE that is just on top of the stack - ; into the proper index in (SYM_CTX_VALUES). Our index, remember, is - ; currently in A'. - ex af, af' - pop de - push de ; push it right back to avoid stack imbalance - ld hl, (SYM_CTX_VALUES) - call addHL - call addHL ; twice because our values are words + ; Nothing to pop. We've already popped our stack in the lines above. + ret - ; Everything is set! DE is our value HL points to the proper index in - ; (SYM_CTX_VALUES). Let's just write it (little endian). - ld (hl), e - inc hl - ld (hl), d .error: ; Z already unset pop de - pop bc pop hl ret diff --git a/apps/zasm/util.asm b/apps/zasm/util.asm index d61fe25..41841f1 100644 --- a/apps/zasm/util.asm +++ b/apps/zasm/util.asm @@ -117,6 +117,27 @@ strcmp: ; early, set otherwise) ret +; Copy string from (HL) in (DE), that is, copy bytes until a null char is +; encountered. The null char is also copied. +; HL and DE point to the char right after the null char. +strcpyM: + ld a, (hl) + ld (de), a + inc hl + inc de + or a + jr nz, strcpyM + ret + +; Like strcpyM, but preserve HL and DE +strcpy: + push hl + push de + call strcpyM + pop de + pop hl + ret + ; If string at (HL) starts with ( and ends with ), "enter" into the parens ; (advance HL and put a null char at the end of the string) and set Z. ; Otherwise, do nothing and reset Z. diff --git a/tools/emul/zasm/glue.asm b/tools/emul/zasm/glue.asm index 46d449b..2ce84a6 100644 --- a/tools/emul/zasm/glue.asm +++ b/tools/emul/zasm/glue.asm @@ -16,6 +16,7 @@ jp upcase jp unsetZ jp intoDE jp intoHL +jp writeHLinDE jp findchar jp parseHex jp parseHexPair diff --git a/tools/emul/zasm/user.asm b/tools/emul/zasm/user.asm index ff39220..7717434 100644 --- a/tools/emul/zasm/user.asm +++ b/tools/emul/zasm/user.asm @@ -6,15 +6,16 @@ upcase .equ 0x0c unsetZ .equ 0x0f intoDE .equ 0x12 intoHL .equ 0x15 -findchar .equ 0x18 -parseHex .equ 0x1b -parseHexPair .equ 0x1e -blkSel .equ 0x21 -fsFindFN .equ 0x24 -fsOpen .equ 0x27 -fsGetC .equ 0x2a -fsSeek .equ 0x2d -fsTell .equ 0x30 +writeHLinDE .equ 0x18 +findchar .equ 0x1b +parseHex .equ 0x1e +parseHexPair .equ 0x21 +blkSel .equ 0x24 +fsFindFN .equ 0x27 +fsOpen .equ 0x2a +fsGetC .equ 0x2d +fsSeek .equ 0x30 +fsTell .equ 0x33 .equ FS_HANDLE_SIZE 8 .equ STDERR_PORT 0x04 diff --git a/tools/tests/unit/test_symbol.asm b/tools/tests/unit/test_symbol.asm index 9cf5604..b134b61 100644 --- a/tools/tests/unit/test_symbol.asm +++ b/tools/tests/unit/test_symbol.asm @@ -34,6 +34,16 @@ test: jp nz, fail call nexttest + ld a, 1 ; index of FOO + call symGetVal + ld a, d + or a + jp nz, fail + ld a, e + cp 43 + jp nz, fail + call nexttest + ; success xor a halt