First working interactive shell for memory monitor

This commit is contained in:
Daniele Verducci su MatissePenguin
2020-11-25 19:39:20 +01:00
parent 3d7610e113
commit 336f2fe181
6 changed files with 60 additions and 43 deletions

View File

@ -0,0 +1,57 @@
; Arduino terminal driver
; @author Daniele Verducci
; config (IO port 0)
DATA_REG: EQU IO_0
; variables
TERM_VAR_SPACE: EQU DRV_VAR_SPACE + 128
incoming_string: EQU TERM_VAR_SPACE
; functions
; Sends string
; @param BC Pointer to a null-terminated string first character
Term_print:
ld a, (bc) ; bc is the pointer to passed string's first char
cp 0 ; compare A content with 0 (subtract 0 from value and set zero flag Z if result is 0)
ret z ; if prev compare is true (Z flag set), string is finished, return
out (DATA_REG),a ; output char
inc bc ; increment bc to move to next char
jp Term_print
; Writes a single character
; @param A Value of character to print
Term_printc:
out (DATA_REG),a
ret
; Reads a single character
; @return A The read character
Term_readc:
in a, (DATA_REG) ; reads a character
add a, 0
jp z, Term_readc ; if char is 0 (NULL), ignores it and waits for another character
ret ; if not NULL, returns it in the a register
; Reads a line
; @return BC The pointer to a null-terminated read string
Term_readline:
ld bc, incoming_string ; this array will contain read string
in a, (DATA_REG) ; reads a character
; if char is 0 (ascii NULL), ignore it
add a, 0
jp z, Term_readline ; if 0 (= ascii NULL), ignores it and waits for another character
; if char is a newline (CR or LF), line is finished.
cp 10 ; CR
jp z, term_readline_foundcr ; Found newline. Jump to term_readline_foundcr
cp 13 ; LF
jp z, term_readline_foundcr ; Found newline. Jump to term_readline_foundcr
; At this point the read character is a valid ascii character
ld (bc), a ; adds char to the read string
inc bc ; point to next array position
jp Term_readline
term_readline_foundcr: ; called when carriage return was found (end of line)
;ld (bc), 0 ; Null-terminate string
ld bc, incoming_string ; Returns read string pointer
ret

View File

@ -0,0 +1,112 @@
; HD44780 20x4 characters LCD display driver
; @author Daniele Verducci
;
; USAGE:
; STR: DB "Hello world!",0 <-- null terminated string
; call Lcd_init <-- inits hd44780 controller
; ld bc, STR <-- load pointer to string's first char in reg BC
; call Lcd_print <-- this function will print the string
; LCD config (IO port 0)
LCD_INSTR_REG: EQU IO_0
LCD_DATA_REG: EQU IO_0 + 1
; constants
LCD_LINES_LEFT: DB 0x80, 0xA8, 0x94, 0xBC ;array defining lcd command codes for the first char of every line
; variables
LCD_VAR_SPACE: EQU DRV_VAR_SPACE
lcd_cur_x: EQU LCD_VAR_SPACE
lcd_cur_y: EQU lcd_cur_x + 1
; functions
; Inits the lcd display
Lcd_init:
;reset procedure
ld a,0x38
out (LCD_INSTR_REG),a
ld a,0x08
out (LCD_INSTR_REG),a
ld a,0x01
out (LCD_INSTR_REG),a
;init procedure
ld a,0x38
out (LCD_INSTR_REG),a
ld a,0x0F
out (LCD_INSTR_REG),a
ret
; Writes text starting from current cursor position
; @param BC Pointer to a null-terminated string first character
Lcd_print:
ld a, (bc) ; bc is the pointer to passed string's first char
cp 0 ; compare A content with 0 (subtract 0 from value and set zero flag Z if result is 0)
ret z ; if prev compare is true (Z flag set), string is finished, return
out (LCD_DATA_REG),a ; output char
inc bc ; increment bc to move to next char
; increment x position
ld a, (lcd_cur_x)
inc a
ld (lcd_cur_x), a
; if x position > 19, increment y position and set x to 0
ld a, (lcd_cur_x)
cp 20
jp nz, Lcd_print ; if x position is not 20, continue cycle
ld a, 0
ld (lcd_cur_x), a ; else set x to 0
; and increment y
ld a, (lcd_cur_y)
inc a
ld (lcd_cur_y), a
; if y > 3 set y to 0
cp 4 ; a still contains lcd_cur_y: compare with 4
jp nz, Lcd_print ; if y position is not 4, continue cycle
ld a, 0
ld (lcd_cur_x), a ; else set y pos to 0
jp Lcd_print
; Writes a single character at current cursror position
; @param A Value of character to print
Lcd_printc:
out (LCD_DATA_REG),a
ret
; Set cursor position
; @param B X-axis position (0 to 19)
; @param C Y-axis position (0 to 3)
Lcd_locate:
ld a, b
ld (lcd_cur_x), a
ld a, c
ld (lcd_cur_y), a
call lcd_locate
ret
; private
; The cursor position can seem like black magic but it makes much more sense once you know that the HD44780 is designed to control a 40 character 4-line display. So if you have a 16×2 then you will only see the first 16 characters of the top two lines. Simple enough once you get used to taking these character positions into account. For example, in a 16×2 display, the first line is position 0-15. So 0x80 is the first position, 0x80 + 12 = 0x8C is the 13th (remember, they are zero indexed). The second line is a little tricky since it shows positions 64-79. Just add the position number (in decimal) to 0x80 (in hex) to get the hex address of the cursor position. The address is the command to move the cursor to that location. So, to move to the 13th position of the top line in a 16×2 Sparkfun Display, I would send “0xFE 0x8C”. The first byte warns the onboard microcontroller that a command is coming, and the second byte is the command.
lcd_locate:
; warns the lcd microcontroller that a command is coming
ld a, 0xFE
out (LCD_INSTR_REG),a
; get line start command code from array
ld hl, LCD_LINES_LEFT ; load array pointer
ld bc, lcd_cur_y ; load line number
ld b, 0 ; since line number is only 8 bit, clean garbage on the upper bit
add hl, bc ; sum first array element to line number to access correct array element. Now hl contains array pointer
; now sum x offset to the start line code to obtain lcd controller complete position code
ld a, (lcd_cur_x) ; load cursor x position
add a, (hl) ; sum cursor x pos to line start code. Result is in a
out (LCD_INSTR_REG),a ; send cursor position to lcd controller
ret
; Clears the screen
Lcd_cls:
ld a,0x01
out (LCD_INSTR_REG),a ; clear display
ld a,0x02
out (LCD_INSTR_REG),a ; cursor to home (top left)
ret

View File

@ -0,0 +1,56 @@
; Keyboard driver
; @author Daniele Verducci
;
; Requires declaration of following pointers, one for every column of the keys grid:
; KEYB_A0_REG
; KEYB_A1_REG
; KEYB_A2_REG
; KEYB_A3_REG
; KEYB_A4_REG
; These address must be exclusive if a decoder is not present.
;
; Example (no decoder):
; KEYB_A0_REG = 0000001
; KEYB_A1_REG = 0000010
; KEYB_A2_REG = 0000100
; KEYB_A3_REG = 0001000
; etc...
;
; Example (with decoder):
; KEYB_A0_REG = 0000000
; KEYB_A1_REG = 0000001
; KEYB_A2_REG = 0000010
; KEYB_A3_REG = 0000011
; etc...
; Keyboard config (IO port 1)
KEYB_A0_REG: EQU IO_1 + %00000001
KEYB_A1_REG: EQU IO_1 + %00000010
KEYB_A2_REG: EQU IO_1 + %00000100
KEYB_A3_REG: EQU IO_1 + %00001000
KEYB_A4_REG: EQU IO_1 + %00010000
; Reads the keyboard
; @return: a 0-terminated array of keycodes representing the pressed keys
Keyb_read:
in a, (KEYB_A0_REG)
cp 0
jp z, _keyb_read_a1
add a, %01000000
call Lcd_printc ; A already contains char to print
_loop:
in a, (KEYB_A0_REG)
cp 0
jp nz, _loop
ret
_keyb_read_a1:
in a, (KEYB_A1_REG)
cp 0
ret z
add a, %01010000
call Lcd_printc ; A already contains char to print
_loop2:
in a, (KEYB_A1_REG)
cp 0
jp nz, _loop2
ret