No more commits because I don't work on it anymore
main release
Plaza521 2023-03-15 00:59:50 +03:00 committed by GitHub
parent 0c7002019d
commit a86c9533d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 2809 additions and 0 deletions

160
bootloader.asm Normal file
View File

@ -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'

11
constants.asm Normal file
View File

@ -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

117
data.asm Normal file
View File

@ -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

BIN
fasm Normal file

Binary file not shown.

8
filetable.asm Normal file
View File

@ -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

846
funcs.asm Normal file
View File

@ -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

74
functable.asm Normal file
View File

@ -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]

152
help.txt Normal file
View File

@ -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:

BIN
iso/boot.img Normal file

Binary file not shown.

BIN
iso/calc.bin Normal file

Binary file not shown.

10
iso/just_text.t Normal file
View File

@ -0,0 +1,10 @@
Privet, ti 4udovishe
Novay strok
Dolistay ahaha

BIN
iso/notepad.bin Normal file

Binary file not shown.

BIN
iso/os.bin Normal file

Binary file not shown.

BIN
iso/snake.bin Normal file

Binary file not shown.

BIN
iso/viewer.bin Normal file

Binary file not shown.

480
kernel.asm Normal file
View File

@ -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

71
macros.asm Normal file
View File

@ -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
}

232
programs/calculator.asm Normal file
View File

@ -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

58
programs/dskview.asm Normal file
View File

@ -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

6
programs/hw.asm Normal file
View File

@ -0,0 +1,6 @@
include 'include.asm'
print hw
ret
hw db "Hello, world", 0Dh, 0Ah, 0

52
programs/include.asm Normal file
View File

@ -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

44
programs/notepad.asm Normal file
View File

@ -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

View File

@ -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
}

274
programs/snake.asm Normal file
View File

@ -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

72
programs/viewer.asm Normal file
View File

@ -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"

35
run.sh Normal file
View File

@ -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

36
secstage.asm Normal file
View File

@ -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