Files
kern/asmSrc/fs/edit.asm
T
Tom-on 726247a4f2 Began moving to C. (No C yet)
If you want to build the assembly version, run the buildAsm.sh script
Currently just setting up the bootloader.
2024-01-02 14:40:32 +01:00

309 lines
5.8 KiB
NASM

[bits 16]
start:
pusha
mov byte [driveNum], dl
hexEditor:
call clearText
mov di, 0x0e60 ; Offset in vidmem (2nd to last line)
mov si, hexModeMsg
call drawString
mov di, 0x0f00 ; Last line
mov si, controlsMsg
call drawString
mov di, hexCode
xor cx, cx ; Clear counter
mov dx, [codeLen]
call printHexByte
mov si, bytesMsg
call print
mov si, newline
call print
cmp word [codeLen], 0
je getHexCh
mov cx, [codeLen]
.printCode:
mov dl, [di]
call printHexByte
mov ah, 0x0e
mov al, ' '
int 0x10
inc di
dec cx
jnz .printCode
mov cx, [codeLen]
getHexCh:
xor ax, ax
int 0x16
cmp al, RUN_CODE
je .runInput
cmp al, QUIT_EDIT
je return
cmp al, SAVE_FILE
je save
cmp al, OPEN_FILE
je open
cmp al, 0x08 ; Backspace
je .backspace
xor ah, ah
call asciiToHex ; Get the hex digit into bx
cmp ax, 15 ; Check if it's a hex character
jg getHexCh ; If not, ignore it
inc cx
cmp cx, 2 ; Check if we've gotten a whole byte (2 hex digits/nibbles)
je .putByte
mov [hexByte], al
jmp getHexCh
.putByte:
cmp di, hexCode+510
jge getHexCh ; Max length reached
rol byte [hexByte], 4
or byte [hexByte], al
mov al, [hexByte]
stosb
mov dx, [hexByte]
call printHexByte
inc word [codeLen]
xor cx, cx
mov al, ' '
mov ah, 0x0e
int 0x10
jmp getHexCh
.backspace:
cmp word [codeLen], 0 ; Check if there's anything to delete
je getHexCh ; If not, ignore
mov byte [hexByte], 0
dec word [codeLen]
xor cx, cx
mov byte [di], 0
dec di
mov si, hexBackspace
call print
jmp getHexCh
.runInput:
mov si, runMsg
call print
pusha
push es
call hexCode ;! Runs arbitrary code (may break everything)
pop es
popa
mov si, ranMsg
call print
xor ax, ax
int 0x16
jmp hexEditor
return:
popa
mov ax, 0x2000
mov es, ax
xor bx, bx
mov ds, ax
mov fs, ax
mov gs, ax
jmp 0x2000:0x0000
; Saves a file
save:
mov dl, 9
mov si, saveFileMsg
call getInput
mov byte al, [filename]
cmp byte al, 0
je getHexCh
; Call saveFile
mov byte dl, [driveNum]
push word filename
push word binFile ; Filetype, TODO: More filetypes other than .bin
push word 1 ; TODO: Dynamic filesize
push word 0x8000 ; Program location (this segment)
push word savedData ; Offset (hex code location)
call saveFile ; Returns exit code in al
add sp, 10 ; Stack bs
mov ax, 0x8000
mov es, ax
mov fs, ax
cmp al, 0 ; Won't be 1 (File not found) so must be disk error
jne .error
jmp getHexCh
.error:
mov si, diskErrMsg
mov di, 0x0f00 ; Last line
call drawString
jmp getHexCh
; Opens a file
open:
mov dl, 11
mov si, openFileMsg
call getInput
mov byte al, [filename]
cmp byte al, 0
je getHexCh
; Call loadFile
mov byte dl, [driveNum]
push word filename
push word 0x8000
push word hexCode
call loadFile
mov ax, 0x8000
mov es, ax
mov fs, ax
cmp al, 1
je .notFound
cmp al, 2
je .diskErr
; Success
jmp hexEditor
.notFound:
mov si, notFoundMsg
jmp .err
.diskErr:
mov si, diskErrMsg
.err:
mov di, 0x0f00
call drawString
xor ax, ax
int 0x16
jmp hexEditor
;
; Gets a filename (10 chars, If less, padded with Nulls)
; Outputs the filename in the filename buffer
; si - Prompt string (Null terminated)
; dl - String offset
;
getInput:
pusha
push es
mov di, 0x0f00 ; Last line
call drawString ; si should contain the string
mov ah, 2 ; Move cursor to input position
mov dh, 24 ; Last line
int 0x10
mov di, filename
xor cx, cx ; Entered filename length
.loop:
xor ax, ax
int 0x16
cmp al, 0xD ; User pressed enter
je .done
cmp al, 8 ; Backspace
je .backspace
cmp al, 27 ; Escape
je .escape
cmp cx, 10 ; Filename too long
je .loop
mov ah, 0x0e
int 0x10
mov [di], al
inc di
inc cx
jmp .loop
.backspace:
cmp cx, 0
je .loop
dec cx
dec di
mov si, textBackspace
call print
jmp .loop
.escape:
xor cx, cx
mov si, filename
.done:
cmp cx, 10
je .after
mov byte [di], 0
inc cx
inc di
.after:
mov ah, 2 ; Move cursor
xor dx, dx ; 0,0
int 0x10
pop es
popa
ret
; Expects al to contain an ASCII character, will set bx to it's hex equivalent
asciiToHex:
cmp al, '9'
jle .getHex
sub al, 7
.getHex:
sub al, '0'
ret
;; Includes
%include "./src/lib/print.asm"
%include "./src/lib/disk.asm"
;; Variables
hexModeMsg: db " -- HEX -- ", 0
textModeMsg: db " -- Text -- ", 0
controlsMsg: db "'$' Execute; ^Q Quit; ^S Save; ^O Open", 0
saveFileMsg: db "Save as: ", 0 ; Make sure to erase the controls
openFileMsg: db "Open file: ", 0
bytesMsg: db " Bytes", 0
; savedMsg: db "Saved file as '", 0
; oepenedMsg: db "Editing file '", 0
runMsg: db ENDL, ENDL, 0
ranMsg: db ENDL, ENDL, " - Finished Execution - ", ENDL, 0
notFoundMsg: db "File not found! ", 0 ; Erase the user input
diskErrMsg: db "Disk Error! ", 0
; Filetypes
binFile: db "bin"
txtFile: db "txt"
hexBackspace: db 8,8,8,' ',8,8,0
textBackspace: db 8,' ',8,0
driveNum: db 0
hexByte: db 0
filenameLen: db 0
filename: times 10 db 0
;; Constants
RUN_CODE equ '$'
QUIT_EDIT equ 'q'
NEW_FILE equ 'n'
SAVE_FILE equ 's'
OPEN_FILE equ 'o'
times 3*512-($-$$) db 0
savedData:
hexCode: times 510 db 0 ; Code buffer
codeLen: dw 0 ; Hopefully we don't overflow :)