|
|
@@ -4,34 +4,59 @@ |
|
|
|
; for now, this unit is tightly coupled to acia.asm, but it will eventually be |
|
|
|
; more general than that. |
|
|
|
|
|
|
|
; Incomplete. For now, this outputs a welcome prompt and then waits for input. |
|
|
|
; Whenever input is CR or LF, we echo back what we've received and empty the |
|
|
|
; input buffer. This also happen when the buffer is full. |
|
|
|
; Status: incomplete. As it is now, it spits a welcome prompt, wait for input |
|
|
|
; and compare the first 4 chars of the input with a command table and call the |
|
|
|
; appropriate routine if it's found, an error if it's not. |
|
|
|
; |
|
|
|
; Commands, for now, are dummy. |
|
|
|
; |
|
|
|
; See constants below for error codes. |
|
|
|
|
|
|
|
; *** CONSTS *** |
|
|
|
CR .equ 0x0d |
|
|
|
LF .equ 0x0a |
|
|
|
|
|
|
|
; number of entries in shellCmdTbl |
|
|
|
SHELL_CMD_COUNT .equ 2 |
|
|
|
|
|
|
|
; The command that was type isn't known to the shell |
|
|
|
SHELL_ERR_UNKNOWN_CMD .equ 0x01 |
|
|
|
|
|
|
|
; Arguments for the command weren't properly formatted |
|
|
|
SHELL_ERR_BAD_ARGS .equ 0x02 |
|
|
|
|
|
|
|
; *** CODE *** |
|
|
|
shellInit: |
|
|
|
; print prompt |
|
|
|
ld hl, d_welcome |
|
|
|
ld hl, .prompt |
|
|
|
call printstr |
|
|
|
call printcrlf |
|
|
|
ret |
|
|
|
|
|
|
|
.prompt: |
|
|
|
.db "Collapse OS", 0 |
|
|
|
|
|
|
|
shellLoop: |
|
|
|
call chkbuf |
|
|
|
jr shellLoop |
|
|
|
|
|
|
|
; print null-terminated string pointed to by HL |
|
|
|
printstr: |
|
|
|
push af |
|
|
|
push hl |
|
|
|
|
|
|
|
.loop: |
|
|
|
ld a, (hl) ; load character to send |
|
|
|
or a ; is it zero? |
|
|
|
ret z ; if yes, we're finished |
|
|
|
jr z, .end ; if yes, we're finished |
|
|
|
call aciaPutC |
|
|
|
inc hl |
|
|
|
jr printstr |
|
|
|
; no ret because our only way out is ret z above |
|
|
|
jr .loop |
|
|
|
|
|
|
|
.end: |
|
|
|
pop hl |
|
|
|
pop af |
|
|
|
ret |
|
|
|
|
|
|
|
printcrlf: |
|
|
|
ld a, CR |
|
|
@@ -73,9 +98,124 @@ chkbuf: |
|
|
|
|
|
|
|
; alright, let's go! |
|
|
|
ld hl, ACIA_BUF |
|
|
|
call shellParse |
|
|
|
ret |
|
|
|
|
|
|
|
; Compares strings pointed to by HL and DE up to A count of characters. If |
|
|
|
; equal, Z is set. If not equal, Z is reset. |
|
|
|
strncmp: |
|
|
|
push bc |
|
|
|
push hl |
|
|
|
push de |
|
|
|
|
|
|
|
ld b, a |
|
|
|
.loop: |
|
|
|
ld a, (de) |
|
|
|
cp (hl) |
|
|
|
jr nz, .end ; not equal? break early |
|
|
|
inc hl |
|
|
|
inc de |
|
|
|
djnz .loop |
|
|
|
|
|
|
|
.end: |
|
|
|
pop de |
|
|
|
pop hl |
|
|
|
pop bc |
|
|
|
; Because we don't call anything else than CP that modify the Z flag, |
|
|
|
; our Z value will be that of the last cp (reset if we broke the loop |
|
|
|
; early, set otherwise) |
|
|
|
ret |
|
|
|
|
|
|
|
; add the value of A into DE |
|
|
|
addDE: |
|
|
|
add a, e |
|
|
|
jr nc, .end ; no carry? skip inc |
|
|
|
inc d |
|
|
|
.end: |
|
|
|
ld e, a |
|
|
|
ret |
|
|
|
|
|
|
|
; jump to the location pointed to by HL. This allows us to call HL instead of |
|
|
|
; just jumping it. |
|
|
|
jumpHL: |
|
|
|
jp hl |
|
|
|
ret |
|
|
|
|
|
|
|
; Parse command (null terminated) at HL and calls it |
|
|
|
shellParse: |
|
|
|
push af |
|
|
|
push bc |
|
|
|
push de |
|
|
|
|
|
|
|
ld de, shellCmdTbl |
|
|
|
ld a, SHELL_CMD_COUNT |
|
|
|
ld b, a |
|
|
|
|
|
|
|
.loop: |
|
|
|
ld a, 4 ; 4 chars to compare |
|
|
|
call strncmp |
|
|
|
jr z, .found |
|
|
|
ld a, 6 |
|
|
|
call addDE |
|
|
|
djnz .loop |
|
|
|
|
|
|
|
; exhausted loop? not found |
|
|
|
ld a, SHELL_ERR_UNKNOWN_CMD |
|
|
|
call shellPrintErr |
|
|
|
jr .end |
|
|
|
|
|
|
|
.found: |
|
|
|
ld a, 4 |
|
|
|
call addDE |
|
|
|
ex hl, de |
|
|
|
call jumpHL |
|
|
|
ex hl, de |
|
|
|
|
|
|
|
.end: |
|
|
|
pop de |
|
|
|
pop bc |
|
|
|
pop af |
|
|
|
ret |
|
|
|
|
|
|
|
; Print the error code set in A (doesn't work for codes > 9 yet...) |
|
|
|
shellPrintErr: |
|
|
|
push af |
|
|
|
push hl |
|
|
|
|
|
|
|
ld hl, .str |
|
|
|
call printstr |
|
|
|
|
|
|
|
; ascii for '0' is 0x30 |
|
|
|
add a, 0x30 |
|
|
|
call aciaPutC |
|
|
|
call printcrlf |
|
|
|
|
|
|
|
pop hl |
|
|
|
pop af |
|
|
|
ret |
|
|
|
|
|
|
|
.str: |
|
|
|
.db "ERR ", 0 |
|
|
|
|
|
|
|
; *** COMMANDS *** |
|
|
|
shellSeek: |
|
|
|
ld hl, .str |
|
|
|
call printstr |
|
|
|
ret |
|
|
|
.str: |
|
|
|
.db "seek called", CR, LF, 0 |
|
|
|
|
|
|
|
shellPeek: |
|
|
|
ld hl, .str |
|
|
|
call printstr |
|
|
|
ret |
|
|
|
.str: |
|
|
|
.db "peek called", CR, LF, 0 |
|
|
|
|
|
|
|
; Format: 4 bytes name followed by 2 bytes jump. fill names with zeroes |
|
|
|
shellCmdTbl: |
|
|
|
.db "seek" |
|
|
|
jr shellSeek |
|
|
|
.db "peek" |
|
|
|
jr shellPeek |
|
|
|
|
|
|
|
; *** DATA *** |
|
|
|
d_welcome: .byte "Welcome to Collapse OS", 0 |