apps/ed: refactoring
This commit is contained in:
parent
8cf68dc7ad
commit
2d9f74c2af
135
apps/ed/cmd.asm
Normal file
135
apps/ed/cmd.asm
Normal file
@ -0,0 +1,135 @@
|
||||
; 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 BOF 2
|
||||
.equ EOF 3
|
||||
|
||||
; *** Variables ***
|
||||
|
||||
; An address is a one byte type and a two bytes line number (0-indexed)
|
||||
.equ CMD_ADDR1 CMD_RAMSTART
|
||||
.equ CMD_ADDR2 CMD_ADDR1+3
|
||||
.equ CMD_TYPE CMD_ADDR2+3
|
||||
.equ CMD_RAMEND CMD_TYPE+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, .quit
|
||||
ld (CMD_TYPE), a
|
||||
ld ix, CMD_ADDR1
|
||||
jp .readAddr
|
||||
.quit:
|
||||
; 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
|
||||
call parseDecimalDigit
|
||||
jr c, .notHandled
|
||||
; straight number
|
||||
ld a, ABSOLUTE
|
||||
ld (ix), a
|
||||
call .parseDecimalM
|
||||
ret nz
|
||||
dec de ; from 1-based to 0-base
|
||||
jr .end
|
||||
.notHandled:
|
||||
; something else. Something we don't handle. Our addr is therefore "."
|
||||
ld a, RELATIVE
|
||||
ld (ix), a
|
||||
xor a ; sets Z
|
||||
ld (ix+1), a
|
||||
ld (ix+2), a
|
||||
ret
|
||||
.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
|
||||
call parseDecimalDigit
|
||||
jr c, .pmNoSuffix
|
||||
call .parseDecimalM ; --> 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 expect HL (rest of the cmdline) to be a null char, otherwise it's
|
||||
; garbage
|
||||
ld a, (hl)
|
||||
or a
|
||||
ret nz
|
||||
; we still have to save DE in memory
|
||||
ld (ix+1), e
|
||||
ld (ix+2), d
|
||||
ret
|
||||
|
||||
; call parseDecimal and set HL to the character following the last digit
|
||||
.parseDecimalM:
|
||||
push bc
|
||||
push ix
|
||||
push hl
|
||||
.loop:
|
||||
inc hl
|
||||
ld a, (hl)
|
||||
call parseDecimalDigit
|
||||
jr nc, .loop
|
||||
; We're at the first non-digit char. Let's save it because we're going
|
||||
; to temporarily replace it with a null.
|
||||
ld b, a
|
||||
xor a
|
||||
ld (hl), a
|
||||
; Now, let's go back to the beginning of the string and parse it.
|
||||
; but before we do this, let's save the end of string in DE
|
||||
ex de, hl
|
||||
pop hl
|
||||
call parseDecimal
|
||||
; Z is set properly at this point. nothing touches Z below.
|
||||
ld a, b
|
||||
ld (de), a
|
||||
ex de, hl ; put end of string back from DE to HL
|
||||
; Put addr in its final register, DE
|
||||
push ix \ pop de
|
||||
pop ix
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; Make (IX) point to addr 1
|
||||
cmdAddr1:
|
||||
ld ix, CMD_ADDR1
|
||||
ret
|
||||
|
||||
; Set A to CMD_TYPE
|
||||
cmdType:
|
||||
ld a, (CMD_TYPE)
|
||||
ret
|
@ -9,6 +9,8 @@
|
||||
#include "ed/io.asm"
|
||||
.equ BUF_RAMSTART IO_RAMEND
|
||||
#include "ed/buf.asm"
|
||||
.equ ED_RAMSTART BUF_RAMEND
|
||||
.equ CMD_RAMSTART BUF_RAMEND
|
||||
#include "ed/cmd.asm"
|
||||
.equ ED_RAMSTART CMD_RAMEND
|
||||
#include "ed/main.asm"
|
||||
|
||||
|
125
apps/ed/main.asm
125
apps/ed/main.asm
@ -86,118 +86,43 @@ edMain:
|
||||
; We're done. Process line.
|
||||
call printcrlf
|
||||
call stdioGetLine
|
||||
call .processLine
|
||||
ret z
|
||||
jr .mainLoop
|
||||
|
||||
; Sets Z if we need to quit
|
||||
.processLine:
|
||||
ld a, (hl)
|
||||
call cmdParse
|
||||
jr nz, .error
|
||||
call cmdType
|
||||
cp 'q'
|
||||
ret z
|
||||
call edReadAddr
|
||||
jr z, .processNumber
|
||||
jr .processError
|
||||
.processNumber:
|
||||
; number is in DE
|
||||
; We expect HL (rest of the cmdline) to be a null char, otherwise it's
|
||||
; garbage
|
||||
ld a, (hl)
|
||||
or a
|
||||
jr nz, .processError
|
||||
ex de, hl
|
||||
jr .doPrint
|
||||
|
||||
.doPrint:
|
||||
call cmdAddr1
|
||||
call edResolveAddr
|
||||
ld (ED_CURLINE), hl
|
||||
call bufGetLine
|
||||
jr nz, .processError
|
||||
jr nz, .error
|
||||
call printstr
|
||||
call printcrlf
|
||||
; continue to end
|
||||
.processEnd:
|
||||
call printcrlf
|
||||
jp unsetZ
|
||||
.processError:
|
||||
jr .mainLoop
|
||||
.error:
|
||||
ld a, '?'
|
||||
call stdioPutC
|
||||
call printcrlf
|
||||
jp unsetZ
|
||||
jr .mainLoop
|
||||
|
||||
; Parse the string at (HL) and sets its corresponding address in DE, 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.
|
||||
edReadAddr:
|
||||
ld a, (hl)
|
||||
cp '+'
|
||||
jr z, .plusOrMinus
|
||||
cp '-'
|
||||
jr z, .plusOrMinus
|
||||
call parseDecimalDigit
|
||||
jr c, .notHandled
|
||||
; straight number
|
||||
call .parseDecimalM ; Z has proper value
|
||||
dec de ; from 1-based to 0-base. 16bit doesn't affect flags.
|
||||
|
||||
; Transform an address "cmd" in IX into an absolute address in HL.
|
||||
edResolveAddr:
|
||||
ld a, (ix)
|
||||
cp RELATIVE
|
||||
jr z, .relative
|
||||
; absolute
|
||||
ld l, (ix+1)
|
||||
ld a, l
|
||||
ld h, (ix+2)
|
||||
ret
|
||||
.notHandled:
|
||||
; something else. Something we don't handle. Our addr is therefore
|
||||
; (ED_CURLINE).
|
||||
push hl
|
||||
.relative:
|
||||
ld hl, (ED_CURLINE)
|
||||
ex de, hl
|
||||
pop hl
|
||||
cp a ; ensure Z
|
||||
ret
|
||||
.plusOrMinus:
|
||||
push af ; preserve that + or -
|
||||
inc hl ; advance cmd cursor
|
||||
ld a, (hl)
|
||||
ld de, 1 ; if .pmNoSuffix
|
||||
call parseDecimalDigit
|
||||
jr c, .pmNoSuffix
|
||||
call .parseDecimalM ; --> DE
|
||||
.pmNoSuffix:
|
||||
pop af ; bring back that +/-
|
||||
push hl
|
||||
ld hl, (ED_CURLINE)
|
||||
cp '-'
|
||||
jr z, .pmIsMinus
|
||||
ld e, (ix+1)
|
||||
ld d, (ix+2)
|
||||
add hl, de
|
||||
jr .pmEnd
|
||||
.pmIsMinus:
|
||||
sbc hl, de
|
||||
.pmEnd:
|
||||
ex de, hl
|
||||
pop hl
|
||||
cp a ; ensure Z
|
||||
ret
|
||||
|
||||
; call parseDecimal and set HL to the character following the last digit
|
||||
.parseDecimalM:
|
||||
push bc
|
||||
push ix
|
||||
push hl
|
||||
.loop:
|
||||
inc hl
|
||||
ld a, (hl)
|
||||
call parseDecimalDigit
|
||||
jr nc, .loop
|
||||
; We're at the first non-digit char. Let's save it because we're going
|
||||
; to temporarily replace it with a null.
|
||||
ld b, a
|
||||
xor a
|
||||
ld (hl), a
|
||||
; Now, let's go back to the beginning of the string and parse it.
|
||||
; but before we do this, let's save the end of string in DE
|
||||
ex de, hl
|
||||
pop hl
|
||||
call parseDecimal
|
||||
; Z is set properly at this point. nothing touches Z below.
|
||||
ld a, b
|
||||
ld (de), a
|
||||
ex de, hl ; put end of string back from DE to HL
|
||||
; Put addr in its final register, DE
|
||||
push ix \ pop de
|
||||
pop ix
|
||||
pop bc
|
||||
ret
|
||||
|
Loading…
Reference in New Issue
Block a user