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