From b7d4860acfbcdd6772ced8827de51cc395663e00 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sat, 23 Nov 2019 20:35:21 -0500 Subject: [PATCH] basic: add in/out commands Also, fixed the cmd matching algo to not accept partial matches. For example, to stop matching "input" when the command was "in". --- apps/basic/README.md | 6 +++++ apps/basic/main.asm | 59 ++++++++++++++++++++++++++++++++++---------- apps/basic/tok.asm | 24 ------------------ 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/apps/basic/README.md b/apps/basic/README.md index bc2d871..cad5c42 100644 --- a/apps/basic/README.md +++ b/apps/basic/README.md @@ -115,5 +115,11 @@ address. For example, `poke 42 0x102+0x40` puts `0x42` in memory address 0x2a (MSB is ignored) and `doke 42 0x102+0x40` does the same as poke, but also puts `0x01` in memory address 0x2b. +**in**: Same thing as `peek`, but for a I/O port. `in 42 a` generates an input +I/O on port 42 and stores the byte result in `a`. + +**out**: Same thing as `poke`, but for a I/O port. `out 42 1+2` generates an +output I/O on port 42 with value 3. + **sleep**: Sleep a number of "units" specified by the supplied expression. A "unit" depends on the CPU clock speed. At 4MHz, it is roughly 8 microseconds. diff --git a/apps/basic/main.asm b/apps/basic/main.asm index 2e1dca9..2fc3468 100644 --- a/apps/basic/main.asm +++ b/apps/basic/main.asm @@ -56,17 +56,17 @@ basCallCmd: ; let's see if it's a variable assignment. call varTryAssign ret z ; Done! - ; Second, get cmd length - call fnWSIdx - cp 7 - jp nc, unsetZ ; Too long, can't possibly fit anything. - ; A contains whitespace IDX, save it in B - ld b, a - ex de, hl + push de ; --> lvl 1. + ld de, SCRATCHPAD + call rdWord + ; cmdname to find in (DE) + ; How lucky, we have a legitimate use of "ex (sp), hl"! We have the + ; cmd table in the stack, which we want in HL and we have the rest of + ; the cmdline in (HL), which we want in the stack! + ex (sp), hl inc hl \ inc hl .loop: - ld a, b ; whitespace IDX - call strncmp + call strcmp jr z, .found ld a, 8 call addHL @@ -74,15 +74,14 @@ basCallCmd: cp 0xff jr nz, .loop ; not found + pop hl ; <-- lvl 1 jp unsetZ .found: dec hl \ dec hl call intoHL push hl \ pop ix - ; Bring back command string from DE to HL - ex de, hl - ld a, b ; cmd's length - call addHL + ; Bring back rest of the command string from the stack + pop hl ; <-- lvl 1 call rdSep jp (ix) @@ -309,6 +308,36 @@ basDOKE: ld (ix+1), h ret +basOUT: + call rdExpr + ret nz + ; out address in IX. Save it for later + push ix ; --> lvl 1 + call rdSep + call rdExpr + push ix \ pop hl + pop bc ; <-- lvl 1 + ret nz + ; Out! + out (c), l + cp a ; ensure Z + ret + +basIN: + call rdExpr + ret nz + push ix \ pop bc + ld d, 0 + in e, (c) + call rdSep + ld a, (hl) + call varChk + ret nz ; not in variable range + ; All good assign + call varAssign + cp a ; ensure Z + ret + basSLEEP: call rdExpr ret nz @@ -346,6 +375,10 @@ basCmds2: .db "deek", 0, 0 .dw basDOKE .db "doke", 0, 0 + .dw basOUT + .db "out", 0, 0, 0 + .dw basIN + .db "in", 0, 0, 0, 0 .dw basSLEEP .db "sleep", 0 .db 0xff, 0xff, 0xff ; end of table diff --git a/apps/basic/tok.asm b/apps/basic/tok.asm index b3bd516..1e6c630 100644 --- a/apps/basic/tok.asm +++ b/apps/basic/tok.asm @@ -32,30 +32,6 @@ rdSep: inc a ; unset Z ret -; Find the first whitespace in (HL) and returns its index in A -; Sets Z if whitespace is found, unset if end of string was found. -; In the case where no whitespace was found, A returns the length of the string. -fnWSIdx: - push hl - push bc - ld b, 0 -.loop: - ld a, (hl) - call isSep - jr z, .found - or a - jr z, .eos - inc hl - inc b - jr .loop -.eos: - inc a ; unset Z -.found: ; Z already set from isSep - ld a, b - pop bc - pop hl - ret - ; Advance HL to the next separator or to the end of string. toSep: ld a, (hl)