mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 12:28:06 +11:00
zasm: Add support for (NN) constants
This commit is contained in:
parent
e1d6178457
commit
c5c8369ce9
@ -4,7 +4,7 @@
|
|||||||
; Number of rows in the argspec table
|
; Number of rows in the argspec table
|
||||||
ARGSPEC_TBL_CNT .equ 27
|
ARGSPEC_TBL_CNT .equ 27
|
||||||
; Number of rows in the primary instructions table
|
; Number of rows in the primary instructions table
|
||||||
INSTR_TBLP_CNT .equ 56
|
INSTR_TBLP_CNT .equ 58
|
||||||
; size in bytes of each row in the primary instructions table
|
; size in bytes of each row in the primary instructions table
|
||||||
INSTR_TBLP_ROWSIZE .equ 8
|
INSTR_TBLP_ROWSIZE .equ 8
|
||||||
|
|
||||||
@ -33,6 +33,45 @@ rlaX:
|
|||||||
djnz .loop
|
djnz .loop
|
||||||
ret
|
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.
|
||||||
|
enterParens:
|
||||||
|
ld a, (hl)
|
||||||
|
cp '('
|
||||||
|
ret nz ; nothing to do
|
||||||
|
push hl
|
||||||
|
ld a, 0 ; look for null char
|
||||||
|
; advance until we get null
|
||||||
|
.loop:
|
||||||
|
cpi
|
||||||
|
jp z, .found
|
||||||
|
jr .loop
|
||||||
|
.found:
|
||||||
|
dec hl ; cpi over-advances. go back to null-char
|
||||||
|
dec hl ; looking at the last char before null
|
||||||
|
ld a, (hl)
|
||||||
|
cp ')'
|
||||||
|
jr nz, .doNotEnter
|
||||||
|
; We have parens. While we're here, let's put a null
|
||||||
|
xor a
|
||||||
|
ld (hl), a
|
||||||
|
pop hl ; back at the beginning. Let's advance.
|
||||||
|
inc hl
|
||||||
|
cp a ; ensure Z
|
||||||
|
ret ; we're good!
|
||||||
|
.doNotEnter:
|
||||||
|
pop hl
|
||||||
|
call unsetZ
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Checks whether A is 'N' or 'M'
|
||||||
|
checkNOrM:
|
||||||
|
cp 'N'
|
||||||
|
ret z
|
||||||
|
cp 'M'
|
||||||
|
ret
|
||||||
|
|
||||||
; Parse the decimal char at A and extract it's 0-9 numerical value. Put the
|
; Parse the decimal char at A and extract it's 0-9 numerical value. Put the
|
||||||
; result in A.
|
; result in A.
|
||||||
;
|
;
|
||||||
@ -49,10 +88,20 @@ parseDecimal:
|
|||||||
; Parses the string at (HL) and returns the 16-bit value in IX.
|
; 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
|
; 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.
|
; number is invalid. If the number is valid, Z is set, otherwise, unset.
|
||||||
|
; If (HL) contains a number inside parens, we properly enter into it.
|
||||||
|
; Upon successful return, A is set to 'N' for a parens-less number, 'M' for
|
||||||
|
; a number inside parens.
|
||||||
parseNumber:
|
parseNumber:
|
||||||
push hl
|
push hl
|
||||||
push de
|
push de
|
||||||
|
push bc
|
||||||
|
|
||||||
|
; Let's see if we have parens and already set the A result in B.
|
||||||
|
ld b, 'N' ; if no parens
|
||||||
|
call enterParens
|
||||||
|
jr nz, .noparens
|
||||||
|
ld b, 'M' ; we have parens and entered it.
|
||||||
|
.noparens:
|
||||||
ld ix, 0
|
ld ix, 0
|
||||||
.loop:
|
.loop:
|
||||||
ld a, (hl)
|
ld a, (hl)
|
||||||
@ -87,6 +136,8 @@ parseNumber:
|
|||||||
.error:
|
.error:
|
||||||
call unsetZ
|
call unsetZ
|
||||||
.end:
|
.end:
|
||||||
|
ld a, b
|
||||||
|
pop bc
|
||||||
pop de
|
pop de
|
||||||
pop hl
|
pop hl
|
||||||
ret
|
ret
|
||||||
@ -262,13 +313,12 @@ parseArg:
|
|||||||
call JUMP_ADDDE
|
call JUMP_ADDDE
|
||||||
djnz .loop1
|
djnz .loop1
|
||||||
|
|
||||||
; We exhausted the argspecs. Let's see if it's a number
|
; We exhausted the argspecs. Let's see if it's a number. This sets
|
||||||
|
; A to 'N' or 'M'
|
||||||
call parseNumber
|
call parseNumber
|
||||||
jr nz, .notanumber
|
jr z, .end ; Alright, we have a parsed number in IX. We're
|
||||||
; Alright, we have a parsed number in IX. We're done.
|
; done.
|
||||||
ld a, 'N'
|
; not a number
|
||||||
jr .end
|
|
||||||
.notanumber:
|
|
||||||
ld a, 0xff
|
ld a, 0xff
|
||||||
jr .end
|
jr .end
|
||||||
.found:
|
.found:
|
||||||
@ -375,16 +425,18 @@ matchArg:
|
|||||||
cp a, (hl)
|
cp a, (hl)
|
||||||
ret z
|
ret z
|
||||||
; not an exact match, let's check for numerical constants.
|
; not an exact match, let's check for numerical constants.
|
||||||
|
call JUMP_UPCASE
|
||||||
cp 'N'
|
cp 'N'
|
||||||
jr z, .expectsNumber
|
jr z, .expectsNumber
|
||||||
cp 'n'
|
cp 'M'
|
||||||
jr z, .expectsNumber
|
jr z, .expectsNumber
|
||||||
jr .notNumber
|
jr .notNumber
|
||||||
.expectsNumber:
|
.expectsNumber:
|
||||||
ld a, (hl)
|
ld a, (hl)
|
||||||
cp 'N' ; In parsed arg, we don't have 'n', only 'N'
|
call checkNOrM ; In parsed arg, we don't have 'n' or 'm', only
|
||||||
ret ; whether we match or not, the result of Z is the good
|
; 'N' and 'M'
|
||||||
; one
|
ret ; whether we match or not, the result of Z is
|
||||||
|
; the good one.
|
||||||
.notNumber:
|
.notNumber:
|
||||||
; A bit of a delicate situation here: we want A to go in H but also
|
; A bit of a delicate situation here: we want A to go in H but also
|
||||||
; (HL) to go in A. If not careful, we overwrite each other. EXX is
|
; (HL) to go in A. If not careful, we overwrite each other. EXX is
|
||||||
@ -516,16 +568,20 @@ parseLine:
|
|||||||
push hl ; we use HL to point to the currently read arg
|
push hl ; we use HL to point to the currently read arg
|
||||||
ld a, (ix+4) ; first argspec
|
ld a, (ix+4) ; first argspec
|
||||||
ld hl, curArg1
|
ld hl, curArg1
|
||||||
cp 'N'
|
call checkNOrM
|
||||||
jr z, .withWord
|
jr z, .withWord
|
||||||
cp 'n'
|
cp 'n'
|
||||||
jr z, .withByte
|
jr z, .withByte
|
||||||
|
cp 'm'
|
||||||
|
jr z, .withByte
|
||||||
ld a, (ix+5) ; second argspec
|
ld a, (ix+5) ; second argspec
|
||||||
ld hl, curArg2
|
ld hl, curArg2
|
||||||
cp 'N'
|
call checkNOrM
|
||||||
jr z, .withWord
|
jr z, .withWord
|
||||||
cp 'n'
|
cp 'n'
|
||||||
jr z, .withByte
|
jr z, .withByte
|
||||||
|
cp 'm'
|
||||||
|
jr z, .withByte
|
||||||
; nope, no number, aright, only one opcode
|
; nope, no number, aright, only one opcode
|
||||||
ld a, 1
|
ld a, 1
|
||||||
jr .end
|
jr .end
|
||||||
@ -653,6 +709,7 @@ instrTBlPrimary:
|
|||||||
.db "EX",0,0, 'd', 'h', 0, 0xeb ; EX DE, HL
|
.db "EX",0,0, 'd', 'h', 0, 0xeb ; EX DE, HL
|
||||||
.db "EXX", 0, 0, 0, 0, 0xd9 ; EXX
|
.db "EXX", 0, 0, 0, 0, 0xd9 ; EXX
|
||||||
.db "HALT", 0, 0, 0, 0x76 ; HALT
|
.db "HALT", 0, 0, 0, 0x76 ; HALT
|
||||||
|
.db "IN",0,0, 'A', 'm', 0, 0xdb ; IN A, (n)
|
||||||
.db "INC", 0, 'l', 0, 0, 0x34 ; INC (HL)
|
.db "INC", 0, 'l', 0, 0, 0x34 ; INC (HL)
|
||||||
.db "INC", 0, 0xb, 0, 3, 0b00000100 ; INC r
|
.db "INC", 0, 0xb, 0, 3, 0b00000100 ; INC r
|
||||||
.db "INC", 0, 0x3, 0, 4, 0b00000011 ; INC s
|
.db "INC", 0, 0x3, 0, 4, 0b00000011 ; INC s
|
||||||
@ -671,6 +728,7 @@ instrTBlPrimary:
|
|||||||
.db "NOP", 0, 0, 0, 0, 0x00 ; NOP
|
.db "NOP", 0, 0, 0, 0, 0x00 ; NOP
|
||||||
.db "OR",0,0, 'l', 0, 0, 0xb6 ; OR (HL)
|
.db "OR",0,0, 'l', 0, 0, 0xb6 ; OR (HL)
|
||||||
.db "OR",0,0, 0xb, 0, 0, 0b10110000 ; OR r
|
.db "OR",0,0, 0xb, 0, 0, 0b10110000 ; OR r
|
||||||
|
.db "OUT", 0, 'm', 'A', 0, 0xd3 ; OUT (n), A
|
||||||
.db "POP", 0, 0x1, 0, 4, 0b11000001 ; POP qq
|
.db "POP", 0, 0x1, 0, 4, 0b11000001 ; POP qq
|
||||||
.db "PUSH", 0x1, 0, 4, 0b11000101 ; PUSH qq
|
.db "PUSH", 0x1, 0, 4, 0b11000101 ; PUSH qq
|
||||||
.db "RET", 0, 0xa, 0, 3, 0b11000000 ; RET cc
|
.db "RET", 0, 0xa, 0, 3, 0b11000000 ; RET cc
|
||||||
|
Loading…
Reference in New Issue
Block a user