1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-01 17:30:55 +11:00
collapseos/apps/ed/cmd.asm
Virgil Dupras 289037a3dd lib/parse: make parseDecimal "tail" HL
HL, instead of being preserved, is set to the character following
the last read character.
2019-12-30 10:13:55 -05:00

151 lines
2.8 KiB
NASM

; cmd - parse and interpret command
;
; *** Consts ***
; address type
.equ ABSOLUTE 0
; handles +, - and ".". For +, easy. For -, addr is negative. For ., it's 0.
.equ RELATIVE 1
.equ EOF 2
; *** Variables ***
; An address is a one byte type and a two bytes line number (0-indexed)
.equ CMD_ADDR1 CMD_RAMSTART
.equ CMD_ADDR2 @+3
.equ CMD_TYPE @+3
.equ CMD_RAMEND @+1
; *** Code ***
; Parse command line that HL points to and set unit's variables
; Sets Z on success, unset on error.
cmdParse:
ld a, (hl)
cp 'q'
jr z, .simpleCmd
cp 'w'
jr z, .simpleCmd
ld ix, CMD_ADDR1
call .readAddr
ret nz
; Before we check for the existence of a second addr, let's set that
; second addr to the same value as the first. That's going to be its
; value if we have to ",".
ld a, (ix)
ld (CMD_ADDR2), a
ld a, (ix+1)
ld (CMD_ADDR2+1), a
ld a, (ix+2)
ld (CMD_ADDR2+2), a
ld a, (hl)
cp ','
jr nz, .noaddr2
inc hl
ld ix, CMD_ADDR2
call .readAddr
ret nz
.noaddr2:
; We expect HL (rest of the cmdline) to be a null char or an accepted
; cmd, otherwise it's garbage
ld a, (hl)
or a
jr z, .nullCmd
cp 'p'
jr z, .okCmd
cp 'd'
jr z, .okCmd
cp 'a'
jr z, .okCmd
cp 'i'
jr z, .okCmd
; unsupported cmd
ret ; Z unset
.nullCmd:
ld a, 'p'
.okCmd:
ld (CMD_TYPE), a
ret ; Z already set
.simpleCmd:
; Z already set
ld (CMD_TYPE), a
ret
; Parse the string at (HL) and sets its corresponding address in IX, properly
; considering implicit values (current address when nothing is specified).
; advances HL to the char next to the last parsed char.
; It handles "+" and "-" addresses such as "+3", "-2", "+", "-".
; Sets Z on success, unset on error. Line out of bounds isn't an error. Only
; overflows.
.readAddr:
ld a, (hl)
cp '+'
jr z, .plusOrMinus
cp '-'
jr z, .plusOrMinus
cp '.'
jr z, .dot
cp '$'
jr z, .eof
; inline parseDecimalDigit
add a, 0xff-'9'
sub 0xff-9
jr c, .notHandled
; straight number
ld a, ABSOLUTE
ld (ix), a
call parseDecimal
ret nz
dec de ; from 1-based to 0-base
jr .end
.dot:
inc hl ; advance cmd cursor
; the rest is the same as .notHandled
.notHandled:
; something else. It's probably our command. Our addr is therefore "."
ld a, RELATIVE
ld (ix), a
xor a ; sets Z
ld (ix+1), a
ld (ix+2), a
ret
.eof:
inc hl ; advance cmd cursor
ld a, EOF
ld (ix), a
ret ; Z set during earlier CP
.plusOrMinus:
push af ; preserve that + or -
ld a, RELATIVE
ld (ix), a
inc hl ; advance cmd cursor
ld a, (hl)
ld de, 1 ; if .pmNoSuffix
; inline parseDecimalDigit
add a, 0xff-'9'
sub 0xff-9
jr c, .pmNoSuffix
call parseDecimal ; --> DE
.pmNoSuffix:
pop af ; bring back that +/-
cp '-'
jr nz, .end
; we had a "-". Negate DE
push hl
ld hl, 0
sbc hl, de
ex de, hl
pop hl
.end:
; we still have to save DE in memory
ld (ix+1), e
ld (ix+2), d
cp a ; ensure Z
ret