parent
0c7002019d
commit
a86c9533d8
|
@ -0,0 +1,160 @@
|
||||||
|
USE16
|
||||||
|
format binary as 'bin'
|
||||||
|
|
||||||
|
include 'macros.asm'
|
||||||
|
include 'constants.asm'
|
||||||
|
|
||||||
|
org 7C00h
|
||||||
|
|
||||||
|
start:
|
||||||
|
mov byte [BOOT_DRIVE], dl
|
||||||
|
mov ax, [0410h]
|
||||||
|
mov word [DETECTED_HARDWARE], ax
|
||||||
|
|
||||||
|
cli
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, 1000h
|
||||||
|
sti
|
||||||
|
|
||||||
|
mov ax, 3
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ax, 1301h
|
||||||
|
mov cx, 10
|
||||||
|
mov bp, loadingdb
|
||||||
|
xor dx, dx
|
||||||
|
mov bx, 7
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 02h
|
||||||
|
; Number of sectors to load
|
||||||
|
; mov al, PROGRAM_LENGTH
|
||||||
|
mov al, 4
|
||||||
|
mov dl, [BOOT_DRIVE]
|
||||||
|
; Cylinder
|
||||||
|
mov ch, 0
|
||||||
|
; Head
|
||||||
|
mov dh, 0
|
||||||
|
; Start sector number
|
||||||
|
mov cl, 2
|
||||||
|
; Where load
|
||||||
|
mov bx, functable
|
||||||
|
int 13h
|
||||||
|
|
||||||
|
jc booterror
|
||||||
|
|
||||||
|
; call main
|
||||||
|
jmp secstage
|
||||||
|
|
||||||
|
; call dbg_halt_cpu
|
||||||
|
|
||||||
|
loadingdb db "Loading..."
|
||||||
|
|
||||||
|
; Print unsigned int
|
||||||
|
;
|
||||||
|
; AX - Num to convert
|
||||||
|
; SI - Where save string
|
||||||
|
; ---
|
||||||
|
; SI - Pointer to string with converted num
|
||||||
|
its:
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push di
|
||||||
|
push ax
|
||||||
|
|
||||||
|
mov cx, 0
|
||||||
|
mov bx, 10
|
||||||
|
mov di, si
|
||||||
|
|
||||||
|
its.push:
|
||||||
|
mov dx, 0
|
||||||
|
div bx
|
||||||
|
inc cx
|
||||||
|
push dx
|
||||||
|
test ax, ax
|
||||||
|
jnz its.push
|
||||||
|
its.pop:
|
||||||
|
pop dx
|
||||||
|
add dl, '0'
|
||||||
|
push ax
|
||||||
|
mov ah, 0Eh
|
||||||
|
mov al, dl
|
||||||
|
int 10h
|
||||||
|
pop ax
|
||||||
|
inc di
|
||||||
|
dec cx
|
||||||
|
jnz its.pop
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
pop di
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
ret
|
||||||
|
|
||||||
|
errcode db 0
|
||||||
|
booterror:
|
||||||
|
mov [errcode], ah
|
||||||
|
mov ax, 3
|
||||||
|
int 10h
|
||||||
|
mov ax, 1301h
|
||||||
|
mov bx, 7
|
||||||
|
xor dx, dx
|
||||||
|
mov cx, 13
|
||||||
|
mov bp, booterror.message
|
||||||
|
int 10h
|
||||||
|
xor ax, ax
|
||||||
|
mov al, [errcode]
|
||||||
|
call its
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
|
||||||
|
booterror.message db "Error! Code: "
|
||||||
|
|
||||||
|
; times 507-($-$$) db 0
|
||||||
|
; MBR partition table starting at byte 446
|
||||||
|
times 443-($-$$) db 0
|
||||||
|
DETECTED_HARDWARE dw 0
|
||||||
|
BOOT_DRIVE db 0
|
||||||
|
|
||||||
|
; partition 1 (contains the kernel code)
|
||||||
|
boot_indicator: db 0x80 ; mark as bootable
|
||||||
|
starting_head: db 0x0
|
||||||
|
starting_sector: db 0x1 ; bits 5-0 for sector and bits 7-6 are upper bits of cylinder
|
||||||
|
starting_cylinder: db 0x0
|
||||||
|
system_id: db 0x7f ; just some ID that has not been used for anything else by standard
|
||||||
|
; the last sector of the partition should be 2880
|
||||||
|
ending_head: db 1 ; here I assume the maximum number of heads as 255
|
||||||
|
ending_sector: db 4
|
||||||
|
ending_cylinder: db 0x0
|
||||||
|
first_sector_lba: dd 0x1 ; first sector after the bootsector
|
||||||
|
total_sectors_in_partition: dd 21 ; 2880-1 because first sector is bootsector
|
||||||
|
|
||||||
|
; partitions 2-4 are unused and therefore set to 0
|
||||||
|
times 16 db 0
|
||||||
|
times 16 db 0
|
||||||
|
times 16 db 0
|
||||||
|
|
||||||
|
db 0x55, 0xAA
|
||||||
|
|
||||||
|
|
||||||
|
include 'functable.asm'
|
||||||
|
|
||||||
|
include 'filetable.asm'
|
||||||
|
|
||||||
|
include 'secstage.asm'
|
||||||
|
|
||||||
|
include 'kernel.asm'
|
||||||
|
|
||||||
|
include 'funcs.asm'
|
||||||
|
|
||||||
|
include 'data.asm'
|
||||||
|
|
||||||
|
VIDEO_MODE db 0
|
||||||
|
|
||||||
|
times 8192-($-$$) db 0
|
||||||
|
; times 8400h-($-$$) db 0
|
||||||
|
|
||||||
|
; include 'programs/calculator.asm'
|
|
@ -0,0 +1,11 @@
|
||||||
|
INNUM_BUFFER_SIZE equ 5
|
||||||
|
SHNUM_BUFFER_SIZE equ 3
|
||||||
|
ACTION_BUFFER_SIZE equ 3
|
||||||
|
RESULT_BUFFER_SIZE equ 7
|
||||||
|
USERINPUT_BUFFER_SIZE equ 64
|
||||||
|
ARGUMENT_BUFFER_SIZE equ 16
|
||||||
|
FILENAME_BUFFER_SIZE equ 11
|
||||||
|
|
||||||
|
PROGRAM_ADDRESS equ 1000h
|
||||||
|
PROGRAM_LENGTH equ 65 ; In sectors, without boot sector
|
||||||
|
TABLE_SIZE equ 64
|
|
@ -0,0 +1,117 @@
|
||||||
|
greetings db "Welcome to the Command Line (c)Plaza 2022-2023.", 0Dh, 0Ah, \
|
||||||
|
"Write help to see list of commands.", 0
|
||||||
|
|
||||||
|
goodbye db "Uhadi!", 0
|
||||||
|
|
||||||
|
zx db "0x", 0
|
||||||
|
ln db 0Dh, 0Ah, 0
|
||||||
|
space db " ", 0
|
||||||
|
|
||||||
|
print_registers.axd db "AX: 0x", 0
|
||||||
|
print_registers.bxd db "BX: 0x", 0
|
||||||
|
print_registers.cxd db "CX: 0x", 0
|
||||||
|
print_registers.dxd db "DX: 0x", 0
|
||||||
|
print_registers.sid db "SI: 0x", 0
|
||||||
|
print_registers.did db "DI: 0x", 0
|
||||||
|
print_registers.esd db "ES: 0x", 0
|
||||||
|
print_registers.dsd db "DS: 0x", 0
|
||||||
|
print_registers.ssd db "SS: 0x", 0
|
||||||
|
print_registers.fd db "FLAGS: 0x", 0
|
||||||
|
print_registers.h db " ", 0
|
||||||
|
|
||||||
|
cmd.prefix db ">", 0
|
||||||
|
cmd.inc_com db "Invalid command or filename. Type 'help' to see more.", 0Dh, 0Ah, 0
|
||||||
|
cmd.file_notfound_err db "There are no files with this filename.", 0
|
||||||
|
|
||||||
|
cmd.cmd_help db "help", 0
|
||||||
|
cmd.cmd_help_desc db "Commands:", 0Dh, 0Ah, \
|
||||||
|
"mrun - Run program on user offset", 0Dh, 0Ah, \
|
||||||
|
"stdfuncs - show standart functions", 0Dh, 0Ah, \
|
||||||
|
"showmem <offset> <number of lines> - show memory on offset", 0Dh, 0Ah, \
|
||||||
|
"writemem - write byte to memory", 0Dh, 0Ah, \
|
||||||
|
"loadmem - load from disk to memory with offset", 0Dh, 0Ah, \
|
||||||
|
"shutdown - turn off the computer", 0Dh, 0Ah, \
|
||||||
|
"rfd - run program from disk", 0Dh, 0Ah, \
|
||||||
|
"dir - show files on disk", 0Dh, 0Ah, \
|
||||||
|
"rm <file> - remove file", 0Dh, 0Ah, \
|
||||||
|
"help - Show this menu", 0
|
||||||
|
|
||||||
|
cmd.cmd_mrun db "mrun", 0
|
||||||
|
cmd.cmd_mrun_desc db "Enter offset>", 0
|
||||||
|
|
||||||
|
cmd.cmd_stdfuncs db "stdfuncs", 0
|
||||||
|
cmd.cmd_stdfuncs_desc db "System functions:", 0
|
||||||
|
|
||||||
|
cmd.cmd_showmem db "showmem", 0
|
||||||
|
cmd.cmd_showmem_usage db "Usage: showmem <offset> <number of lines>", 0
|
||||||
|
; cmd.cmd_showmem_desc db "Enter offset>", 0
|
||||||
|
; cmd.cmd_showmem_desc1 db "Enter number of lines(16 bytes) to read>", 0
|
||||||
|
|
||||||
|
cmd.cmd_writemem db "writemem", 0
|
||||||
|
cmd.cmd_writemem_desc db "Enter offset>", 0
|
||||||
|
cmd.cmd_writemem_desc1 db "Enter value>", 0
|
||||||
|
|
||||||
|
cmd.cmd_addlink db "addlink", 0
|
||||||
|
cmd.cmd_addlink_desc db "Enter size>", 0
|
||||||
|
cmd.cmd_addlink_desc1 db "Enter filename>", 0
|
||||||
|
cmd.cmd_addlink_usage db "Usage: addlink <cylinder> <head> <sector>", 0
|
||||||
|
cmd.cmd_addlink_size db 0
|
||||||
|
|
||||||
|
cmd.cmd_loadmem db "loadmem", 0
|
||||||
|
cmd.cmd_loadmem_desc db "Enter numbers of sectors to read>", 0
|
||||||
|
cmd.cmd_loadmem_desc1 db "Enter drive to read>", 0
|
||||||
|
cmd.cmd_loadmem_desc2 db "Enter cylinder>", 0
|
||||||
|
cmd.cmd_loadmem_desc3 db "Enter head>", 0
|
||||||
|
cmd.cmd_loadmem_desc4 db "Enter number from which sector read>", 0
|
||||||
|
cmd.cmd_loadmem_desc5 db "Enter offset to load>", 0
|
||||||
|
cmd.cmd_loadmem_sectors db 0
|
||||||
|
cmd.cmd_loadmem_drive db 0
|
||||||
|
cmd.cmd_loadmem_cylinder db 0
|
||||||
|
cmd.cmd_loadmem_head db 0
|
||||||
|
cmd.cmd_loadmem_loadoffset db 0
|
||||||
|
cmd.cmd_loadmem_saveoffset dw 0
|
||||||
|
cmd.cmd_loadmem_loaderr db "Error while reading. See error code in AL", 0
|
||||||
|
|
||||||
|
cmd.cmd_run_nonex db "File is not executable or link is broken", 0
|
||||||
|
|
||||||
|
cmd.cmd_rfd db "rfd", 0
|
||||||
|
cmd.cmd_rfd_desc db "Enter len of program>", 0
|
||||||
|
cmd.cmd_rfd_desc1 db "Enter drive>", 0
|
||||||
|
cmd.cmd_rfd_desc4 db "Enter first sector>", 0
|
||||||
|
cmd.cmd_rfd_locateerr db "There are no any programs at your address", 0
|
||||||
|
|
||||||
|
cmd.cmd_dir db "dir", 0
|
||||||
|
|
||||||
|
cmd.cmd_rm db "rm", 0
|
||||||
|
cmd.cmd_rm_usage db "Usage: rm <file>", 0
|
||||||
|
|
||||||
|
; cmd.cmd_cf db "cf", 0
|
||||||
|
|
||||||
|
cmd.cmd_exit db "shutdown", 0
|
||||||
|
|
||||||
|
cmd.cmd_reboot db "reboot", 0
|
||||||
|
|
||||||
|
cmd.userinput_buf:
|
||||||
|
times USERINPUT_BUFFER_SIZE db 0
|
||||||
|
db 0
|
||||||
|
|
||||||
|
cmd.userinput_com:
|
||||||
|
times ARGUMENT_BUFFER_SIZE db 0
|
||||||
|
db 0
|
||||||
|
|
||||||
|
cmd.userinput_arg1:
|
||||||
|
times ARGUMENT_BUFFER_SIZE db 0
|
||||||
|
db 0
|
||||||
|
|
||||||
|
cmd.userinput_arg2:
|
||||||
|
times ARGUMENT_BUFFER_SIZE db 0
|
||||||
|
db 0
|
||||||
|
|
||||||
|
cmd.userinput_arg3:
|
||||||
|
times ARGUMENT_BUFFER_SIZE db 0
|
||||||
|
db 0
|
||||||
|
|
||||||
|
cmd.cmd_mrun_buf:
|
||||||
|
times INNUM_BUFFER_SIZE db 0
|
||||||
|
db 0
|
||||||
|
cmd.cmd_mrun_offset dw 0
|
|
@ -0,0 +1,8 @@
|
||||||
|
filetable:
|
||||||
|
filetable_ff db 0, 0, 6, 11, "kernel.bin", 0, 0 ; Cylinder, Head, Sector, Size, Name
|
||||||
|
db 0, 0, 17, 1, "calc.bin", 0, 0, 0, 0
|
||||||
|
db 0, 0, 18, 2, "viewer.bin", 0, 0
|
||||||
|
db 0, 1, 2, 1, 'null.bin', 0, 0, 0, 0
|
||||||
|
db 0, 1, 3, 1, "snake.bin", 0, 0, 0
|
||||||
|
|
||||||
|
times 2048-($-$$) db 0 ; 1024 bytes
|
|
@ -0,0 +1,846 @@
|
||||||
|
; Clear the screen and set cursor position to (0, 0)
|
||||||
|
clear:
|
||||||
|
push ax
|
||||||
|
mov ax, 03h
|
||||||
|
int 10h
|
||||||
|
mov ax, 200h
|
||||||
|
xor dx, dx
|
||||||
|
int 10h
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Detect display. Video mode 0 if no display,
|
||||||
|
; 1 if monochrome display, 2 if colour display
|
||||||
|
detect_video:
|
||||||
|
push ax
|
||||||
|
|
||||||
|
mov ax, 30h
|
||||||
|
and ax, DETECTED_HARDWARE
|
||||||
|
|
||||||
|
cmp ax, 20h
|
||||||
|
mov [VIDEO_MODE], 2
|
||||||
|
|
||||||
|
cmp ax, 30h
|
||||||
|
mov [VIDEO_MODE], 1
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Print terminated string
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on string
|
||||||
|
print_string:
|
||||||
|
pusha
|
||||||
|
mov cx, 1
|
||||||
|
mov bh, 0Fh
|
||||||
|
print_string.print:
|
||||||
|
lodsb
|
||||||
|
|
||||||
|
cmp al, 0
|
||||||
|
je print_string.finish
|
||||||
|
|
||||||
|
call print_symbol
|
||||||
|
jmp print_string.print
|
||||||
|
print_string.finish:
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Split user input on 4 parts by space
|
||||||
|
split_str_4_space:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
reset_buf cmd.userinput_com, ARGUMENT_BUFFER_SIZE
|
||||||
|
reset_buf cmd.userinput_arg1, ARGUMENT_BUFFER_SIZE
|
||||||
|
reset_buf cmd.userinput_arg2, ARGUMENT_BUFFER_SIZE
|
||||||
|
reset_buf cmd.userinput_arg3, ARGUMENT_BUFFER_SIZE
|
||||||
|
mov bx, cmd.userinput_com
|
||||||
|
mov si, cmd.userinput_buf
|
||||||
|
|
||||||
|
split_str_4_space.lp:
|
||||||
|
mov al, [si]
|
||||||
|
mov [bx], al
|
||||||
|
|
||||||
|
inc bx
|
||||||
|
inc si
|
||||||
|
|
||||||
|
cmp byte [si], ' '
|
||||||
|
je split_str_4_space.change_part
|
||||||
|
cmp byte [si], 0
|
||||||
|
je split_str_4_space.rtt
|
||||||
|
|
||||||
|
jmp split_str_4_space.lp
|
||||||
|
split_str_4_space.rtt:
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
mov byte [split_str_4_space.part], 1
|
||||||
|
ret
|
||||||
|
split_str_4_space.change_part:
|
||||||
|
cmp byte [split_str_4_space.part], 1
|
||||||
|
je split_str_4_space.change_part.part1
|
||||||
|
cmp byte [split_str_4_space.part], 2
|
||||||
|
je split_str_4_space.change_part.part2
|
||||||
|
cmp byte [split_str_4_space.part], 3
|
||||||
|
je split_str_4_space.change_part.part3
|
||||||
|
cmp byte [split_str_4_space.part], 4
|
||||||
|
je split_str_4_space.change_part.part4
|
||||||
|
|
||||||
|
split_str_4_space.part db 1
|
||||||
|
|
||||||
|
split_str_4_space.change_part.part1:
|
||||||
|
inc [split_str_4_space.part]
|
||||||
|
mov bx, cmd.userinput_arg1
|
||||||
|
inc si
|
||||||
|
jmp split_str_4_space.lp
|
||||||
|
split_str_4_space.change_part.part2:
|
||||||
|
inc [split_str_4_space.part]
|
||||||
|
mov bx, cmd.userinput_arg2
|
||||||
|
inc si
|
||||||
|
jmp split_str_4_space.lp
|
||||||
|
split_str_4_space.change_part.part3:
|
||||||
|
inc [split_str_4_space.part]
|
||||||
|
mov bx, cmd.userinput_arg3
|
||||||
|
inc si
|
||||||
|
jmp split_str_4_space.lp
|
||||||
|
split_str_4_space.change_part.part4:
|
||||||
|
jmp split_str_4_space.rtt
|
||||||
|
|
||||||
|
; Print symbol
|
||||||
|
;
|
||||||
|
; AL - symbol
|
||||||
|
print_symbol:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
xor bx, bx
|
||||||
|
mov cx, 1
|
||||||
|
mov ah, 0Eh
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; Reset buffer
|
||||||
|
; DS:SI - buffer
|
||||||
|
; CX - Length
|
||||||
|
reset_buffer:
|
||||||
|
push si
|
||||||
|
push cx
|
||||||
|
reset_buffer.lp:
|
||||||
|
mov byte [ds:si], 0
|
||||||
|
inc si
|
||||||
|
|
||||||
|
dec cx
|
||||||
|
cmp cx, 0
|
||||||
|
jne reset_buffer.lp
|
||||||
|
reset_buffer.nd:
|
||||||
|
pop cx
|
||||||
|
pop si
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Input string
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on buffer
|
||||||
|
; CX - Buffer length
|
||||||
|
; ---
|
||||||
|
; AX - Last pressed key
|
||||||
|
input_string:
|
||||||
|
push bx
|
||||||
|
mov bx, 0
|
||||||
|
|
||||||
|
input_string.reset_buffer:
|
||||||
|
push si
|
||||||
|
push cx
|
||||||
|
input_string.reset_buffer.lp:
|
||||||
|
mov byte [ds:si], 0
|
||||||
|
inc si
|
||||||
|
|
||||||
|
dec cx
|
||||||
|
cmp cx, 0
|
||||||
|
jne input_string.reset_buffer.lp
|
||||||
|
input_string.reset_buffer.nd:
|
||||||
|
pop cx
|
||||||
|
pop si
|
||||||
|
|
||||||
|
input_string.processing:
|
||||||
|
xor ah, ah
|
||||||
|
int 16h
|
||||||
|
|
||||||
|
cmp al, 0Dh
|
||||||
|
je input_string.ent
|
||||||
|
|
||||||
|
cmp al, 08h
|
||||||
|
je input_string.backspace
|
||||||
|
|
||||||
|
cmp al, 03h
|
||||||
|
je input_string.ctrlc
|
||||||
|
|
||||||
|
call print_symbol
|
||||||
|
|
||||||
|
mov [ds:si+bx], al
|
||||||
|
inc bx
|
||||||
|
|
||||||
|
cmp bx, cx
|
||||||
|
je input_string.ent
|
||||||
|
|
||||||
|
jmp input_string.processing
|
||||||
|
input_string.backspace:
|
||||||
|
cmp bx, 0
|
||||||
|
je input_string.processing
|
||||||
|
|
||||||
|
mov ah, 0Eh
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov al, ' '
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov al, 08h
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
dec bx
|
||||||
|
mov byte [ds:si+bx], 0
|
||||||
|
|
||||||
|
jmp input_string.processing
|
||||||
|
input_string.ent:
|
||||||
|
pop bx
|
||||||
|
xor ah, ah
|
||||||
|
print ln
|
||||||
|
ret
|
||||||
|
input_string.ctrlc:
|
||||||
|
jmp input_string.ent
|
||||||
|
|
||||||
|
; Compare strings
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on first string
|
||||||
|
; DS:BX - Pointer on second string
|
||||||
|
; ---
|
||||||
|
; Carry flag - 1 if strings are not equal
|
||||||
|
compare_strings:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push si
|
||||||
|
compare_strings.comp:
|
||||||
|
lodsb
|
||||||
|
|
||||||
|
cmp [bx], al
|
||||||
|
jne compare_strings.not_equal
|
||||||
|
cmp al, 0
|
||||||
|
je compare_strings.equal
|
||||||
|
|
||||||
|
inc bx
|
||||||
|
|
||||||
|
jmp compare_strings.comp
|
||||||
|
compare_strings.equal:
|
||||||
|
clc
|
||||||
|
jmp compare_strings.return
|
||||||
|
compare_strings.not_equal:
|
||||||
|
stc
|
||||||
|
jmp compare_strings.return
|
||||||
|
compare_strings.return:
|
||||||
|
pop si
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Copies string
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on memory from where copy
|
||||||
|
; DS:BX - Pointer on memory where copy
|
||||||
|
copy_string:
|
||||||
|
push si
|
||||||
|
push bx
|
||||||
|
push ax
|
||||||
|
copy_string.lp:
|
||||||
|
lodsb
|
||||||
|
|
||||||
|
cmp al, 0
|
||||||
|
je copy_string.ed
|
||||||
|
|
||||||
|
mov byte [bx], al
|
||||||
|
|
||||||
|
inc bx
|
||||||
|
|
||||||
|
jmp copy_string.lp
|
||||||
|
copy_string.ed:
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
pop si
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Calculate len of string
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on string
|
||||||
|
; ---
|
||||||
|
; AX - Len of string
|
||||||
|
calculate_string_len:
|
||||||
|
push si
|
||||||
|
xor ax, ax
|
||||||
|
push ax
|
||||||
|
calculate_string_len.lp:
|
||||||
|
lodsb
|
||||||
|
cmp al, 0
|
||||||
|
je calculate_string_len.ed
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
inc ax
|
||||||
|
push ax
|
||||||
|
|
||||||
|
jmp calculate_string_len.lp
|
||||||
|
calculate_string_len.ed:
|
||||||
|
pop ax
|
||||||
|
pop si
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; os_print_digit -- Displays contents of AX as a single digit
|
||||||
|
; Works up to base 37, ie digits 0-Z
|
||||||
|
; IN: AX = "digit" to format and print
|
||||||
|
|
||||||
|
os_print_digit:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
cmp ax, 9 ; There is a break in ASCII table between 9 and A
|
||||||
|
jle .digit_format
|
||||||
|
|
||||||
|
add ax, 'A'-'9'-1 ; Correct for the skipped punctuation
|
||||||
|
|
||||||
|
.digit_format:
|
||||||
|
add ax, "0" ; 0 will display as '0', etc.
|
||||||
|
|
||||||
|
mov ah, 0Eh ; May modify other registers
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; os_print_1hex -- Displays low nibble of AL in hex format
|
||||||
|
; IN: AL = number to format and print
|
||||||
|
|
||||||
|
os_print_1hex:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
and ax, 0Fh ; Mask off data to display
|
||||||
|
call os_print_digit
|
||||||
|
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Print AL in hex
|
||||||
|
;
|
||||||
|
; AL - Number to print
|
||||||
|
os_print_2hex:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
push ax ; Output high nibble
|
||||||
|
shr ax, 4
|
||||||
|
call os_print_1hex
|
||||||
|
|
||||||
|
pop ax ; Output low nibble
|
||||||
|
call os_print_1hex
|
||||||
|
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; Print AX in hex
|
||||||
|
;
|
||||||
|
; AX - Number to print
|
||||||
|
print_hex:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
push ax ; Output high byte
|
||||||
|
mov al, ah
|
||||||
|
call os_print_2hex
|
||||||
|
|
||||||
|
pop ax ; Output low byte
|
||||||
|
call os_print_2hex
|
||||||
|
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Print values of registers to screen
|
||||||
|
;
|
||||||
|
; AX, BX, CX, DX, SI, DI, ES, DS, SS, FLAGS - Registers to print
|
||||||
|
print_registers:
|
||||||
|
pushf
|
||||||
|
push ss
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push di
|
||||||
|
push si
|
||||||
|
push dx
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
|
||||||
|
print print_registers.axd
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.bxd
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h, ln
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.cxd
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.dxd
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h, ln
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.sid
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.did
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h, ln
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.esd
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.dsd
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h, ln
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.ssd
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
print print_registers.fd
|
||||||
|
call print_hex
|
||||||
|
print print_registers.h, ln
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; os_string_to_int -- Convert decimal string to integer value
|
||||||
|
; IN: SI = string location (max 5 chars, up to '65536')
|
||||||
|
; OUT: AX = number
|
||||||
|
string_to_int:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
mov ax, si ; First, get length of string
|
||||||
|
call os_string_length
|
||||||
|
|
||||||
|
add si, ax ; Work from rightmost char in string
|
||||||
|
dec si
|
||||||
|
|
||||||
|
mov cx, ax ; Use string length as counter
|
||||||
|
|
||||||
|
mov bx, 0 ; BX will be the final number
|
||||||
|
mov ax, 0
|
||||||
|
|
||||||
|
|
||||||
|
; As we move left in the string, each char is a bigger multiple. The
|
||||||
|
; right-most character is a multiple of 1, then next (a char to the
|
||||||
|
; left) a multiple of 10, then 100, then 1,000, and the final (and
|
||||||
|
; leftmost char) in a five-char number would be a multiple of 10,000
|
||||||
|
|
||||||
|
mov word [.multiplier], 1 ; Start with multiples of 1
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
mov ax, 0
|
||||||
|
mov byte al, [si] ; Get character
|
||||||
|
sub al, 48 ; Convert from ASCII to real number
|
||||||
|
|
||||||
|
mul word [.multiplier] ; Multiply by our multiplier
|
||||||
|
|
||||||
|
add bx, ax ; Add it to BX
|
||||||
|
|
||||||
|
push ax ; Multiply our multiplier by 10 for next char
|
||||||
|
mov word ax, [.multiplier]
|
||||||
|
mov dx, 10
|
||||||
|
mul dx
|
||||||
|
mov word [.multiplier], ax
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
dec cx ; Any more chars?
|
||||||
|
cmp cx, 0
|
||||||
|
je .finish
|
||||||
|
dec si ; Move back a char in the string
|
||||||
|
jmp .loop
|
||||||
|
|
||||||
|
.finish:
|
||||||
|
mov word [.tmp], bx
|
||||||
|
popa
|
||||||
|
mov word ax, [.tmp]
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
.multiplier dw 0
|
||||||
|
.tmp dw 0
|
||||||
|
|
||||||
|
os_string_length:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
mov bx, ax ; Move location of string to BX
|
||||||
|
|
||||||
|
mov cx, 0 ; Counter
|
||||||
|
|
||||||
|
.more:
|
||||||
|
cmp byte [bx], 0 ; Zero (end of string) yet?
|
||||||
|
je .done
|
||||||
|
inc bx ; If not, keep adding
|
||||||
|
inc cx
|
||||||
|
jmp .more
|
||||||
|
|
||||||
|
|
||||||
|
.done:
|
||||||
|
mov word [.tmp_counter], cx ; Store count before restoring other registers
|
||||||
|
popa
|
||||||
|
|
||||||
|
mov ax, [.tmp_counter] ; Put count back into AX before returning
|
||||||
|
ret
|
||||||
|
|
||||||
|
.tmp_counter dw 0
|
||||||
|
|
||||||
|
; Convert unsigned int to string
|
||||||
|
;
|
||||||
|
; AX - Num to convert
|
||||||
|
; SI - Where save string
|
||||||
|
; ---
|
||||||
|
; SI - Pointer to string with converted num
|
||||||
|
int_to_string:
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push di
|
||||||
|
push ax
|
||||||
|
|
||||||
|
mov cx, 0
|
||||||
|
mov bx, 10 ; Set BX 10, for division and mod
|
||||||
|
mov di, si ; Get our pointer ready
|
||||||
|
|
||||||
|
int_to_string.push:
|
||||||
|
mov dx, 0
|
||||||
|
div bx ; Remainder in DX, quotient in AX
|
||||||
|
inc cx ; Increase pop loop counter
|
||||||
|
push dx ; Push remainder, so as to reverse order when popping
|
||||||
|
test ax, ax ; Is quotient zero?
|
||||||
|
jnz int_to_string.push ; If not, loop again
|
||||||
|
int_to_string.pop:
|
||||||
|
pop dx ; Pop off values in reverse order, and add 48 to make them digits
|
||||||
|
add dl, '0' ; And save them in the string, increasing the pointer each time
|
||||||
|
mov [di], dl
|
||||||
|
inc di
|
||||||
|
dec cx
|
||||||
|
jnz int_to_string.pop
|
||||||
|
|
||||||
|
mov byte [di], 0 ; Zero-terminate string
|
||||||
|
|
||||||
|
mov si, di
|
||||||
|
pop ax
|
||||||
|
pop di
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Find file on disk from filename
|
||||||
|
; BX - filename
|
||||||
|
; ---
|
||||||
|
; SI - filename position in table
|
||||||
|
; CF - 1 if file not exist
|
||||||
|
find_file:
|
||||||
|
push bx
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
mov cx, TABLE_SIZE
|
||||||
|
mov si, filetable
|
||||||
|
add si, 4
|
||||||
|
mov [find_file.fn_offset], bx
|
||||||
|
find_file.lp:
|
||||||
|
|
||||||
|
mov bx, [find_file.fn_offset]
|
||||||
|
call compare_strings
|
||||||
|
jnc find_file.found
|
||||||
|
|
||||||
|
dec cx
|
||||||
|
cmp cx, 0
|
||||||
|
je find_fileret
|
||||||
|
|
||||||
|
mov bx, 12
|
||||||
|
; len si
|
||||||
|
xor ax, ax
|
||||||
|
sub bx, ax
|
||||||
|
xchg ax, bx
|
||||||
|
add si, ax
|
||||||
|
add si, 4
|
||||||
|
; mov al, [si]
|
||||||
|
; cmp al, 0
|
||||||
|
je find_fileret
|
||||||
|
jmp find_file.lp
|
||||||
|
find_file.found:
|
||||||
|
sub si, 4
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
find_fileret:
|
||||||
|
xor si, si
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
|
||||||
|
find_file.fn_offset dw 0
|
||||||
|
|
||||||
|
; Remove file
|
||||||
|
; BX - filename
|
||||||
|
; ---
|
||||||
|
; CF - 1 if file not exist
|
||||||
|
remove_file:
|
||||||
|
push ax
|
||||||
|
push si
|
||||||
|
push bx
|
||||||
|
|
||||||
|
call find_file
|
||||||
|
jc remove_file.rtt
|
||||||
|
|
||||||
|
mov dword [si], 0
|
||||||
|
add si, 2
|
||||||
|
mov dword [si], 0
|
||||||
|
add si, 2
|
||||||
|
mov dword [si], 0
|
||||||
|
add si, 2
|
||||||
|
mov dword [si], 0
|
||||||
|
add si, 2
|
||||||
|
mov dword [si], 0
|
||||||
|
add si, 2
|
||||||
|
mov dword [si], 0
|
||||||
|
add si, 2
|
||||||
|
mov dword [si], 0
|
||||||
|
add si, 2
|
||||||
|
mov dword [si], 0
|
||||||
|
|
||||||
|
pop bx
|
||||||
|
pop si
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
remove_file.rtt:
|
||||||
|
pop bx
|
||||||
|
pop si
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Append file to FS table
|
||||||
|
; AL - Cylinder
|
||||||
|
; AH - Head
|
||||||
|
; BL - sector
|
||||||
|
; BH - Size
|
||||||
|
; SI - Pointer on name (Max 11 chars)
|
||||||
|
append_file:
|
||||||
|
pusha
|
||||||
|
mov [append_file.cylinder], al
|
||||||
|
mov [append_file.head], ah
|
||||||
|
mov [append_file.sector], bl
|
||||||
|
mov [append_file.size], bh
|
||||||
|
mov word [append_file.name_os], si
|
||||||
|
mov cx, TABLE_SIZE
|
||||||
|
mov si, filetable+4
|
||||||
|
append_file.lp:
|
||||||
|
cmp byte [si], 0
|
||||||
|
je append_file.write
|
||||||
|
add si, 16
|
||||||
|
dec cx
|
||||||
|
cmp cx, 0
|
||||||
|
je append_file.cannot
|
||||||
|
jmp append_file.lp
|
||||||
|
append_file.nd:
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
append_file.write:
|
||||||
|
sub si, 4
|
||||||
|
mov al, [append_file.cylinder]
|
||||||
|
mov ah, [append_file.head]
|
||||||
|
mov bl, [append_file.sector]
|
||||||
|
mov bh, [append_file.size]
|
||||||
|
mov byte [si], al
|
||||||
|
mov byte [si+1], ah
|
||||||
|
mov byte [si+2], bl
|
||||||
|
mov byte [si+3], bh
|
||||||
|
add si, 4
|
||||||
|
mov bx, si
|
||||||
|
mov si, word [append_file.name_os]
|
||||||
|
call copy_string
|
||||||
|
clc
|
||||||
|
call write_table
|
||||||
|
jmp append_file.nd
|
||||||
|
append_file.cannot:
|
||||||
|
stc
|
||||||
|
jmp append_file.nd
|
||||||
|
|
||||||
|
append_file.cylinder db 0
|
||||||
|
append_file.head db 0
|
||||||
|
append_file.sector db 0
|
||||||
|
append_file.size db 0
|
||||||
|
append_file.name_os dw 0
|
||||||
|
|
||||||
|
; Rename file in FS table
|
||||||
|
; SI - Filename
|
||||||
|
; BX - To what filename change
|
||||||
|
rename_file:
|
||||||
|
pusha
|
||||||
|
mov word [rename_file.fst], si
|
||||||
|
mov word [rename_file.snd], bx
|
||||||
|
mov bx, si
|
||||||
|
call find_file
|
||||||
|
jc rename_file.notfound
|
||||||
|
add si, 4
|
||||||
|
push si
|
||||||
|
reset_buf si, 12
|
||||||
|
pop si
|
||||||
|
mov bx, si
|
||||||
|
mov si, word [rename_file.snd]
|
||||||
|
call copy_string
|
||||||
|
rename_file.notfound:
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
rename_file.fst dw 0
|
||||||
|
rename_file.snd dw 0
|
||||||
|
|
||||||
|
; Read file and load to memory
|
||||||
|
; SI - File in FS table
|
||||||
|
; BX - Where load
|
||||||
|
load_file:
|
||||||
|
pusha
|
||||||
|
mov ah, 02h
|
||||||
|
mov al, [si+3]
|
||||||
|
mov dl, [BOOT_DRIVE]
|
||||||
|
mov ch, [si]
|
||||||
|
mov dh, [si+1]
|
||||||
|
mov cl, [si+2]
|
||||||
|
int 13h
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; loadoffset dw 0
|
||||||
|
|
||||||
|
; Write file and load to memory
|
||||||
|
; SI - File in FS table
|
||||||
|
; CX - Where
|
||||||
|
save_file:
|
||||||
|
pusha
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Read FS table from disk
|
||||||
|
read_table:
|
||||||
|
pusha
|
||||||
|
mov ah, 02h
|
||||||
|
mov al, 2
|
||||||
|
mov dl, [BOOT_DRIVE]
|
||||||
|
mov ch, 0
|
||||||
|
mov dh, 0
|
||||||
|
mov cl, 3
|
||||||
|
mov bx, filetable
|
||||||
|
int 13h
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Write FS table to disk
|
||||||
|
write_table:
|
||||||
|
pusha
|
||||||
|
mov ah, 03h
|
||||||
|
mov al, 2
|
||||||
|
mov dl, [BOOT_DRIVE]
|
||||||
|
mov ch, 0
|
||||||
|
mov dh, 0
|
||||||
|
mov cl, 3
|
||||||
|
mov bx, filetable
|
||||||
|
int 13h
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
wait_key:
|
||||||
|
mov ah, 11h
|
||||||
|
int 16h
|
||||||
|
|
||||||
|
jnz wait_key.key_pressed
|
||||||
|
|
||||||
|
hlt
|
||||||
|
jmp wait_key
|
||||||
|
|
||||||
|
wait_key.key_pressed:
|
||||||
|
mov ah, 10h
|
||||||
|
int 16h
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Copy memory from A to B
|
||||||
|
; SI - A
|
||||||
|
; BX - B
|
||||||
|
; CX - Number of bytes to copy
|
||||||
|
copy_memory:
|
||||||
|
pusha
|
||||||
|
copy_memory.lp:
|
||||||
|
cmp cx, 0
|
||||||
|
je copy_memory.nd
|
||||||
|
lodsb
|
||||||
|
mov [bx], al
|
||||||
|
inc bx
|
||||||
|
dec cx
|
||||||
|
jmp copy_memory.lp
|
||||||
|
copy_memory.nd:
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Get cursor position
|
||||||
|
; ---
|
||||||
|
; DL - X
|
||||||
|
; DH - Y
|
||||||
|
get_cursor_pos:
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
mov ah, 03h
|
||||||
|
xor bx, bx
|
||||||
|
int 10h
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Set cursor position
|
||||||
|
; DL - X
|
||||||
|
; DH - Y
|
||||||
|
set_cursor_pos:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
mov ah, 02h
|
||||||
|
xor bx, bx
|
||||||
|
int 10h
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Print values of registers and halt cpu
|
||||||
|
dbg_halt_cpu:
|
||||||
|
call print_registers
|
||||||
|
call halt_cpu
|
||||||
|
|
||||||
|
; Shows goodbye message and stops the CPU
|
||||||
|
halt_cpu:
|
||||||
|
print ln, goodbye
|
||||||
|
cli
|
||||||
|
hlt
|
|
@ -0,0 +1,74 @@
|
||||||
|
functable:
|
||||||
|
|
||||||
|
dw clear
|
||||||
|
dw detect_video
|
||||||
|
dw print_string
|
||||||
|
dw print_symbol
|
||||||
|
dw input_string
|
||||||
|
dw compare_strings
|
||||||
|
dw copy_string
|
||||||
|
dw calculate_string_len
|
||||||
|
dw os_print_digit
|
||||||
|
dw os_print_1hex
|
||||||
|
dw os_print_2hex
|
||||||
|
dw print_hex
|
||||||
|
dw print_registers
|
||||||
|
dw string_to_int
|
||||||
|
dw int_to_string
|
||||||
|
dw dbg_halt_cpu
|
||||||
|
dw halt_cpu
|
||||||
|
dw its
|
||||||
|
dw find_file
|
||||||
|
dw remove_file
|
||||||
|
dw write_table
|
||||||
|
dw cmd.userinput_arg1
|
||||||
|
dw cmd.userinput_arg2
|
||||||
|
dw cmd.userinput_arg3
|
||||||
|
dw reset_buffer
|
||||||
|
dw append_file
|
||||||
|
dw rename_file
|
||||||
|
dw load_file
|
||||||
|
dw save_file
|
||||||
|
dw wait_key
|
||||||
|
dw copy_memory
|
||||||
|
dw get_cursor_pos
|
||||||
|
dw set_cursor_pos
|
||||||
|
dw read_table
|
||||||
|
dw 0
|
||||||
|
|
||||||
|
times 1024 - ($-$$) db 0
|
||||||
|
|
||||||
|
; FUNCTABLE EQU 7E00h
|
||||||
|
; clear EQU word [7E00h]
|
||||||
|
; detect_video EQU word [7E02h]
|
||||||
|
; print_string EQU word [7E04h]
|
||||||
|
; print_symbol EQU word [7E06h]
|
||||||
|
; input_string EQU word [7E08h]
|
||||||
|
; compare_strings EQU word [7E0Ah]
|
||||||
|
; copy_string EQU word [7E0Ch]
|
||||||
|
; calculate_string_len EQU word [7E0Eh]
|
||||||
|
; os_print_digit EQU word [7E10h]
|
||||||
|
; os_print_1hex EQU word [7E12h]
|
||||||
|
; os_print_2hex EQU word [7E14h]
|
||||||
|
; print_hex EQU word [7E16h]
|
||||||
|
; print_registers EQU word [7E18h]
|
||||||
|
; string_to_int EQU word [7E1Ah]
|
||||||
|
; int_to_string EQU word [7E1Ch]
|
||||||
|
; dbg_halt_cpu EQU word [7E1Eh]
|
||||||
|
; halt_cpu EQU word [7E20h]
|
||||||
|
; its EQU word [7E22h]
|
||||||
|
; find_file EQU word [7E24h]
|
||||||
|
; remove_file EQU word [7E26h]
|
||||||
|
; write_table EQU word [7E28h]
|
||||||
|
; arg1 EQU word [7E2Ah]
|
||||||
|
; arg2 EQU word [7E2Ch]
|
||||||
|
; arg3 EQU word [7E2Eh]
|
||||||
|
; reset_buffer EQU word [7E30h]
|
||||||
|
; append_file EQU word [7E32h]
|
||||||
|
; rename_file EQU word [7E34h]
|
||||||
|
; load_file EQU word [7E36h]
|
||||||
|
; save_file EQU word [7E38h]
|
||||||
|
; wait_key EQU word [7E3Ah]
|
||||||
|
; copy_memory EQU word [7E3Ch]
|
||||||
|
; get_cursor_pos EQU word [7E3Eh]
|
||||||
|
; set_cursor_pos EQU word [7E40h]
|
|
@ -0,0 +1,152 @@
|
||||||
|
; Clear the screen and set cursor position to (0, 0)
|
||||||
|
clear:
|
||||||
|
|
||||||
|
; Detect display. Video mode 0 if no display,
|
||||||
|
; 1 if monochrome display, 2 if colour display
|
||||||
|
detect_video:
|
||||||
|
|
||||||
|
; Print terminated string
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on string
|
||||||
|
print_string:
|
||||||
|
|
||||||
|
; Print symbol
|
||||||
|
;
|
||||||
|
; AL - symbol
|
||||||
|
; print_symbol:
|
||||||
|
|
||||||
|
; Reset buffer
|
||||||
|
; DS:SI - buffer
|
||||||
|
; CX - Length
|
||||||
|
reset_buffer:
|
||||||
|
|
||||||
|
; Input string
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on buffer
|
||||||
|
; CX - Buffer length
|
||||||
|
; ---
|
||||||
|
; AX - Last pressed key
|
||||||
|
input_string:
|
||||||
|
|
||||||
|
; Compare strings
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on first string
|
||||||
|
; DS:BX - Pointer on second string
|
||||||
|
; ---
|
||||||
|
; Carry flag - 1 if strings are not equal
|
||||||
|
compare_strings:
|
||||||
|
|
||||||
|
; Copies string
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on memory from where copy
|
||||||
|
; DS:BX - Pointer on memory where copy
|
||||||
|
copy_string:
|
||||||
|
|
||||||
|
; Calculate len of string
|
||||||
|
;
|
||||||
|
; DS:SI - Pointer on string
|
||||||
|
; ---
|
||||||
|
; AX - Len of string
|
||||||
|
calculate_string_len:
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; os_print_digit -- Displays contents of AX as a single digit
|
||||||
|
; Works up to base 37, ie digits 0-Z
|
||||||
|
; IN: AX = "digit" to format and print
|
||||||
|
os_print_digit:
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; os_print_1hex -- Displays low nibble of AL in hex format
|
||||||
|
; IN: AL = number to format and print
|
||||||
|
os_print_1hex:
|
||||||
|
|
||||||
|
; Print AL in hex
|
||||||
|
;
|
||||||
|
; AL - Number to print
|
||||||
|
os_print_2hex:
|
||||||
|
|
||||||
|
; Print AX in hex
|
||||||
|
;
|
||||||
|
; AX - Number to print
|
||||||
|
print_hex:
|
||||||
|
|
||||||
|
; Print values of registers to screen
|
||||||
|
;
|
||||||
|
; AX, BX, CX, DX, SI, DI, ES, DS, SS, FLAGS - Registers to print
|
||||||
|
print_registers:
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; os_string_to_int -- Convert decimal string to integer value
|
||||||
|
; IN: SI = string location (max 5 chars, up to '65536')
|
||||||
|
; OUT: AX = number
|
||||||
|
string_to_int:
|
||||||
|
|
||||||
|
; Convert unsigned int to string
|
||||||
|
;
|
||||||
|
; AX - Num to convert
|
||||||
|
; SI - Where save string
|
||||||
|
; ---
|
||||||
|
; SI - Pointer to string with converted num
|
||||||
|
int_to_string:
|
||||||
|
|
||||||
|
; Find file on disk from filename
|
||||||
|
; BX - filename
|
||||||
|
; ---
|
||||||
|
; SI - filename position in table
|
||||||
|
; CF - 1 if file not exist
|
||||||
|
find_file:
|
||||||
|
|
||||||
|
; Remove file
|
||||||
|
; BX - filename
|
||||||
|
; ---
|
||||||
|
; CF - 1 if file not exist
|
||||||
|
remove_file:
|
||||||
|
|
||||||
|
; Append file to FS table
|
||||||
|
; AL - Cylinder
|
||||||
|
; AH - Head
|
||||||
|
; BL - sector
|
||||||
|
; BH - Size
|
||||||
|
; SI - Pointer on name (Max 11 chars)
|
||||||
|
append_file:
|
||||||
|
|
||||||
|
; Rename file in FS table
|
||||||
|
; SI - Filename
|
||||||
|
; BX - To what filename change
|
||||||
|
rename_file:
|
||||||
|
|
||||||
|
; Read file and load to memory
|
||||||
|
; SI - File in FS table
|
||||||
|
; CX - Where load
|
||||||
|
load_file:
|
||||||
|
|
||||||
|
; Write file and load to memory
|
||||||
|
; SI - File in FS table
|
||||||
|
; CX - Where
|
||||||
|
save_file:
|
||||||
|
|
||||||
|
; Write FS table to disk
|
||||||
|
write_table:
|
||||||
|
|
||||||
|
; Copy memory from A to B
|
||||||
|
; SI - A
|
||||||
|
; BX - B
|
||||||
|
; CX - Number of bytes to copy
|
||||||
|
copy_memory:
|
||||||
|
|
||||||
|
; Get cursor position
|
||||||
|
; ---
|
||||||
|
; DL - X
|
||||||
|
; DH - Y
|
||||||
|
get_cursor_pos:
|
||||||
|
|
||||||
|
; Set cursor position
|
||||||
|
; DL - X
|
||||||
|
; DH - Y
|
||||||
|
set_cursor_pos:
|
||||||
|
|
||||||
|
; Print values of registers and halt cpu
|
||||||
|
dbg_halt_cpu:
|
||||||
|
|
||||||
|
; Shows goodbye message and stops the CPU
|
||||||
|
halt_cpu:
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,10 @@
|
||||||
|
Privet, ti 4udovishe
|
||||||
|
Novay strok
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dolistay ahaha
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,480 @@
|
||||||
|
; main:
|
||||||
|
; call clear
|
||||||
|
; print greetings
|
||||||
|
; mainloop:
|
||||||
|
; print parol
|
||||||
|
|
||||||
|
; input input_data, BUFFER_SIZE
|
||||||
|
|
||||||
|
; cmp_strs right_password, input_data
|
||||||
|
; jnc correct
|
||||||
|
; print incorrect_password, ln
|
||||||
|
|
||||||
|
; jmp mainloop
|
||||||
|
|
||||||
|
; correct:
|
||||||
|
; print password_done
|
||||||
|
; jmp dbg_halt_cpu
|
||||||
|
|
||||||
|
main:
|
||||||
|
call clear
|
||||||
|
print greetings, ln
|
||||||
|
mainloop:
|
||||||
|
push ax
|
||||||
|
xor ax, ax
|
||||||
|
mov al, [BOOT_DRIVE]
|
||||||
|
call its
|
||||||
|
pop ax
|
||||||
|
print cmd.prefix
|
||||||
|
|
||||||
|
input cmd.userinput_buf, USERINPUT_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainret
|
||||||
|
call split_str_4_space
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_help
|
||||||
|
jnc command.help
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_mrun
|
||||||
|
jnc command.mrun
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_stdfuncs
|
||||||
|
jnc command.stdfuncs
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_showmem
|
||||||
|
jnc command.showmem
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_writemem
|
||||||
|
jnc command.writemem
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_loadmem
|
||||||
|
jnc command.loadmem
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_exit
|
||||||
|
jnc command.shutdown
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_rfd
|
||||||
|
jnc command.rfd
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_dir
|
||||||
|
jnc command.dir
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_com, cmd.cmd_rm
|
||||||
|
jnc command.rm
|
||||||
|
|
||||||
|
cmp_strs cmd.userinput_buf, cmd.cmd_reboot
|
||||||
|
jnc command.reboot
|
||||||
|
|
||||||
|
; cmp_strs cmd.userinput_com, cmd.cmd_addlink
|
||||||
|
; jnc command.addlink
|
||||||
|
|
||||||
|
len cmd.userinput_com
|
||||||
|
cmp ax, 0
|
||||||
|
je mainloop.continue
|
||||||
|
|
||||||
|
mov bx, cmd.userinput_com
|
||||||
|
call find_file
|
||||||
|
jnc command.run
|
||||||
|
|
||||||
|
mainloop.continue:
|
||||||
|
|
||||||
|
print cmd.inc_com
|
||||||
|
|
||||||
|
jmp mainloop
|
||||||
|
mainret:
|
||||||
|
ret
|
||||||
|
|
||||||
|
command.help:
|
||||||
|
print cmd.cmd_help_desc, ln
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
|
||||||
|
command.mrun:
|
||||||
|
print cmd.cmd_mrun_desc
|
||||||
|
input cmd.cmd_mrun_buf, INNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
|
||||||
|
str_to_i cmd.cmd_mrun_buf
|
||||||
|
add ax, 7C00h
|
||||||
|
mov word [cmd.cmd_mrun_offset], ax
|
||||||
|
call ax
|
||||||
|
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
|
||||||
|
command.stdfuncs:
|
||||||
|
print cmd.cmd_stdfuncs_desc, ln
|
||||||
|
mov si, functable
|
||||||
|
push si
|
||||||
|
command.stdfuncs.lp:
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
cmp ax, 0
|
||||||
|
je command.stdfuncsret
|
||||||
|
sub ax, 7C00h
|
||||||
|
call its
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
cmp ax, 0
|
||||||
|
je command.stdfuncsret_med
|
||||||
|
sub ax, 7C00h
|
||||||
|
call its
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
cmp ax, 0
|
||||||
|
je command.stdfuncsret_med
|
||||||
|
sub ax, 7C00h
|
||||||
|
call its
|
||||||
|
print ln
|
||||||
|
jmp command.stdfuncs.lp
|
||||||
|
command.stdfuncsret_med:
|
||||||
|
print ln
|
||||||
|
pop si
|
||||||
|
jmp mainloop
|
||||||
|
command.stdfuncsret:
|
||||||
|
pop si
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
|
||||||
|
command.showmem:
|
||||||
|
len cmd.userinput_arg2
|
||||||
|
cmp ax, 0
|
||||||
|
je command.showmem_usageret
|
||||||
|
str_to_i cmd.userinput_arg1
|
||||||
|
add ax, 7C00h
|
||||||
|
mov si, ax
|
||||||
|
push si
|
||||||
|
|
||||||
|
str_to_i cmd.userinput_arg2
|
||||||
|
mov cx, ax
|
||||||
|
|
||||||
|
command.showmem.lp:
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
xchg ah, al
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
call print_hex
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
xchg ah, al
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
call print_hex
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
xchg ah, al
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
call print_hex
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
xchg ah, al
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
call print_hex
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
xchg ah, al
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
call print_hex
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
xchg ah, al
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
call print_hex
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
xchg ah, al
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
call print_hex
|
||||||
|
print space
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ax, [si]
|
||||||
|
xchg ah, al
|
||||||
|
add si, 2
|
||||||
|
push si
|
||||||
|
call print_hex
|
||||||
|
print ln
|
||||||
|
|
||||||
|
dec cx
|
||||||
|
cmp cx, 0
|
||||||
|
je mainloop
|
||||||
|
|
||||||
|
jmp command.showmem.lp
|
||||||
|
command.showmem_usageret:
|
||||||
|
print cmd.cmd_showmem_usage, ln
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
|
||||||
|
command.writemem:
|
||||||
|
print cmd.cmd_writemem_desc
|
||||||
|
input cmd.userinput_buf, INNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
add ax, 7C00h
|
||||||
|
push ax
|
||||||
|
|
||||||
|
print cmd.cmd_writemem_desc1
|
||||||
|
input cmd.userinput_buf, INNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
pop si
|
||||||
|
|
||||||
|
mov [si], ax
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
|
||||||
|
command.loadmem:
|
||||||
|
print cmd.cmd_loadmem_desc
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_sectors], al
|
||||||
|
|
||||||
|
print cmd.cmd_loadmem_desc1
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_drive], al
|
||||||
|
|
||||||
|
print cmd.cmd_loadmem_desc2
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_cylinder], al
|
||||||
|
|
||||||
|
print cmd.cmd_loadmem_desc3
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_head], al
|
||||||
|
|
||||||
|
print cmd.cmd_loadmem_desc4
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_loadoffset], al
|
||||||
|
|
||||||
|
print cmd.cmd_loadmem_desc5
|
||||||
|
input cmd.userinput_buf, INNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov word [cmd.cmd_loadmem_saveoffset], ax
|
||||||
|
|
||||||
|
mov ah, 02h
|
||||||
|
mov al, byte [cmd.cmd_loadmem_sectors]
|
||||||
|
mov dl, byte [cmd.cmd_loadmem_drive]
|
||||||
|
mov ch, byte [cmd.cmd_loadmem_cylinder]
|
||||||
|
mov dh, byte [cmd.cmd_loadmem_head]
|
||||||
|
mov cl, byte [cmd.cmd_loadmem_loadoffset]
|
||||||
|
mov bx, word [cmd.cmd_loadmem_saveoffset]
|
||||||
|
add bx, 7C00h
|
||||||
|
int 13h
|
||||||
|
jc command.loadmem_err
|
||||||
|
jmp mainloop
|
||||||
|
command.loadmem_err:
|
||||||
|
call print_registers
|
||||||
|
print cmd.cmd_loadmem_loaderr, ln
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
command.shutdown:
|
||||||
|
mov ax, 5307h
|
||||||
|
mov bx, 01h
|
||||||
|
mov cx, 03h
|
||||||
|
int 15h
|
||||||
|
ret
|
||||||
|
|
||||||
|
command.rfd:
|
||||||
|
print cmd.cmd_rfd_desc
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_sectors], al
|
||||||
|
|
||||||
|
print cmd.cmd_rfd_desc1
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_drive], al
|
||||||
|
|
||||||
|
print cmd.cmd_loadmem_desc2
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_cylinder], al
|
||||||
|
|
||||||
|
print cmd.cmd_loadmem_desc3
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_head], al
|
||||||
|
|
||||||
|
print cmd.cmd_rfd_desc4
|
||||||
|
input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je mainloop
|
||||||
|
str_to_i cmd.userinput_buf
|
||||||
|
mov byte [cmd.cmd_loadmem_loadoffset], al
|
||||||
|
|
||||||
|
mov ah, 02h
|
||||||
|
mov al, byte [cmd.cmd_loadmem_sectors]
|
||||||
|
mov dl, byte [cmd.cmd_loadmem_drive]
|
||||||
|
mov ch, byte [cmd.cmd_loadmem_cylinder]
|
||||||
|
mov dh, byte [cmd.cmd_loadmem_head]
|
||||||
|
mov cl, byte [cmd.cmd_loadmem_loadoffset]
|
||||||
|
mov bx, PROGRAM_ADDRESS
|
||||||
|
int 13h
|
||||||
|
jnc command.rfd_ok
|
||||||
|
jc command.loadmem_err
|
||||||
|
|
||||||
|
command.rfd_ok:
|
||||||
|
mov al, byte [PROGRAM_ADDRESS]
|
||||||
|
cmp al, 0
|
||||||
|
je command.rfd_noprog
|
||||||
|
call PROGRAM_ADDRESS
|
||||||
|
jmp mainloop
|
||||||
|
command.rfd_noprog:
|
||||||
|
print cmd.cmd_rfd_locateerr, ln
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
command.dir:
|
||||||
|
|
||||||
|
call read_table
|
||||||
|
|
||||||
|
mov si, filetable_ff
|
||||||
|
mov cx, 64
|
||||||
|
add si, 4
|
||||||
|
command.dir.lp:
|
||||||
|
mov al, [si]
|
||||||
|
cmp al, 0
|
||||||
|
jne command.dir.printstring
|
||||||
|
; push si
|
||||||
|
; call print_string
|
||||||
|
; print space
|
||||||
|
; pop si
|
||||||
|
command.dir.continue:
|
||||||
|
|
||||||
|
dec cx
|
||||||
|
cmp cx, 0
|
||||||
|
je command.dirret
|
||||||
|
|
||||||
|
cmp si, 8380h
|
||||||
|
ja command.dirret
|
||||||
|
|
||||||
|
mov bx, 12
|
||||||
|
xor ax, ax
|
||||||
|
sub bx, ax
|
||||||
|
xchg ax, bx
|
||||||
|
add si, ax
|
||||||
|
add si, 4
|
||||||
|
; mov al, [si]
|
||||||
|
; cmp al, 0
|
||||||
|
; je command.dirret
|
||||||
|
|
||||||
|
jmp command.dir.lp
|
||||||
|
command.dirret:
|
||||||
|
print ln
|
||||||
|
jmp mainloop
|
||||||
|
command.dir.printstring:
|
||||||
|
push si
|
||||||
|
call print_string
|
||||||
|
print space
|
||||||
|
pop si
|
||||||
|
jmp command.dir.continue
|
||||||
|
|
||||||
|
command.run:
|
||||||
|
mov bx, cmd.userinput_com
|
||||||
|
call find_file
|
||||||
|
|
||||||
|
mov bx, PROGRAM_ADDRESS
|
||||||
|
call load_file
|
||||||
|
jc command.loadmem_err
|
||||||
|
|
||||||
|
cmp byte [PROGRAM_ADDRESS], 0x7A
|
||||||
|
je command.run.run
|
||||||
|
|
||||||
|
print cmd.cmd_run_nonex, ln
|
||||||
|
|
||||||
|
jmp mainloop
|
||||||
|
command.run.run:
|
||||||
|
call PROGRAM_ADDRESS+1
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
command.rm:
|
||||||
|
len cmd.userinput_arg1
|
||||||
|
cmp ax, 0
|
||||||
|
je command.rm.usage
|
||||||
|
|
||||||
|
mov bx, cmd.userinput_arg1
|
||||||
|
|
||||||
|
call remove_file
|
||||||
|
|
||||||
|
jc command.rm.notfound
|
||||||
|
|
||||||
|
call write_table
|
||||||
|
|
||||||
|
jmp mainloop
|
||||||
|
command.rm.notfound:
|
||||||
|
print cmd.file_notfound_err, ln
|
||||||
|
jmp mainloop
|
||||||
|
command.rm.usage:
|
||||||
|
print cmd.cmd_rm_usage, ln
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
; command.addlink:
|
||||||
|
; len cmd.userinput_arg3
|
||||||
|
; cmp ax, 0
|
||||||
|
; je command.addlink.usage
|
||||||
|
; print cmd.cmd_addlink_desc
|
||||||
|
; input cmd.userinput_buf, SHNUM_BUFFER_SIZE
|
||||||
|
; str_to_i cmd.userinput_buf
|
||||||
|
; mov [cmd.cmd_addlink_size], al
|
||||||
|
; print cmd.cmd_addlink_desc1
|
||||||
|
; input cmd.userinput_buf, FILENAME_BUFFER_SIZE
|
||||||
|
; jmp mainloop
|
||||||
|
; command.addlink.usage:
|
||||||
|
; print usage, ln
|
||||||
|
; jmp mainloop
|
||||||
|
|
||||||
|
command.reboot:
|
||||||
|
jmp 0xFFFF:0
|
|
@ -0,0 +1,71 @@
|
||||||
|
macro print [pointer]
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
call print_string
|
||||||
|
}
|
||||||
|
|
||||||
|
macro printh [num]
|
||||||
|
{
|
||||||
|
mov ax, num
|
||||||
|
call print_hex
|
||||||
|
}
|
||||||
|
|
||||||
|
macro printi [num]
|
||||||
|
{
|
||||||
|
mov ax, num
|
||||||
|
call its
|
||||||
|
}
|
||||||
|
|
||||||
|
macro cmp_strs ptr1, ptr2
|
||||||
|
{
|
||||||
|
mov si, ptr1
|
||||||
|
mov bx, ptr2
|
||||||
|
call compare_strings
|
||||||
|
}
|
||||||
|
|
||||||
|
macro cp_str ptr1, ptr2
|
||||||
|
{
|
||||||
|
mov si, ptr1
|
||||||
|
mov bx, ptr2
|
||||||
|
call copy_string
|
||||||
|
}
|
||||||
|
|
||||||
|
macro input pointer, length
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
mov cx, length
|
||||||
|
call input_string
|
||||||
|
}
|
||||||
|
|
||||||
|
macro len pointer
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
call calculate_string_len
|
||||||
|
}
|
||||||
|
|
||||||
|
macro muln num1, num2
|
||||||
|
{
|
||||||
|
mov ax, num1
|
||||||
|
mov bx, num2
|
||||||
|
mul bx
|
||||||
|
}
|
||||||
|
|
||||||
|
macro str_to_i pointer
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
call string_to_int
|
||||||
|
}
|
||||||
|
|
||||||
|
macro i_to_str pointer, number
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
mov ax, number
|
||||||
|
call int_to_string
|
||||||
|
}
|
||||||
|
|
||||||
|
macro reset_buf pointer, length
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
mov cx, length
|
||||||
|
call reset_buffer
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
; USE16
|
||||||
|
; format binary as 'bin'
|
||||||
|
|
||||||
|
; include "include.asm"
|
||||||
|
|
||||||
|
; INNUM_BUFFER_SIZE equ 5
|
||||||
|
; ACTION_BUFFER_SIZE equ 3
|
||||||
|
; RESULT_BUFFER_SIZE equ 7
|
||||||
|
; USERINPUT_BUFFER_SIZE equ 10
|
||||||
|
|
||||||
|
; include 'programmacros.asm'
|
||||||
|
|
||||||
|
; org 1000h
|
||||||
|
|
||||||
|
; db 0x7A
|
||||||
|
|
||||||
|
; FUNCTABLE EQU 7E00h
|
||||||
|
; clear EQU word [7E00h]
|
||||||
|
; detect_video EQU word [7E02h]
|
||||||
|
; print_string EQU word [7E04h]
|
||||||
|
; print_symbol EQU word [7E06h]
|
||||||
|
; input_string EQU word [7E08h]
|
||||||
|
; compare_strings EQU word [7E0Ah]
|
||||||
|
; copy_string EQU word [7E0Ch]
|
||||||
|
; calculate_string_len EQU word [7E0Eh]
|
||||||
|
; os_print_digit EQU word [7E10h]
|
||||||
|
; os_print_1hex EQU word [7E12h]
|
||||||
|
; os_print_2hex EQU word [7E14h]
|
||||||
|
; print_hex EQU word [7E16h]
|
||||||
|
; print_registers EQU word [7E18h]
|
||||||
|
; string_to_int EQU word [7E1Ah]
|
||||||
|
; int_to_string EQU word [7E1Ch]
|
||||||
|
; dbg_halt_cpu EQU word [7E1Eh]
|
||||||
|
; halt_cpu EQU word [7E20h]
|
||||||
|
|
||||||
|
|
||||||
|
; print calcgreetings
|
||||||
|
; pusha
|
||||||
|
; calcloop:
|
||||||
|
; print firstn
|
||||||
|
; input first_num_buf, INNUM_BUFFER_SIZE
|
||||||
|
; cmp al, 03h
|
||||||
|
; je calcret
|
||||||
|
|
||||||
|
; print secondn
|
||||||
|
; input second_num_buf, INNUM_BUFFER_SIZE
|
||||||
|
; cmp al, 03h
|
||||||
|
; je calcret
|
||||||
|
|
||||||
|
; str_to_i first_num_buf
|
||||||
|
; mov word [first_num], ax
|
||||||
|
|
||||||
|
; str_to_i second_num_buf
|
||||||
|
; mov word [second_num], ax
|
||||||
|
|
||||||
|
; print actionn
|
||||||
|
; input action_buf, ACTION_BUFFER_SIZE
|
||||||
|
; cmp_strs action_buf, action_add
|
||||||
|
; jnc do_add
|
||||||
|
|
||||||
|
; cmp_strs action_buf, action_sub
|
||||||
|
; jnc go_sub
|
||||||
|
|
||||||
|
; cmp_strs action_buf, action_and
|
||||||
|
; jnc go_and
|
||||||
|
|
||||||
|
; cmp_strs action_buf, action_or
|
||||||
|
; jnc go_or
|
||||||
|
|
||||||
|
; cmp_strs action_buf, action_xor
|
||||||
|
; jnc go_xor
|
||||||
|
|
||||||
|
; print inc_act, ln
|
||||||
|
|
||||||
|
; jmp calcloop
|
||||||
|
; calcret:
|
||||||
|
; popa
|
||||||
|
; ret
|
||||||
|
|
||||||
|
; do_add:
|
||||||
|
; mov ax, word [first_num]
|
||||||
|
; mov bx, word [second_num]
|
||||||
|
; add ax, bx
|
||||||
|
|
||||||
|
; mov si, result_buf
|
||||||
|
; call int_to_string
|
||||||
|
; jmp print_res
|
||||||
|
|
||||||
|
; go_sub:
|
||||||
|
; mov ax, word [first_num]
|
||||||
|
; mov bx, word [second_num]
|
||||||
|
; sub ax, bx
|
||||||
|
|
||||||
|
; mov si, result_buf
|
||||||
|
; call int_to_string
|
||||||
|
; jmp print_res
|
||||||
|
|
||||||
|
; go_and:
|
||||||
|
; mov ax, word [first_num]
|
||||||
|
; mov bx, word [second_num]
|
||||||
|
; and ax, bx
|
||||||
|
|
||||||
|
; mov si, result_buf
|
||||||
|
; call int_to_string
|
||||||
|
; jmp print_res
|
||||||
|
|
||||||
|
; go_or:
|
||||||
|
; mov ax, word [first_num]
|
||||||
|
; mov bx, word [second_num]
|
||||||
|
; or ax, bx
|
||||||
|
|
||||||
|
; mov si, result_buf
|
||||||
|
; call int_to_string
|
||||||
|
; jmp print_res
|
||||||
|
|
||||||
|
; go_xor:
|
||||||
|
; mov ax, word [first_num]
|
||||||
|
; mov bx, word [second_num]
|
||||||
|
; xor ax, bx
|
||||||
|
|
||||||
|
; mov si, result_buf
|
||||||
|
; call int_to_string
|
||||||
|
; jmp print_res
|
||||||
|
|
||||||
|
; print_res:
|
||||||
|
; print resultn, result_buf, ln
|
||||||
|
; jmp calcloop
|
||||||
|
|
||||||
|
; Sdata:
|
||||||
|
; calcgreetings db "Welcome to the calculator", 0Dh, 0Ah, 0
|
||||||
|
; goodbye db "Uhadi!", 0
|
||||||
|
|
||||||
|
; firstn db "Enter first number:", 0
|
||||||
|
; secondn db "Enter second number:", 0
|
||||||
|
; actionn db "Enter action:", 0
|
||||||
|
; inc_act db "Incrorrect action!", 0
|
||||||
|
; resultn db "Result - ", 0
|
||||||
|
|
||||||
|
; action_add db "add", 0
|
||||||
|
; action_sub db "sub", 0
|
||||||
|
; action_and db "and", 0
|
||||||
|
; action_or db "or" , 0
|
||||||
|
; action_xor db "xor", 0
|
||||||
|
|
||||||
|
; zx db "0x", 0
|
||||||
|
; ln db 0Dh, 0Ah, 0
|
||||||
|
|
||||||
|
; first_num_buf:
|
||||||
|
; times INNUM_BUFFER_SIZE db 0
|
||||||
|
; db 0
|
||||||
|
; first_num dw 0
|
||||||
|
|
||||||
|
; second_num_buf:
|
||||||
|
; times INNUM_BUFFER_SIZE db 0
|
||||||
|
; db 0
|
||||||
|
; second_num dw 0
|
||||||
|
|
||||||
|
; action_buf:
|
||||||
|
; times ACTION_BUFFER_SIZE db 0
|
||||||
|
; db 0
|
||||||
|
|
||||||
|
; result_buf:
|
||||||
|
; times RESULT_BUFFER_SIZE db 0
|
||||||
|
; db 0
|
||||||
|
|
||||||
|
include 'include.asm'
|
||||||
|
|
||||||
|
program:
|
||||||
|
print greetings, ln
|
||||||
|
.loop:
|
||||||
|
print prefix_1
|
||||||
|
input innum_buffer, INNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je .end
|
||||||
|
str_to_i innum_buffer
|
||||||
|
push ax
|
||||||
|
|
||||||
|
print prefix_2
|
||||||
|
input innum_buffer, INNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je .end
|
||||||
|
str_to_i innum_buffer
|
||||||
|
push ax
|
||||||
|
|
||||||
|
print prefix_act
|
||||||
|
input innum_buffer, INNUM_BUFFER_SIZE
|
||||||
|
cmp al, 03h
|
||||||
|
je .end
|
||||||
|
|
||||||
|
cmp_strs innum_buffer, act_add
|
||||||
|
jnc do_add
|
||||||
|
cmp_strs innum_buffer, act_sub
|
||||||
|
jnc do_sub
|
||||||
|
cmp_strs innum_buffer, act_div
|
||||||
|
jnc do_div
|
||||||
|
cmp_strs innum_buffer, act_mul
|
||||||
|
jnc do_mul
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
print inc_act, ln
|
||||||
|
|
||||||
|
jmp .loop
|
||||||
|
.end:
|
||||||
|
ret
|
||||||
|
|
||||||
|
do_add:
|
||||||
|
jmp print_result
|
||||||
|
do_sub:
|
||||||
|
jmp print_result
|
||||||
|
do_div:
|
||||||
|
jmp print_result
|
||||||
|
do_mul:
|
||||||
|
jmp print_result
|
||||||
|
print_result:
|
||||||
|
jmp program.loop
|
||||||
|
|
||||||
|
greetings db "Welcome to the calculator. List of actions - +-/*", 0
|
||||||
|
prefix_1 db "First number>", 0
|
||||||
|
prefix_2 db "Second number>", 0
|
||||||
|
prefix_act db "Action>", 0
|
||||||
|
inc_act db "Incorrect action!", 0
|
||||||
|
ln db 0Dh, 0Ah, 0
|
||||||
|
act_add db "+", 0
|
||||||
|
act_sub db "-", 0
|
||||||
|
act_div db "/", 0
|
||||||
|
act_mul db "*", 0
|
||||||
|
|
||||||
|
innum_buffer:
|
||||||
|
times INNUM_BUFFER_SIZE db 0
|
||||||
|
db 0
|
|
@ -0,0 +1,58 @@
|
||||||
|
USE16
|
||||||
|
include 'programmacros.asm'
|
||||||
|
format binary as 'bin'
|
||||||
|
|
||||||
|
FUNCTABLE EQU 7E00h
|
||||||
|
clear EQU word [7E00h]
|
||||||
|
detect_video EQU word [7E02h]
|
||||||
|
print_string EQU word [7E04h]
|
||||||
|
print_symbol EQU word [7E06h]
|
||||||
|
input_string EQU word [7E08h]
|
||||||
|
compare_strings EQU word [7E0Ah]
|
||||||
|
copy_string EQU word [7E0Ch]
|
||||||
|
calculate_string_len EQU word [7E0Eh]
|
||||||
|
os_print_digit EQU word [7E10h]
|
||||||
|
os_print_1hex EQU word [7E12h]
|
||||||
|
os_print_2hex EQU word [7E14h]
|
||||||
|
print_hex EQU word [7E16h]
|
||||||
|
print_registers EQU word [7E18h]
|
||||||
|
string_to_int EQU word [7E1Ah]
|
||||||
|
int_to_string EQU word [7E1Ch]
|
||||||
|
dbg_halt_cpu EQU word [7E1Eh]
|
||||||
|
halt_cpu EQU word [7E20h]
|
||||||
|
its EQU word [7E22h]
|
||||||
|
find_file EQU word [7E24h]
|
||||||
|
remove_file EQU word [7E26h]
|
||||||
|
write_table EQU word [7E28h]
|
||||||
|
arg1 EQU word [7E2Ah]
|
||||||
|
arg2 EQU word [7E2Ch]
|
||||||
|
arg3 EQU word [7E2Eh]
|
||||||
|
reset_buffer EQU word [7E30h]
|
||||||
|
append_file EQU word [7E32h]
|
||||||
|
rename_file EQU word [7E34h]
|
||||||
|
load_file EQU word [7E36h]
|
||||||
|
save_file EQU word [7E38h]
|
||||||
|
wait_key EQU word [7E3Ah]
|
||||||
|
copy_memory EQU word [7E3Ch]
|
||||||
|
|
||||||
|
org 1000h
|
||||||
|
|
||||||
|
start:
|
||||||
|
mainloop:
|
||||||
|
print userinput_prefix
|
||||||
|
input userinput_buf, 30
|
||||||
|
cmp al, 03h
|
||||||
|
je progret
|
||||||
|
|
||||||
|
cmp_strs userinput_buf, loadsector
|
||||||
|
je loadsector_com
|
||||||
|
|
||||||
|
jmp mainloop
|
||||||
|
progret:
|
||||||
|
ret
|
||||||
|
loadsector_com:
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
userinput_prefix db '>', 0
|
||||||
|
loadsector db "load", 0
|
||||||
|
userinput_buf: times 31 db 0
|
|
@ -0,0 +1,6 @@
|
||||||
|
include 'include.asm'
|
||||||
|
|
||||||
|
print hw
|
||||||
|
ret
|
||||||
|
|
||||||
|
hw db "Hello, world", 0Dh, 0Ah, 0
|
|
@ -0,0 +1,52 @@
|
||||||
|
USE16
|
||||||
|
format binary as 'bin'
|
||||||
|
|
||||||
|
include 'programmacros.asm'
|
||||||
|
|
||||||
|
INNUM_BUFFER_SIZE equ 5
|
||||||
|
SHNUM_BUFFER_SIZE equ 3
|
||||||
|
ACTION_BUFFER_SIZE equ 3
|
||||||
|
RESULT_BUFFER_SIZE equ 7
|
||||||
|
USERINPUT_BUFFER_SIZE equ 64
|
||||||
|
ARGUMENT_BUFFER_SIZE equ 16
|
||||||
|
FILENAME_BUFFER_SIZE equ 11
|
||||||
|
|
||||||
|
FUNCTABLE EQU 7E00h
|
||||||
|
clear EQU word [7E00h]
|
||||||
|
detect_video EQU word [7E02h]
|
||||||
|
print_string EQU word [7E04h]
|
||||||
|
print_symbol EQU word [7E06h]
|
||||||
|
input_string EQU word [7E08h]
|
||||||
|
compare_strings EQU word [7E0Ah]
|
||||||
|
copy_string EQU word [7E0Ch]
|
||||||
|
calculate_string_len EQU word [7E0Eh]
|
||||||
|
os_print_digit EQU word [7E10h]
|
||||||
|
os_print_1hex EQU word [7E12h]
|
||||||
|
os_print_2hex EQU word [7E14h]
|
||||||
|
print_hex EQU word [7E16h]
|
||||||
|
print_registers EQU word [7E18h]
|
||||||
|
string_to_int EQU word [7E1Ah]
|
||||||
|
int_to_string EQU word [7E1Ch]
|
||||||
|
dbg_halt_cpu EQU word [7E1Eh]
|
||||||
|
halt_cpu EQU word [7E20h]
|
||||||
|
its EQU word [7E22h]
|
||||||
|
find_file EQU word [7E24h]
|
||||||
|
remove_file EQU word [7E26h]
|
||||||
|
write_table EQU word [7E28h]
|
||||||
|
arg1 EQU word [7E2Ah]
|
||||||
|
arg2 EQU word [7E2Ch]
|
||||||
|
arg3 EQU word [7E2Eh]
|
||||||
|
reset_buffer EQU word [7E30h]
|
||||||
|
append_file EQU word [7E32h]
|
||||||
|
rename_file EQU word [7E34h]
|
||||||
|
load_file EQU word [7E36h]
|
||||||
|
save_file EQU word [7E38h]
|
||||||
|
wait_key EQU word [7E3Ah]
|
||||||
|
copy_memory EQU word [7E3Ch]
|
||||||
|
get_cursor_pos EQU word [7E3Eh]
|
||||||
|
set_cursor_pos EQU word [7E40h]
|
||||||
|
read_table EQU word [7E42h]
|
||||||
|
|
||||||
|
org 1000h
|
||||||
|
|
||||||
|
db 0x7A
|
|
@ -0,0 +1,44 @@
|
||||||
|
include 'programmacros.asm'
|
||||||
|
|
||||||
|
FUNCTABLE EQU 7E00h
|
||||||
|
clear EQU word [7E00h]
|
||||||
|
detect_video EQU word [7E02h]
|
||||||
|
print_string EQU word [7E04h]
|
||||||
|
print_symbol EQU word [7E06h]
|
||||||
|
input_string EQU word [7E08h]
|
||||||
|
compare_strings EQU word [7E0Ah]
|
||||||
|
copy_string EQU word [7E0Ch]
|
||||||
|
calculate_string_len EQU word [7E0Eh]
|
||||||
|
os_print_digit EQU word [7E10h]
|
||||||
|
os_print_1hex EQU word [7E12h]
|
||||||
|
os_print_2hex EQU word [7E14h]
|
||||||
|
print_hex EQU word [7E16h]
|
||||||
|
print_registers EQU word [7E18h]
|
||||||
|
string_to_int EQU word [7E1Ah]
|
||||||
|
int_to_string EQU word [7E1Ch]
|
||||||
|
dbg_halt_cpu EQU word [7E1Eh]
|
||||||
|
halt_cpu EQU word [7E20h]
|
||||||
|
its EQU word [7E22h]
|
||||||
|
find_file EQU word [7E24h]
|
||||||
|
remove_file EQU word [7E26h]
|
||||||
|
write_table EQU word [7E28h]
|
||||||
|
arg1 EQU word [7E2Ah]
|
||||||
|
arg2 EQU word [7E2Ch]
|
||||||
|
arg3 EQU word [7E2Eh]
|
||||||
|
reset_buffer EQU word [7E30h]
|
||||||
|
append_file EQU word [7E32h]
|
||||||
|
rename_file EQU word [7E34h]
|
||||||
|
|
||||||
|
org 1000h
|
||||||
|
|
||||||
|
start:
|
||||||
|
print greetings, ln
|
||||||
|
ret
|
||||||
|
|
||||||
|
2d_input
|
||||||
|
|
||||||
|
|
||||||
|
greetings db "Welcome to the notepad!", 0
|
||||||
|
zx db "0x", 0
|
||||||
|
ln db 0Dh, 0Ah, 0
|
||||||
|
space db " ", 0
|
|
@ -0,0 +1,71 @@
|
||||||
|
macro print [pointer]
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
call print_string
|
||||||
|
}
|
||||||
|
|
||||||
|
macro printh [num]
|
||||||
|
{
|
||||||
|
mov ax, num
|
||||||
|
call print_hex
|
||||||
|
}
|
||||||
|
|
||||||
|
macro printi [num]
|
||||||
|
{
|
||||||
|
mov ax, num
|
||||||
|
call its
|
||||||
|
}
|
||||||
|
|
||||||
|
macro cmp_strs ptr1, ptr2
|
||||||
|
{
|
||||||
|
mov si, ptr1
|
||||||
|
mov bx, ptr2
|
||||||
|
call compare_strings
|
||||||
|
}
|
||||||
|
|
||||||
|
macro cp_str ptr1, ptr2
|
||||||
|
{
|
||||||
|
mov si, ptr1
|
||||||
|
mov bx, ptr2
|
||||||
|
call copy_string
|
||||||
|
}
|
||||||
|
|
||||||
|
macro input pointer, length
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
mov cx, length
|
||||||
|
call input_string
|
||||||
|
}
|
||||||
|
|
||||||
|
macro len pointer
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
call calculate_string_len
|
||||||
|
}
|
||||||
|
|
||||||
|
macro muln num1, num2
|
||||||
|
{
|
||||||
|
mov ax, num1
|
||||||
|
mov bx, num2
|
||||||
|
mul bx
|
||||||
|
}
|
||||||
|
|
||||||
|
macro str_to_i pointer
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
call string_to_int
|
||||||
|
}
|
||||||
|
|
||||||
|
macro i_to_str pointer, number
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
mov ax, number
|
||||||
|
call int_to_string
|
||||||
|
}
|
||||||
|
|
||||||
|
macro reset_buf pointer, length
|
||||||
|
{
|
||||||
|
mov si, pointer
|
||||||
|
mov cx, length
|
||||||
|
call reset_buffer
|
||||||
|
}
|
|
@ -0,0 +1,274 @@
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; ;;;;;; ;;;;;; ;;
|
||||||
|
;; ;; ;; ;; ;;
|
||||||
|
;; ;; ;; ;;;;;; ;;; ;; ;; ;; ;; ;;; ;; ;; ;;;;;; ;;
|
||||||
|
;; ;;;;;; ;; ;; ;; ;; ;;;;;;; ;;; ;; ;; ;; ;; ;; ;; ;;
|
||||||
|
;; ;; ;; ;;;;; ;; ;; ;; ;; ;; ; ;; ;; ;; ;;;; ;;;;;; ;;
|
||||||
|
;; ;; ;; ;; ;;;;;;; ;; ;; ;; ;;; ;;;;;;; ;; ;; ;; ;;
|
||||||
|
;; ;; ;; ;;;;;; ;; ;; ;;;;;; ;;;;;; ;; ;; ;; ;; ;; ;; ;;;;;; ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; Snake like game writen in x86 real mode assembly. ;;
|
||||||
|
;; Copyright (C) 2014 Piotr Majkrzak <petrol.91@gmail.com> ;;
|
||||||
|
;; ;;
|
||||||
|
;; This program is free software: you can redistribute it and/or modify ;;
|
||||||
|
;; it under the terms of the GNU General Public License as published by ;;
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or ;;
|
||||||
|
;; (at your option) any later version. ;;
|
||||||
|
;; ;;
|
||||||
|
;; This program is distributed in the hope that it will be useful, ;;
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;
|
||||||
|
;; GNU General Public License for more details. ;;
|
||||||
|
;; ;;
|
||||||
|
;; You should have received a copy of the GNU General Public License ;;
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>. ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; ;;
|
||||||
|
;; About ;;
|
||||||
|
;;------- ;;
|
||||||
|
;; ;;
|
||||||
|
;; This game is written in Intel's x86 real mode assembly. It is designed ;;
|
||||||
|
;; to fit in the boot sector, so it must have at most 510 bytes. Therefore, ;;
|
||||||
|
;; it has very limited functionalities and spaghetti code. You are able to ;;
|
||||||
|
;; change snake's head direction, eat fruits and restart the game. ;;
|
||||||
|
;; ;;
|
||||||
|
;; ;;
|
||||||
|
;; Assembly ;;
|
||||||
|
;;---------- ;;
|
||||||
|
;; ;;
|
||||||
|
;; To build this code you need to have NASM installed, you can get it from ;;
|
||||||
|
;; this website: (http://www.nasm.us/). ;;
|
||||||
|
;; Execute following command: ;;
|
||||||
|
;; ;;
|
||||||
|
;; nasm -fbin snake.asm -o snake.bin ;;
|
||||||
|
;; ;;
|
||||||
|
;; ;;
|
||||||
|
;; Launch ;;
|
||||||
|
;;-------- ;;
|
||||||
|
;; ;;
|
||||||
|
;; Now you have `snake.bin` file, which can be installed or loaded into ;;
|
||||||
|
;; virtual machine like QEMU, which you can get from (www.qemu.org/). ;;
|
||||||
|
;; ;;
|
||||||
|
;; qemu-system-i386 snake.bin ;;
|
||||||
|
;; ;;
|
||||||
|
;; ;;
|
||||||
|
;; Gameplay ;;
|
||||||
|
;;---------- ;;
|
||||||
|
;; ;;
|
||||||
|
;; When the game will be launched, you will see huge green rectangle in the ;;
|
||||||
|
;; middle of the screen. Snake is hidden now in top left corner. To move it ;;
|
||||||
|
;; you should set its head direction, using arrow keys. If you are stuck or ;;
|
||||||
|
;; you just want to restart the game, you should press space bar. ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
[org 0x1000]
|
||||||
|
|
||||||
|
%DEFINE EMPTY 0b0000_0000
|
||||||
|
%DEFINE SNAKE 0b0000_0001
|
||||||
|
%DEFINE FRUIT 0b0000_0010
|
||||||
|
%DEFINE EATEN 0b0000_0100
|
||||||
|
%DEFINE WRECK 0b0000_1000
|
||||||
|
%DEFINE DIRUP 0b0001_0000
|
||||||
|
%DEFINE DIRDO 0b0010_0000
|
||||||
|
%DEFINE DIRLE 0b0100_0000
|
||||||
|
%DEFINE DIRRI 0b1000_0000
|
||||||
|
%define map(i) byte [es:i]
|
||||||
|
%define head word [es:1024]
|
||||||
|
%define tail word [es:1026]
|
||||||
|
%define fpos word [es:1028]
|
||||||
|
%define ftim word [es:1030]
|
||||||
|
%define rand word [es:1032]
|
||||||
|
|
||||||
|
db 0x7A
|
||||||
|
|
||||||
|
init:
|
||||||
|
.random:
|
||||||
|
mov ah, 0
|
||||||
|
int 0x1A
|
||||||
|
mov rand, dx
|
||||||
|
.display:
|
||||||
|
mov ah, 0x00
|
||||||
|
mov al, 0x13
|
||||||
|
int 0x10
|
||||||
|
.interrupt:
|
||||||
|
mov [fs:0x08*4], word timer
|
||||||
|
mov [fs:0x08*4+2], ds
|
||||||
|
mov [fs:0x09*4], word keyboard
|
||||||
|
mov [fs:0x09*4+2], ds
|
||||||
|
|
||||||
|
|
||||||
|
main:
|
||||||
|
hlt
|
||||||
|
jmp main
|
||||||
|
|
||||||
|
|
||||||
|
;; () -> (ax); ax,cx,dx
|
||||||
|
random:
|
||||||
|
mov ax, rand
|
||||||
|
mov dx, 7993
|
||||||
|
mov cx, 9781
|
||||||
|
mul dx
|
||||||
|
add ax, cx
|
||||||
|
mov rand, ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
;; (si) -> (di,ah:al) ; cx,dx
|
||||||
|
movement:
|
||||||
|
mov cl, map(si)
|
||||||
|
mov ax, si
|
||||||
|
mov dl, 32
|
||||||
|
div dl
|
||||||
|
test cl, DIRUP
|
||||||
|
jz $+4
|
||||||
|
dec al
|
||||||
|
test cl, DIRDO
|
||||||
|
jz $+4
|
||||||
|
inc al
|
||||||
|
test cl, DIRLE
|
||||||
|
jz $+4
|
||||||
|
dec ah
|
||||||
|
test cl, DIRRI
|
||||||
|
jz $+4
|
||||||
|
inc ah
|
||||||
|
and al, 31
|
||||||
|
and ah, 31
|
||||||
|
movzx di, al
|
||||||
|
rol di, 5
|
||||||
|
movzx cx, ah
|
||||||
|
add di,cx
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
keyboard:
|
||||||
|
in al, 0x60
|
||||||
|
mov bx, head
|
||||||
|
mov ah, map(bx)
|
||||||
|
cmp al, 0x39
|
||||||
|
jne $+12
|
||||||
|
mov cx, 1032
|
||||||
|
mov al, 0
|
||||||
|
mov di, 0
|
||||||
|
rep stosb
|
||||||
|
and ah, 0x0F
|
||||||
|
cmp al, 0x48
|
||||||
|
jne $+5
|
||||||
|
or ah, DIRUP
|
||||||
|
cmp al, 0x50
|
||||||
|
jne $+5
|
||||||
|
or ah, DIRDO
|
||||||
|
cmp al, 0x4b
|
||||||
|
jne $+5
|
||||||
|
or ah, DIRLE
|
||||||
|
cmp al, 0x4d
|
||||||
|
jne $+5
|
||||||
|
or ah, DIRRI
|
||||||
|
test ah, 0xF0
|
||||||
|
jz $+4
|
||||||
|
mov map(bx), ah
|
||||||
|
mov al, 0x61
|
||||||
|
out 0x20, al
|
||||||
|
iret
|
||||||
|
|
||||||
|
timer:
|
||||||
|
.tick_rtc:
|
||||||
|
int 0x70
|
||||||
|
.move_head:
|
||||||
|
mov si, head
|
||||||
|
call movement
|
||||||
|
mov ah, map(di)
|
||||||
|
mov al, map(si)
|
||||||
|
test al, WRECK
|
||||||
|
jz $+3
|
||||||
|
iret
|
||||||
|
test ah, SNAKE|EATEN
|
||||||
|
jz $+7
|
||||||
|
mov map(si), WRECK
|
||||||
|
iret
|
||||||
|
test ah, FRUIT
|
||||||
|
jz $+20
|
||||||
|
mov ftim, 0
|
||||||
|
mov fpos, -1
|
||||||
|
mov bl, EATEN
|
||||||
|
jmp $+4
|
||||||
|
mov bl, SNAKE
|
||||||
|
and al, 0xF0
|
||||||
|
or bl, al
|
||||||
|
mov map(di), bl
|
||||||
|
mov head, di
|
||||||
|
.move_tail:
|
||||||
|
mov si, tail
|
||||||
|
call movement
|
||||||
|
mov al, map(si)
|
||||||
|
test al, SNAKE
|
||||||
|
jz $+11
|
||||||
|
mov map(si), EMPTY
|
||||||
|
mov tail, di
|
||||||
|
jnz $+9
|
||||||
|
and al, 0xF0
|
||||||
|
or al, SNAKE
|
||||||
|
mov map(si), al
|
||||||
|
.move_fruit:
|
||||||
|
cmp ftim, 0
|
||||||
|
jne $+42
|
||||||
|
mov bx, fpos
|
||||||
|
mov map(bx), EMPTY
|
||||||
|
call random
|
||||||
|
mov bx, ax
|
||||||
|
and bx, 1023
|
||||||
|
cmp map(bx), EMPTY
|
||||||
|
jne $-13
|
||||||
|
mov map(bx), FRUIT
|
||||||
|
mov fpos, bx
|
||||||
|
mov ftim, 64
|
||||||
|
dec ftim
|
||||||
|
.redraw:
|
||||||
|
mov cx, 0
|
||||||
|
mov ax, cx
|
||||||
|
mov dl, 32
|
||||||
|
div dl
|
||||||
|
mov bx, ax
|
||||||
|
movzx ax, bl
|
||||||
|
add ax, 9
|
||||||
|
mov dx, 320
|
||||||
|
mul dx
|
||||||
|
movzx dx, bh
|
||||||
|
add ax, dx
|
||||||
|
add ax, 24
|
||||||
|
mov dx, 4
|
||||||
|
mul dx
|
||||||
|
mov di, cx
|
||||||
|
mov dl, map(di)
|
||||||
|
and dl, 0x0F
|
||||||
|
cmp dl, EMPTY
|
||||||
|
jne $+8
|
||||||
|
mov ebx, 0x02020202
|
||||||
|
cmp dl, SNAKE
|
||||||
|
jne $+8
|
||||||
|
mov ebx, 0x01010101
|
||||||
|
cmp dl, FRUIT
|
||||||
|
jne $+8
|
||||||
|
mov ebx, 0x04040404
|
||||||
|
cmp dl, EATEN
|
||||||
|
jne $+8
|
||||||
|
mov ebx, 0x05050505
|
||||||
|
mov di, ax
|
||||||
|
mov [gs:di],ebx
|
||||||
|
add di, 320
|
||||||
|
mov [gs:di],ebx
|
||||||
|
add di, 320
|
||||||
|
mov [gs:di],ebx
|
||||||
|
add di, 320
|
||||||
|
mov [gs:di],ebx
|
||||||
|
inc cx
|
||||||
|
cmp cx, 1024
|
||||||
|
jne .redraw+3
|
||||||
|
iret
|
||||||
|
|
||||||
|
times 510-($-$$) db 0
|
||||||
|
dw 0AA55h
|
|
@ -0,0 +1,72 @@
|
||||||
|
include 'include.asm'
|
||||||
|
|
||||||
|
start:
|
||||||
|
len arg1
|
||||||
|
cmp ax, 0
|
||||||
|
je progret.usage
|
||||||
|
mov bx, arg1
|
||||||
|
call find_file
|
||||||
|
jc progret.fnf
|
||||||
|
mov word [file_FS_offset], si
|
||||||
|
mov si, file_offset
|
||||||
|
jmp view_text.prt
|
||||||
|
progret.usage:
|
||||||
|
print usage, ln
|
||||||
|
jmp progret
|
||||||
|
progret.fnf:
|
||||||
|
print fnf, ln
|
||||||
|
jmp progret
|
||||||
|
progret:
|
||||||
|
ret
|
||||||
|
|
||||||
|
view_text.prt:
|
||||||
|
mov word [xpos], 0
|
||||||
|
jmp print_symb
|
||||||
|
view_text.prt.continue:
|
||||||
|
inc si
|
||||||
|
jmp view_text.prt
|
||||||
|
view_text.waiting:
|
||||||
|
call wait_key
|
||||||
|
cmp al, 'q'
|
||||||
|
je progret
|
||||||
|
jmp view_text.prt
|
||||||
|
|
||||||
|
print_symb:
|
||||||
|
mov dl, [xpos]
|
||||||
|
mov dh, [ypos]
|
||||||
|
cmp dl, 0
|
||||||
|
je print_symb.mb_end
|
||||||
|
print_symb.continue:
|
||||||
|
mov al, [si]
|
||||||
|
call print_symbol
|
||||||
|
pusha
|
||||||
|
cmp [xpos], 24
|
||||||
|
je print_symb.mov_ln
|
||||||
|
mov al, [xpos]
|
||||||
|
inc al
|
||||||
|
mov [xpos], al
|
||||||
|
print_symb.continue2:
|
||||||
|
popa
|
||||||
|
printh word [xpos]
|
||||||
|
jmp view_text.prt.continue
|
||||||
|
print_symb.mov_ln:
|
||||||
|
mov al, [ypos]
|
||||||
|
inc al
|
||||||
|
mov [ypos], al
|
||||||
|
mov byte [xpos], 0
|
||||||
|
jmp print_symb.continue2
|
||||||
|
print_symb.mb_end:
|
||||||
|
cmp dh, 25
|
||||||
|
je view_text.waiting
|
||||||
|
jmp print_symb.continue
|
||||||
|
|
||||||
|
usage db "Usage: viewer.bin <filename>", 0
|
||||||
|
fnf db "File not found.", 0
|
||||||
|
ln db 0Dh, 0Ah, 0
|
||||||
|
file_FS_offset dw 0
|
||||||
|
xpos db 0
|
||||||
|
ypos db 0
|
||||||
|
|
||||||
|
times 1024-($-$$) db 0
|
||||||
|
file_offset:
|
||||||
|
times 2000 db "A"
|
|
@ -0,0 +1,35 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
rm iso/os.bin
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
./fasm bootloader.asm iso/os.bin
|
||||||
|
echo
|
||||||
|
./fasm programs/calculator.asm iso/calc.bin
|
||||||
|
echo
|
||||||
|
# ./fasm programs/notepad.asm iso/notepad.bin
|
||||||
|
# echo
|
||||||
|
./fasm programs/viewer.asm iso/viewer.bin
|
||||||
|
echo
|
||||||
|
nasm -fbin programs/snake.asm -o iso/snake.bin
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
|
||||||
|
cd iso
|
||||||
|
|
||||||
|
rm boot.img
|
||||||
|
dd if=/dev/zero of=boot.img bs=1024 count=1440
|
||||||
|
dd if=os.bin of=boot.img conv=notrunc
|
||||||
|
dd if=calc.bin of=boot.img conv=notrunc bs=512 seek=16
|
||||||
|
# dd if=notepad.bin of=boot.img conv=notrunc bs=512 seek=17
|
||||||
|
dd if=viewer.bin of=boot.img conv=notrunc bs=512 seek=17
|
||||||
|
dd if=calc.bin of=boot.img bs=512 seek=19 conv=notrunc
|
||||||
|
dd if=snake.bin of=boot.img bs=512 seek=20 conv=notrunc
|
||||||
|
# dd if=just_text.t of=boot.img conv=notrunc bs=512 seek=23
|
||||||
|
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# qemu-system-i386 iso/os.bin
|
||||||
|
qemu-system-i386 -fda iso/boot.img
|
|
@ -0,0 +1,36 @@
|
||||||
|
secstage:
|
||||||
|
mov ah, 02h
|
||||||
|
mov al, [filetable_ff+3]
|
||||||
|
mov dl, [BOOT_DRIVE]
|
||||||
|
mov ch, [filetable_ff]
|
||||||
|
mov dh, [filetable_ff+1]
|
||||||
|
mov cl, [filetable_ff+2]
|
||||||
|
mov bx, main
|
||||||
|
int 13h
|
||||||
|
|
||||||
|
mov al, [BOOT_DRIVE]
|
||||||
|
jc .error
|
||||||
|
|
||||||
|
call main
|
||||||
|
|
||||||
|
call dbg_halt_cpu
|
||||||
|
.error:
|
||||||
|
cmp cl, 0x0
|
||||||
|
je .notfound
|
||||||
|
cmp cl, 0x20
|
||||||
|
je .notfound
|
||||||
|
jmp booterror
|
||||||
|
|
||||||
|
.notfound:
|
||||||
|
mov ax, 1301h
|
||||||
|
mov bx, 7
|
||||||
|
xor dx, dx
|
||||||
|
mov bp, .notfoundmsg
|
||||||
|
mov cx, 22
|
||||||
|
int 10h
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
|
||||||
|
.notfoundmsg db '"kernel.bin" not found'
|
||||||
|
|
||||||
|
times 2560-($-$$) db 0
|
Loading…
Reference in New Issue