summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2018-06-23 15:12:55 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2018-06-23 15:12:55 -0400
commit3b46e7ef1f4c3f364e75e780eff923ef146ee42c (patch)
treec1e08f6ec3925c9c57f2093d59ab7444de9e28ce
parent2362c3ae6b32c816c4febe9714847fa4d80e1ad5 (diff)
downloadminos-3b46e7ef1f4c3f364e75e780eff923ef146ee42c.tar.gz
Implement initial builtin commands
-rw-r--r--builtin_clear.asm11
-rw-r--r--builtin_echo.asm29
-rw-r--r--builtin_exit.asm7
-rw-r--r--builtin_free.asm35
-rw-r--r--builtin_vga_demo.asm123
-rw-r--r--builtin_video_mode.asm98
-rw-r--r--builtins.asm16
7 files changed, 302 insertions, 17 deletions
diff --git a/builtin_clear.asm b/builtin_clear.asm
new file mode 100644
index 0000000..cac6216
--- /dev/null
+++ b/builtin_clear.asm
@@ -0,0 +1,11 @@
+%ifndef _BUILTIN_CLEAR_ASM
+%define _BUILTIN_CLEAR_ASM
+
+builtin_clear:
+ call cls ; clear console
+ push 0000h ; home position 0x0
+ call setcursor ; home cursor on console
+ add sp, 2 ; cleanup stack
+ ret
+
+%endif
diff --git a/builtin_echo.asm b/builtin_echo.asm
index 1b4af89..9cc1e9c 100644
--- a/builtin_echo.asm
+++ b/builtin_echo.asm
@@ -5,16 +5,25 @@ builtin_echo:
push bp
mov bp, sp
- mov bx, word [bp + 4]
- add bx, 2
- push word [bx]
- push .msg_fmt
- call printf
- add sp, 2 * 2
+ mov cx, word [bp + 4] ; argc
+ mov bx, word [bp + 6] ; argv
- mov sp, bp
- pop bp
- ret
- .msg_fmt db '%s\n', 0
+ cmp cx, 0 ; if no arguments, return
+ jbe .return
+
+ .output: ; print argv
+ push word [bx]
+ push .msg_fmt
+ call printf
+ add sp, 2 * 2
+ add bx, 2
+ dec cx
+ jne .output
+
+ .return:
+ mov sp, bp
+ pop bp
+ ret
+ .msg_fmt db '%s ', 0
%endif
diff --git a/builtin_exit.asm b/builtin_exit.asm
index 74594e1..08b0e38 100644
--- a/builtin_exit.asm
+++ b/builtin_exit.asm
@@ -2,16 +2,13 @@
%define _BUILTIN_EXIT_ASM
builtin_exit:
- push bp
- mov bp, sp
-
push .msg_fmt
call printf
add sp, 2 * 1
- add sp, 2 ; cleanup previous call address
+ mov [terminal_exit], byte 1
- jmp terminal
+ ret
.msg_fmt db 'exiting...\n', 0
%endif
diff --git a/builtin_free.asm b/builtin_free.asm
new file mode 100644
index 0000000..96e3c86
--- /dev/null
+++ b/builtin_free.asm
@@ -0,0 +1,35 @@
+%ifndef _BUILTIN_FREE_ASM
+%define _BUILTIN_FREE_ASM
+
+builtin_free:
+ push bp
+ mov bp, sp
+
+ mov cx, word [bp + 4] ; argc
+ mov bx, word [bp + 6] ; argv
+
+ ;cmp cx, 0 ; if no arguments, return
+ ;jbe .return
+
+ mov ah, 88h ; get extended memory size
+ int 15h
+ mov dx, ax
+
+ int 12h ; get conventional memory size
+ ; but it's pretty much bogus
+
+ push dx
+ push ax
+ push .msg_fmt
+ call printf
+ add sp, 2 * 2
+ add bx, 2
+
+ .return:
+ mov sp, bp
+ pop bp
+ ret
+ .msg_fmt db 'Conventional memory: %dK\n'
+ db 'Extended memory: %dK', 0
+
+%endif
diff --git a/builtin_vga_demo.asm b/builtin_vga_demo.asm
new file mode 100644
index 0000000..54d4a4f
--- /dev/null
+++ b/builtin_vga_demo.asm
@@ -0,0 +1,123 @@
+%ifndef _VGA_DEMO_ASM
+%define _VGA_DEMO_ASM
+
+VGA_SCREEN_WIDTH equ 320
+VGA_SCREEN_HEIGHT equ 200
+VGA_COLORS equ 0x100
+
+vga_plot:
+ %define .x [bp + 4]
+ %define .y [bp + 6]
+ %define .color [bp + 8]
+ push bp
+ mov bp, sp
+ pusha
+ push es
+ push ds
+ ;push ax
+ ;push cx
+ ;push dx
+ ;push di
+;
+ xor ax, ax
+ xor cx, cx
+ xor dx, dx
+ xor di, di
+
+ mov ax, 0A000h
+ mov es, ax ; Store VGA memory segment in ES
+ mov ds, ax
+
+ mov ax, word VGA_SCREEN_WIDTH
+ mov cx, word .y
+ mul cx
+ add ax, word .x
+ mov di, ax
+
+ mov ax, word .color
+ mov [es:di], ax
+
+ .return:
+ ;pop di
+ ;pop dx
+ ;pop cx
+ ;pop ax
+ pop ds
+ pop es
+ popa
+ mov sp, bp
+ pop bp
+ ret
+
+
+
+builtin_vga_demo:
+ push bp
+ mov bp, sp
+ sub sp, 2
+
+ ;
+ ; no arguments for this program
+ ;
+
+ .main:
+ mov ah, 0fh ; get current video mode
+ int 10h
+ mov [bp - 2], al ; save current video mode
+
+ mov ah, 00h
+ mov al, 13h ; set 256 color VGA mode
+ int 10h
+
+ mov di, 0ffh
+ .loop:
+ mov si, .data_smiley ; address of smiley face array
+ mov cx, 10 ; number of array elements
+ .do_plot:
+ mov ax, [si] ; Load coordinates
+ add si, 2 ; Next set
+
+ movzx dx, al ; Store y
+ movzx bx, ah ; Store x
+
+ push di ; color
+ push dx ; y
+ push bx ; x
+ call vga_plot ; write pixel
+ add sp, 2 * 3
+
+ and di, 0ffh ; DI overflows into infinity so
+ ; use its low byte instead of resetting to zero
+ dec di ; Next color
+ dec cx ; Next loop
+ jne .do_plot
+
+ xor ax, ax
+ call kbd_read_async ; ZF=1 if no key is pressed
+ je .loop
+
+ .return:
+ mov ah, 00h ; Set video mode
+ mov al, [bp - 2] ; Restore video mode
+ int 10h
+
+ add sp, 2
+ mov sp, bp
+ pop bp
+ ret
+
+ .data_smiley:
+ ; plots a smiley face using coordinates
+ ; row col
+ db 01h,01h ; left eye
+ db 01h,05h ; right eye
+ db 04h,03h ; nose
+ db 06h,00h ; left uptick mouth
+ db 06h,06h ; mouth
+ db 07h,01h ; mouth
+ db 07h,02h ; mouth
+ db 07h,03h ; mouth
+ db 07h,04h ; mouth
+ db 07h,05h ; right uptick mouth
+
+%endif
diff --git a/builtin_video_mode.asm b/builtin_video_mode.asm
new file mode 100644
index 0000000..571899e
--- /dev/null
+++ b/builtin_video_mode.asm
@@ -0,0 +1,98 @@
+%ifndef _BUILTIN_VIDEO_MODE_ASM
+%define _BUILTIN_VIDEO_MODE_ASM
+
+builtin_video_mode:
+ push bp
+ mov bp, sp
+
+ mov cx, [bp + 4] ; Load argc
+ mov bx, [bp + 6] ; Load argv
+
+ cmp cx, 1 ; Not enough args?
+ jl .no_args ; ... die
+ jmp .main
+
+ .no_args:
+ push .error_arg
+ call printf
+ add sp, 2 * 1
+ jmp .return
+
+ ; main program
+
+ .main:
+ mov bx, [bx] ; Load first element in argv array
+ mov si, bx ; First element is source index
+
+ push bx ; Get length of element
+ call strlen
+ add sp, 2
+ mov cx, ax ; Store length
+ mov bx, 0
+
+
+ mov ax, 0
+ mov dx, 0
+ .chars:
+ lodsb ; Load character from ES:SI
+ cmp ax, '9' ; If value is greater than '9' it's likely hex, so
+ ; adjust AX to compensate
+ jg .ishex
+
+ sub ax, '0' ; Otherwise, the value is base-10
+ jmp .nosub
+
+ .tolower:
+ sub ax, 20h
+ .ishex:
+ cmp ax, 'a'
+ jge .tolower ; If we recieved a lowercase letter, convert it
+ ; to uppercase, then continue
+
+ cmp ax, 'F' ; Is this a valid hexadecimal value? (0 ~ F)
+ jg .invalid_input
+
+ sub ax, 'A' ; Convert character to BCD
+ add ax, 10
+
+ .nosub:
+ shl dx, 4 ; Shift current BCD value 4-bits left
+ or dx, ax ; Tack on the latest value
+ dec cx ; Decrement counter
+ jne .chars ; continue until no characters remain
+
+
+ cmp dx, 13h ; Is the final value a valid video mode?
+ jg .invalid_mode
+
+
+ mov al, dl ; BIOS video services only operate on a byte value
+ ; ... oh well.
+
+ mov ah, 00h
+ int 10h ; Set video mode
+
+ .return:
+ mov sp, bp
+ pop bp
+ ret
+
+ .invalid_input:
+ push ax
+ push .error_hex
+ call printf
+ add sp, 2 * 2
+ jmp .return
+
+ .invalid_mode:
+ push dx
+ push .error_mode
+ call printf
+ add sp, 2 * 2
+ jmp .return
+
+ .error_arg: db 'error: no graphics mode requested. (0..13)\n', 0
+ .error_hex: db 'error: "%c" is an invalid hexadecimal value (0..F)\n', 0
+ .error_mode: db 'error: %2x is an invalid video mode (0..13)\n', 0
+
+%endif
diff --git a/builtins.asm b/builtins.asm
index 268e4b2..d09282c 100644
--- a/builtins.asm
+++ b/builtins.asm
@@ -1,19 +1,31 @@
%ifndef _BUILTINS_ASM
%define _BUILTINS_ASM
-%include "builtin_reboot.asm"
-%include "builtin_exit.asm"
+%include "builtin_clear.asm"
%include "builtin_echo.asm"
+%include "builtin_exit.asm"
+%include "builtin_free.asm"
+%include "builtin_reboot.asm"
+%include "builtin_vga_demo.asm"
+%include "builtin_video_mode.asm"
t_builtins_fn:
+ dw builtin_clear
dw builtin_echo
dw builtin_exit
+ dw builtin_free
dw builtin_reboot
+ dw builtin_vga_demo
+ dw builtin_video_mode
dw 0
t_builtins_str:
+ .clear: db 'clear', 0
.echo: db 'echo', 0
.exit: db 'exit', 0
+ .free: db 'free', 0
.reboot: db 'reboot', 0
+ .vga_demo: db 'vga_demo', 0
+ .video_mode: db 'video_mode', 0
dw 0
%endif