From 271d034556c3eb1b03065274ff4152f15f0b3520 Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Fri, 27 Sep 2024 19:57:38 +0100 Subject: [PATCH] Read and process batch files and bug fixes --- build/chimaera.img | Bin 368640 -> 368640 bytes build/chimaera.vhd | Bin 34120704 -> 34120704 bytes src/Makefile.unix | 17 +- src/apps/pcomm/Makefile.unix | 2 +- src/apps/pcomm/Makefile.w32 | 2 +- src/apps/pcomm/ll.asm | 692 +++++++++++++ src/apps/pcomm/pcomm.asm | 1850 ++++++++++++++++++++-------------- src/apps/pcomm/xrealloc.asm | 45 + src/boot/freeldr/core/ll.asm | 2 - src/kernel/disk.asm | 3 +- src/kernel/file.asm | 14 +- src/kernel/int21.asm | 8 + src/kernel/kernel.asm | 12 + src/kernel/krealloc.asm | 4 +- src/kernel/mem.asm | 158 ++- src/lib/crt/stdio/flags.asm | 8 +- src/lib/crt/udivmodsi4.asm | 9 +- 17 files changed, 2041 insertions(+), 785 deletions(-) create mode 100644 src/apps/pcomm/ll.asm create mode 100644 src/apps/pcomm/xrealloc.asm diff --git a/build/chimaera.img b/build/chimaera.img index 79c30fdaf6c5293d02b71a149ae1edeaa654ea5c..0e30930df07fd27292e33a6e4866c42e16f95c07 100644 GIT binary patch delta 17168 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 TpA-DL)Vb}o&on;tQMdmA0i0YW diff --git a/build/chimaera.vhd b/build/chimaera.vhd index 7c92d87f7abcca6c3abec34c86d6c5877927925e..e629017fef72e194369dd7d4c5682a699c76171d 100644 GIT binary patch delta 38196 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�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 O6Z}+u@b>~Yvi}Xv{#A> autoexec.bat +# echo echo 123 >> temp.bat +# echo @ echo %PATH% >> temp.bat +# echo temp.bat >> temp.bat + utils/dosfstools/mkdosfs --boot boot/freeldr/bootsect/fat12.bin --sectors 720 -F 12 -n "CHIMAERA OS" $@ utils/dosfstools/mmd -i $@ boot boot/freeldr @@ -30,13 +37,20 @@ chimaera.img: all utils/dosfstools/mcopy -i $@ boot/freeldr/core/freeldr.sys :: utils/dosfstools/mcopy -i $@ kernel/kernel.sys :: utils/dosfstools/mcopy -i $@ apps/pcomm/pcomm.com ::command.com + utils/dosfstools/mcopy -i $@ autoexec.bat :: -# utils/dosfstools/mmd -i $@ dos + utils/dosfstools/mmd -i $@ dos +# utils/dosfstools/mcopy -i $@ temp.bat ::/dos/temp.bat # utils/dosfstools/mcopy -i $@ apps/hello/hello.com ::dos/hello.com chimaera.vhd: all + if [ -f autoexec.bat ]; then rm -rf autoexec.bat; fi if [ -f $@ ]; then rm -rf $@; fi + echo set PATH=C:\\DOS >> autoexec.bat +# echo echo %PATH% >> autoexec.bat +# echo autoexec.bat >> autoexec.bat + # utils/parted/parted --arca --boot boot/mbr/dosmbr.bin mkpart 128,06,17,65535 $@ # utils/dosfstools/mkdosfs --arca --boot boot/freeldr/bootsect/fat16.bin --offset 17 --sectors 65535 -F 16 -n "CHIMAERA OS" $@ @@ -49,6 +63,7 @@ chimaera.vhd: all utils/dosfstools/mcopy --arca --offset 17 -i $@ boot/freeldr/core/freeldr.sys :: utils/dosfstools/mcopy --arca --offset 17 -i $@ kernel/kernel.sys :: utils/dosfstools/mcopy --arca --offset 17 -i $@ apps/pcomm/pcomm.com ::command.com + utils/dosfstools/mcopy --arca --offset 17 -i $@ autoexec.bat :: # utils/dosfstools/mcopy --arca --offset 17 -i $@ apps/hello/hello.com ::hello.com run-qemu: chimaera.img chimaera.vhd diff --git a/src/apps/pcomm/Makefile.unix b/src/apps/pcomm/Makefile.unix index cf1db90..f52306e 100644 --- a/src/apps/pcomm/Makefile.unix +++ b/src/apps/pcomm/Makefile.unix @@ -46,7 +46,7 @@ genver: genver.c gcc -o $@ $^ endif -pcomm.com: ../../lib/crt/crt0.o cbreak.o cd.o crlf.o date.o del.o dir.o erase.o exit.o history.o mkdir.o path.o pcomm.o rmdir.o set.o time.o touch.o type.o vector.o writechr.o writedec.o writehex.o writestr.o xmalloc.o xstrcpy.o ../../lib/crt/libc.a +pcomm.com: ../../lib/crt/crt0.o cbreak.o cd.o crlf.o date.o del.o dir.o erase.o exit.o history.o ll.o mkdir.o path.o pcomm.o rmdir.o set.o time.o touch.o type.o vector.o writechr.o writedec.o writehex.o writestr.o xmalloc.o xrealloc.o xstrcpy.o ../../lib/crt/libc.a ../../utils/binutils/slink --oformat msdos -o $@ $^ %.o: %.asm diff --git a/src/apps/pcomm/Makefile.w32 b/src/apps/pcomm/Makefile.w32 index f694373..8b28d85 100644 --- a/src/apps/pcomm/Makefile.w32 +++ b/src/apps/pcomm/Makefile.w32 @@ -30,7 +30,7 @@ genhash.exe: genhash.c genver.exe: genver.c gcc -o $@ $^ -pcomm.com: ../../lib/crt/crt0.o cbreak.o cd.o crlf.o date.o del.o dir.o erase.o exit.o history.o mkdir.o path.o pcomm.o rmdir.o set.o time.o touch.o type.o vector.o writedec.o writehex.o writestr.o xmalloc.o xstrcpy.o ../../lib/crt/libc.a +pcomm.com: ../../lib/crt/crt0.o cbreak.o cd.o crlf.o date.o del.o dir.o erase.o exit.o history.o ll.o mkdir.o path.o pcomm.o rmdir.o set.o time.o touch.o type.o vector.o writedec.o writehex.o writestr.o xmalloc.o xrealloc.o xstrcpy.o ../../lib/crt/libc.a ../../utils/binutils/slink --oformat msdos -o $@ $^ %.o: %.asm diff --git a/src/apps/pcomm/ll.asm b/src/apps/pcomm/ll.asm new file mode 100644 index 0000000..fc46e45 --- /dev/null +++ b/src/apps/pcomm/ll.asm @@ -0,0 +1,692 @@ +;****************************************************************************** +; @file ll.asm +;****************************************************************************** +%define CAPACITY_INCREMENT 256 + +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _load_line +;****************************************************************************** +global _load_line +_load_line: + + push bp + + mov bp, sp + sub sp, 12 + + push bx + push cx + push dx + push si + push di + push es + push ds + + mov bx, word ptr [bp + 12] + + and bx, bx + jz .L18 + + mov cx, ds + + push es + push ds + push si + push di + + mov es, cx + mov ds, bx + + mov di, offset _load_line_data + xor si, si + + mov cx, 14 + rep movsb + + pop di + pop si + pop ds + pop es + + mov ax, ss + mov es, ax + + xor ax, ax + lea di, word ptr [bp - 12] + + mov cx, 12 + rep stosb + + mov cx, word ptr [_load_line_data + 12] + + and cx, cx + jz .L1 + + push es + push ds + + mov ax, word ptr [_load_line_data + 8] + sub ax, word ptr [_load_line_data + 12] + + push ax + + mov ax, word ptr [_load_line_data + 2] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, word ptr [_load_line_data + 12] + adc dx, 0 + + div cx + push dx + + xor bx, bx + push bx + + mov bx, word ptr [_load_line_data + 2] + mov es, bx + + mov ds, ax + + call _memmove + add sp, 6 + + pop ds + pop es + + mov cx, word ptr [_load_line_data + 12] + sub word ptr [_load_line_data + 8], cx + +.L1: + + mov ax, word ptr [_load_line_data + 4] + + cmp ax, word ptr [bp - 12] + jb .L2 + + cmp ax, word ptr [bp - 8] + ja .L3 + +.L2: + + mov ax, word ptr [_load_line_data + 4] + xor dx, dx + + add ax, CAPACITY_INCREMENT + mov word ptr [_load_line_data + 4], ax + + mov bx, ax + xor cx, cx + + add bx, 2 + adc cx, 0 + + push ax + push dx + + push bx + push cx + push word ptr word ptr [_load_line_data + 0] + + call _xrealloc + add sp, 6 + + mov word ptr [_load_line_data + 0], ax + pop dx + pop ax + + mov bx, ax + mov cx, dx + + add bx, 1 + adc cx, 0 + + push ax + push dx + + push bx + push cx + push word ptr word ptr [_load_line_data + 2] + + call _xrealloc + add sp, 6 + + mov word ptr [_load_line_data + 2], ax + pop dx + pop ax + +.L3: + + mov ax, word ptr [_load_line_data + 8] + + cmp ax, word ptr [bp - 8] + ja .L4 + + push ds + push word ptr [bp + 10] + + mov ax, word ptr [_load_line_data + 4] + sub ax, word ptr [bp - 8] + + push ax + + mov ax, 1 + push ax + + mov ax, word ptr [_load_line_data + 2] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, word ptr [bp - 8] + adc dx, 0 + + div cx + + mov ds, ax + push dx + + call _fread + add sp, 8 + + pop ds + jc .L5 + + add ax, word ptr [bp - 8] + mov word ptr [_load_line_data + 8], ax + + mov ax, word ptr [_load_line_data + 2] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, word ptr [_load_line_data + 8] + adc dx, 0 + + div cx + + push es + push di + + mov es, ax + mov di, dx + + xor al, al + mov es:[di], al + + pop di + pop es + +.L15: + + cmp word ptr [bp - 4], 1 + jne .L4 + +.L17: + + mov ax, word ptr [_load_line_data + 8] + + cmp ax, word ptr [bp - 8] + jb .L4 + + mov ax, word ptr [_load_line_data + 2] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, word ptr [bp - 8] + adc dx, 0 + + div cx + + push es + push di + + mov es, ax + mov di, dx + + mov bl, es:[di] + pop di + pop es + + cmp bl, HEX (0A) + jne .L16 + + mov word ptr [bp - 4], 0 + jmp .L4 + +.L16: + + add word ptr [bp - 8], 1 + jmp .L17 + +.L4: + + mov ax, word ptr [_load_line_data + 8] + + cmp ax, word ptr [bp - 8] + jbe .L6 + +.L10: + + mov ax, word ptr [_load_line_data + 4] + + cmp ax, word ptr [bp - 12] + jbe .L6 + +.L11: + + push es + push di + + mov ax, word ptr [_load_line_data + 2] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, word ptr [bp - 8] + adc dx, 0 + + div cx + + mov es, ax + mov di, dx + + mov bl, es:[di] + pop di + pop es + + add word ptr [bp - 8], 1 + + push es + push di + + mov ax, word ptr [_load_line_data + 0] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, word ptr [bp - 12] + adc dx, 0 + + div cx + + mov es, ax + mov di, dx + + mov es:[di], bl + + pop di + pop es + + cmp bl, '#' + jne .L14 + + mov word ptr [bp - 4], 1 + jmp .L15 + +.L14: + + cmp bl, HEX (0A) + jne .L7 + + mov si, word ptr [bp - 12] + + and si, si + jz .L12 + + dec si + + mov ax, word ptr [_load_line_data + 0] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, si + adc dx, 0 + + inc si + div cx + + push es + push di + + mov es, ax + mov di, dx + + mov bl, es:[di] + pop di + pop es + + cmp bl, HEX (0D) + jne .L13 + + push es + push di + + mov es, ax + mov di, dx + + mov bl, HEX (0A) + mov es:[di], bl + + pop di + pop es + + mov word ptr [bp - 12], si + +.L13: + + and si, si + jz .L12 + + dec si + + mov ax, word ptr [_load_line_data + 0] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, si + adc dx, 0 + + div cx + + push es + push di + + mov es, ax + mov di, dx + + mov bl, es:[di] + pop di + pop es + + cmp bl, ' ' + jne .L12 + + push es + push di + + mov es, ax + mov di, dx + + mov bl, HEX (0A) + mov es:[di], bl + + pop di + pop es + + mov word ptr [bp - 12], si + jmp .L13 + +.L12: + + mov bx, word ptr [bp - 12] + inc bx + + mov ax, word ptr [_load_line_data + 0] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, bx + adc dx, 0 + + div cx + + push es + push di + + mov es, ax + mov di, dx + + xor al, al + mov es:[di], al + + pop di + pop es + + mov bx, word ptr [bp - 8] + mov word ptr [_load_line_data + 12], bx + + mov bx, word ptr [bp + 4] + + mov ax, word ptr [_load_line_data + 0] + mov [bx], ax + + jmp .L8 + +.L7: + + add word ptr [bp - 12], 1 + jmp .L4 + +.L6: + + push word ptr [bp + 10] + + call _feof + add sp, 2 + + and ax, ax + jz .L1 + + mov cx, word ptr [_load_line_data + 8] + + and cx, cx + jz .L5 + + mov ax, word ptr [_load_line_data + 0] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, word ptr [bp - 12] + adc dx, 0 + + div cx + + push es + push di + + mov es, ax + mov di, dx + + mov al, HEX (0A) + mov es:[di], al + + pop di + pop es + + mov bx, word ptr [bp - 12] + inc bx + + mov ax, word ptr [_load_line_data + 0] + xor dx, dx + + mov cx, 16 + mul cx + + add ax, bx + adc dx, 0 + + push es + push di + + mov es, ax + mov di, dx + + xor ax, ax + mov es:[di], al + + pop di + pop es + + mov word ptr [_load_line_data + 12], ax + mov word ptr [_load_line_data + 8], ax + + mov bx, word ptr [bp + 4] + + mov ax, word ptr [_load_line_data + 0] + mov [bx], ax + + jmp .L8 + +.L5: + + mov ax, word ptr [bp + 12] + mov es, ax + + mov si, offset _load_line_data + xor di, di + + mov cx, 14 + rep movsb + +.L18: + + mov ax, 1 + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + + add sp, 12 + stc + + pop bp + ret + +.L8: + + mov ax, word ptr [bp + 12] + mov es, ax + + mov si, offset _load_line_data + xor di, di + + mov cx, 14 + rep movsb + + xor ax, ax + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + + add sp, 12 + clc + + pop bp + ret + +;****************************************************************************** +; @function _load_line_create_internal_data +;****************************************************************************** +global _load_line_create_internal_data +_load_line_create_internal_data: + + push dx + +.L19: + + mov ax, 16 + xor dx, dx + + push ax + push dx + + call _xmalloc + add sp, 4 + +.L20: + + pop dx + ret + +;****************************************************************************** +; @function _load_line_destroy_internal_data +;****************************************************************************** +global _load_line_destroy_internal_data +_load_line_destroy_internal_data: + + push bp + mov bp, sp + + push es + push bx + push si + + mov bx, word ptr [bp + 4] + + and bx, bx + jz .L21 + + mov es, bx + xor bx, bx + + mov si, es:[bx + 0] + + and si, si + jz .L22 + + push si + + call _free + add sp, 2 + +.L22: + + mov si, es:[bx + 2] + + and si, si + jz L23 + + push si + + call _free + add sp, 2 + +L23: + + push es + + call _free + add sp, 2 + +.L21: + + pop si + pop bx + pop es + pop bp + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Data area. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +_load_line_data: db 14 dup (0) diff --git a/src/apps/pcomm/pcomm.asm b/src/apps/pcomm/pcomm.asm index 8e01127..ff12bf4 100644 --- a/src/apps/pcomm/pcomm.asm +++ b/src/apps/pcomm/pcomm.asm @@ -17,6 +17,15 @@ _main: mov bx, offset _welcome_message call _writestr + + xor ax, ax + push ax + + mov bx, offset _autoexec + push bx + + call _read_batch + add sp, 4 .L5: @@ -1175,1110 +1184,1266 @@ _main: .L21: - mov di, offset _formatted_command - push di - - xor al, al - - mov cx, 255 - rep stosb - mov bx, offset _scratch push bx - call _expand_vars - add sp, 4 + call _process_line + add sp, 2 - mov bx, offset _formatted_command + jmp .L5 + +.L1: + + and ch, ch + jz .L67 - call _get_command - jc .L23 + push ax + push bx + push cx + push dx - mov si, bx - xor ax, ax + xor ah, ah + mov al, cs:[_curr_col] - lodsb + xor dx, dx - and al, al - jz .L7 + mov cl, ch + xor ch, ch - push bx - xor bx, bx + add ax, cx - or al, HEX (20) - mov bl, al - -.L28: - - lodsb + mov di, offset _scratch + add di, cx - or al, al - jz .L31 + mov cx, 80 + div cx - mov cl, 5 - rol bx, cl + mov dh, cs:[_curr_row] + add dh, al - or al, HEX (20) - xor bx, ax + mov ax, HEX (0200) + xor bx, bx + int HEX (10) - jmp .L28 + pop dx + pop cx + pop bx + pop ax -.L31: +.L67: - mov di, bx - pop bx - - mov si, offset _cmd_table - mov cx, offset _cmd_count + call _history_up + jmp .L11 -.L29: +.L2: - lodsw + and ch, ch + jz .L66 - cmp di, ax - je .L30 + push ax + push bx + push cx + push dx - lodsw - lodsw - loop .L29 + xor ah, ah + mov al, cs:[_curr_col] - jmp .L23 - -.L30: - - push bx + xor dx, dx - call _strlen - add sp, 2 + mov cl, ch + xor ch, ch - add bx, ax - inc bx - -.L33: - - cmp byte ptr [bx], 0 - je .L32 + add ax, cx - cmp byte ptr [bx], ' ' - ja .L32 + mov di, offset _scratch + add di, cx - inc bx - jmp .L33 + mov cx, 80 + div cx + + mov dh, cs:[_curr_row] + add dh, al + + mov ax, HEX (0200) + xor bx, bx + int HEX (10) + + pop dx + pop cx + pop bx + pop ax -.L32: +.L66: - lodsw - - call cs:[si] - jmp .L5 + call _history_down + jmp .L11 -.L23: +.L75: - mov di, offset _app_path + and ch, ch + jz .L11 - mov ax, '\\' push ax - - mov si, bx push bx + push cx + push dx - call _strrchr - add sp, 4 + xor ah, ah + mov al, cs:[_curr_col] - and ax, ax - jz .L27 + xor dx, dx - mov bx, ax - mov byte ptr [bx], 0 + mov cl, ch + xor ch, ch - call _format_path + add ax, cx - mov al, '\\' - stosb + mov di, offset _scratch + add di, cx - inc bx + mov cx, 80 + div cx + + mov dh, cs:[_curr_row] + add dh, al + + mov ax, HEX (0200) + xor bx, bx + int HEX (10) + + pop dx + pop cx + pop bx + pop ax + + jmp .L11 -.L27: +.L74: - mov ax, '.' push ax - - mov si, bx push bx + push cx + push dx - call _strrchr - add sp, 4 + mov dh, cs:[_curr_row] + mov dl, cs:[_curr_col] - and ax, ax - jnz .L24 + mov ax, HEX (0200) + xor bx, bx + int HEX (10) + + mov di, offset _scratch + pop dx + pop cx + pop bx + pop ax + + jmp .L11 -.L26: +;****************************************************************************** +; @function _concat_exec +;****************************************************************************** +_concat_exec: + push bp + mov bp, sp + + push ax push bx + push cx + push dx + push si + push di + push es - call _strlen - add sp, 2 + mov ax, ds + mov es, ax - mov cx, ax - rep movsb + mov di, offset _full_path - mov word ptr cs:[_need_ext], 1 - add bx, ax + mov si, word ptr [bp + 4] + call _format_path - mov al, '.' + mov al, '\\' stosb - mov al, 'c' - stosb + mov si, word ptr [bp + 6] + call _format_path - mov al, 'o' - stosb + mov dx, offset _full_path + inc bx + mov di, bx - mov al, 'm' - stosb + mov bx, offset _param_blk - jmp .L25 + mov word ptr [bx + 2], di + mov word ptr [bx + 4], ds + + mov ax, HEX (4B00) + int HEX (21) -.L24: +_concat_exec.done: - push bx - - call _strlen - add sp, 2 - - mov cx, ax - rep movsb - - add bx, ax + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop bp + ret -.L25: +;****************************************************************************** +; @function _concat_read +;****************************************************************************** +_concat_read: - xor al, al - stosb + push bp + mov bp, sp + push ax push bx + push cx + push dx + push si + push di + push es - mov dx, offset _app_path - inc bx - mov di, bx + mov ax, ds + mov es, ax - mov bx, offset _param_blk + mov di, offset _full_path - mov word ptr [bx + 2], di - mov word ptr [bx + 4], ds + mov si, word ptr [bp + 4] + call _format_path - mov ax, HEX (4B00) - int HEX (21) - pop bx - jnc .L5 + mov al, '\\' + stosb - mov ax, '\\' + mov si, word ptr [bp + 6] + call _format_path + + mov ax, 1 push ax - mov ax, offset _app_path + mov ax, offset _full_path push ax - call _strrchr + call _read_batch + jc _concat_read.err + add sp, 4 + clc - and ax, ax - jnz .L98 + jmp _concat_read.done -.L99: +_concat_read.err: - call _get_paths + add sp, 4 + stc + +_concat_read.done: + + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop bp + ret + +;****************************************************************************** +; @function _get_env +;****************************************************************************** +_get_env: + + push bp + mov bp, sp - push ax push bx push cx + push dx + push si push di push es - mov ax, cs:[_vec_paths] - mov es, ax - mov cx, cs:[_vec_paths + 4] + mov si, cs:[_vec_env] + mov cx, cs:[_vec_env + 4] + mov es, si xor di, di -.L96: +.L91: and cx, cx - jz .L97 + jz .L92 - mov ax, offset _app_path + push es + mov ax, es:[di] + + mov es, ax + push es + + xor bx, bx + mov ax, es:[bx] + + push cx + push es + push ds + + mov cx, cs + mov es, cx + mov ds, ax + + push es + push di + + mov di, offset _temp + xor al, al + + mov cx, 255 + rep stosb + + pop di + pop es + + xor ax, ax push ax - mov ax, es:[di] + mov ax, offset _temp push ax - call _concat_exec - jnc .L100 + call _strcpy add sp, 4 - add di, 2 - dec cx + mov ax, word ptr [bp + 4] + push ax - jmp .L96 - -.L100: - + mov ax, offset _temp + push ax + + call _strcmp add sp, 4 + pop ds pop es - pop di pop cx - pop bx + + and ax, ax + jz .L93 + pop ax + pop es - jmp .L5 + add di, 2 + dec cx + + jmp .L91 -.L97: +.L93: + + pop ax + pop es + + jmp .L90 + +.L92: + + xor ax, ax + +.L90: pop es pop di + pop si + pop dx pop cx pop bx - pop ax + pop bp + ret -.L98: +;****************************************************************************** +; @function _expand_vars +;****************************************************************************** +_expand_vars: - mov bx, offset _err_invalid - call _writestr - - cmp word ptr cs:[_need_ext], 1 - jb .L34 + push bp + mov bp, sp - mov ax, '.' push ax - - mov bx, offset _app_path push bx + push cx + push dx + push si + push di - call _strrchr - add sp, 4 + mov di, word ptr [bp + 6] + mov si, word ptr [bp + 4] - mov bx, ax - mov byte ptr [bx], 0 + mov dx, di -.L34: +.L87: - mov bx, offset _app_path - call _writestr - call _crlf + cmp byte ptr [si], 0 + je .L84 - jmp .L5 - -.L1: - - and ch, ch - jz .L67 + mov cx, di + sub cx, dx - push ax - push bx - push cx - push dx + cmp cx, 255 + jae .L84 - xor ah, ah - mov al, cs:[_curr_col] + cmp byte ptr [si], '%' + jne .L85 - xor dx, dx + inc si - mov cl, ch - xor ch, ch + cmp byte ptr [si], 0 + jne .L86 - add ax, cx + mov al, '%' + stosb - mov di, offset _scratch - add di, cx + jmp .L87 + +.L86: + + cmp byte ptr [si], '%' + je .L85 - mov cx, 80 - div cx + mov ax, '%' + push ax - mov dh, cs:[_curr_row] - add dh, al + push si - mov ax, HEX (0200) - xor bx, bx - int HEX (10) + call _strchr + add sp, 4 - pop dx - pop cx - pop bx - pop ax - -.L67: - - call _history_up - jmp .L11 + and ax, ax + jnz .L88 + + ;mov al, '%' + ;stosb + + jmp .L87 -.L2: +.L88: - and ch, ch - jz .L66 + mov bx, ax + mov byte ptr [bx], 0 - push ax - push bx - push cx - push dx + push si - xor ah, ah - mov al, cs:[_curr_col] + call _get_env + add sp, 2 - xor dx, dx + and ax, ax + jz .L89 - mov cl, ch - xor ch, ch + push si + push ds - add ax, cx + mov ds, ax + xor si, si - mov di, offset _scratch - add di, cx + mov ax, [si + 2] + mov ds, ax + +.L94: + + mov cx, di + sub cx, dx - mov cx, 80 - div cx + cmp cx, 255 + jae .L95 - mov dh, cs:[_curr_row] - add dh, al + lodsb - mov ax, HEX (0200) - xor bx, bx - int HEX (10) + and al, al + jz .L95 - pop dx - pop cx - pop bx - pop ax + stosb + jmp .L94 -.L66: +.L95: - call _history_down - jmp .L11 + pop ds + pop si + + jmp .L84 -.L75: +.L89: - and ch, ch - jz .L11 - - push ax - push bx - push cx - push dx - - xor ah, ah - mov al, cs:[_curr_col] - - xor dx, dx - - mov cl, ch - xor ch, ch - - add ax, cx - - mov di, offset _scratch - add di, cx - - mov cx, 80 - div cx - - mov dh, cs:[_curr_row] - add dh, al - - mov ax, HEX (0200) - xor bx, bx - int HEX (10) - - pop dx - pop cx - pop bx - pop ax + mov si, bx + inc si - jmp .L11 + jmp .L87 -.L74: +.L85: - push ax - push bx - push cx - push dx - - mov dh, cs:[_curr_row] - mov dl, cs:[_curr_col] - - mov ax, HEX (0200) - xor bx, bx - int HEX (10) - - mov di, offset _scratch + movsb + jmp .L87 + +.L84: + + pop di + pop si pop dx pop cx pop bx pop ax - - jmp .L11 + pop bp + ret ;****************************************************************************** -; @function _concat_exec +; @function _format_path ;****************************************************************************** -_concat_exec: +_format_path: - push bp - mov bp, sp - push ax push bx push cx push dx - push si - push di - push es - mov ax, ds - mov es, ax + mov dx, di + jmp short _format_path.loop + +_format_path.store: + + stosb - mov di, offset _full_path + cmp al, '\\' + jne _format_path.loop + +_format_path.skip: + + lodsb - mov si, word ptr [bp + 4] - call _format_path + cmp al, '\\' + je _format_path.skip - mov al, '\\' - stosb + dec si + +_format_path.loop: + + mov ax, di + sub ax, dx - mov si, word ptr [bp + 6] - call _format_path + cmp ax, 250 + ja _format_path.done - mov dx, offset _full_path - inc bx - mov di, bx + lodsb - mov bx, offset _param_blk + and al, al + jz _format_path.done - mov word ptr [bx + 2], di - mov word ptr [bx + 4], ds + cmp al, 127 + ja _format_path.done - mov ax, HEX (4B00) - int HEX (21) + cmp al, 32 + jb _format_path.done + + jmp short _format_path.store -_concat_exec.done: +_format_path.done: - pop es - pop di - pop si pop dx pop cx pop bx pop ax - pop bp ret ;****************************************************************************** -; @function _get_env +; @function _get_command ;****************************************************************************** -_get_env: +_get_command: push bp + mov bp, sp + sub sp, 2 - push bx - push cx - push dx push si - push di - push es - - mov si, cs:[_vec_env] - mov cx, cs:[_vec_env + 4] + push ax + push dx - mov es, si - xor di, di + mov word ptr [bp - 2], 0 + mov si, offset _formatted_command -.L91: +_get_command.loop: - and cx, cx - jz .L92 + lodsb - push es - mov ax, es:[di] + and al, al + jz _get_command.done - mov es, ax - push es + cmp al, ' ' + jbe _get_command.null - xor bx, bx - mov ax, es:[bx] + cmp al, ':' + je _get_command.not_internal - push cx - push es - push ds + cmp al, '\\' + je _get_command.not_internal - mov cx, ds - mov es, cx - mov ds, ax + cmp al, '.' + je _get_command.not_internal + +_get_command.check: + + xor ah, ah - push es - push di + mov dx, ax + push dx - mov di, offset _temp - xor al, al - - mov cx, 255 - rep stosb - - pop di - pop es - - xor ax, ax - push ax - - mov ax, offset _temp - push ax - - call _strcpy - add sp, 4 - - pop ds - - mov ax, ds - mov es, ax - - mov ax, word ptr [bp + 4] - push ax - - mov ax, offset _temp - push ax - - call _strcmp - add sp, 4 - - pop es - pop cx + call _isalpha + add sp, 2 and ax, ax - jz .L93 + jz _get_command.loop - pop ax - pop es + push dx - add di, 2 - dec cx + call _tolower + add sp, 2 - jmp .L91 + mov [si - 1], al + jmp _get_command.loop -.L93: +_get_command.not_internal: - pop ax - pop es - - jmp .L90 + mov word ptr [bp - 2], 1 + jmp _get_command.loop -.L92: +_get_command.null: - xor ax, ax + mov byte ptr [si - 1], 0 -.L90: +_get_command.done: - pop es - pop di - pop si + mov bx, word ptr [bp - 2] + pop dx - pop cx - pop bx + pop ax + pop si + + add sp, 2 + clc + pop bp + + and bx, bx + jz _get_command.ret + + stc + +_get_command.ret: + + mov bx, offset _formatted_command ret ;****************************************************************************** -; @function _expand_vars +; @function _handle_backspace ;****************************************************************************** -_expand_vars: +_handle_backspace: - push bp - mov bp, sp + and ch, ch + jz .L12 + + xor ah, ah + mov al, cs:[_curr_col] - push ax push bx push cx push dx - push si - push di - mov di, word ptr [bp + 6] - mov si, word ptr [bp + 4] + xor dx, dx - mov dx, di - -.L87: - - cmp byte ptr [si], 0 - je .L84 + mov cl, ch + xor ch, ch - mov cx, di - sub cx, dx + add ax, cx - cmp cx, 255 - jae .L84 + mov cx, 80 + div cx - cmp byte ptr [si], '%' - jne .L85 + xchg ax, dx + pop dx + pop cx + pop bx - inc si + and ax, ax + jnz .L13 - cmp byte ptr [si], 0 - jne .L86 + push ax + push bx + push dx + push cx - mov al, '%' - stosb + mov ax, HEX (0300) + xor bx, bx + int HEX (10) - jmp .L87 - -.L86: - - cmp byte ptr [si], '%' - je .L85 + pop cx + dec dh - mov ax, '%' - push ax + mov ax, HEX (0200) + xor bx, bx + mov dl, HEX (50) + int HEX (10) - push si + call _erase_char - call _strchr - add sp, 4 + mov ax, HEX (0200) + xor bx, bx + mov dl, HEX (4F) + int HEX (10) - and ax, ax - jnz .L88 + pop dx + pop bx + pop ax - ;mov al, '%' - ;stosb + dec ch + dec di - jmp .L87 + mov byte ptr es:[di], 0 + ret -.L88: +.L13: - mov bx, ax - mov byte ptr [bx], 0 + call _erase_char - push si + dec ch + dec di - call _get_env - add sp, 2 + mov byte ptr es:[di], 0 + +.L12: + + ret + +;****************************************************************************** +; @function _handler_cls +;****************************************************************************** +_handler_cls: + + mov ax, HEX (0600) + mov bh, HEX (07) + xor cx, cx + mov dx, HEX (184F) + int HEX (10) - and ax, ax - jz .L89 + mov ax, HEX (0200) + xor bx, bx + xor dx, dx + int HEX (10) + ret + +;****************************************************************************** +; @function _handler_echo +;****************************************************************************** +_handler_echo: + + push ax + push dx push si - push ds - - mov ds, ax - xor si, si - mov ax, [si + 2] - mov ds, ax + mov si, bx -.L94: +_handler_echo.check: - mov cx, di - sub cx, dx - - cmp cx, 255 - jae .L95 + cmp word ptr cs:[_cbreak], 1 + je _handler_echo.done lodsb and al, al - jz .L95 + jz _handler_echo.newline - stosb - jmp .L94 - -.L95: - - pop ds - pop si - -.L89: - - mov si, bx - inc si + mov ah, HEX (02) + mov dl, al + int HEX (21) - jmp .L87 + jmp _handler_echo.check -.L85: +_handler_echo.newline: - movsb - jmp .L87 + mov ah, HEX (02) + mov dl, HEX (0D) + int HEX (21) + + mov ah, HEX (02) + mov dl, HEX (0A) + int HEX (21) -.L84: +_handler_echo.done: - pop di pop si pop dx - pop cx - pop bx pop ax - pop bp ret ;****************************************************************************** -; @function _format_path +; @function _handler_help ;****************************************************************************** -_format_path: +_handler_help: push ax push bx - push cx - push dx + push ds - mov dx, di - jmp short _format_path.loop + mov ax, cs + mov ds, ax + + mov bx, offset _handler_help.msg + call _writestr -_format_path.store: +_handler_help.done: - stosb + pop ds + pop bx + pop ax + ret + +_handler_help.msg: + + db "CD Change the current directory to the specified path.", HEX (0D), HEX (0A) + db "CLS Clears the screen.", HEX (0D), HEX (0A) + db "DATE Displays the system date.", HEX (0D), HEX (0A) + db "DEL Delete the specified files.", HEX (0D), HEX (0A) + db "DIR Displays a list of files and subdirectories in a directory.", HEX (0D), HEX (0A) + db "ECHO Specifies the text to display to the screen.", HEX (0D), HEX (0A) + db "EXIT Exit the current shell if it's not the last instance.", HEX (0D), HEX (0A) + db "MKDIR Create a new directory.", HEX (0D), HEX (0A) + db "REBOOT Reboots the machine.", HEX (0D), HEX (0A) + db "RMDIR Delete an empty directory.", HEX (0D), HEX (0A) + db "SET Display, enable or disable environment variables.", HEX (0D), HEX (0A) + db "TIME Displays the system time.", HEX (0D), HEX (0A) + db "TOUCH Create a new file if it doesn't already exist.", HEX (0D), HEX (0A) + db "TYPE Displays the contents of a text file.", HEX (0D), HEX (0A) - cmp al, '\\' - jne _format_path.loop + db HEX (00) -_format_path.skip: +;****************************************************************************** +; @function _handler_reboot +;****************************************************************************** +_handler_reboot: - lodsb + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Disable interrupts. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cli - cmp al, '\\' - je _format_path.skip + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Stop floppy motor. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dx, HEX (03F2) + xor al, al + out dx, al - dec si + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Reset console. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, HEX (0003) + int HEX (10) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Cold reboot. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + mov es, ax + + mov bx, HEX (0472) + mov word ptr es:[bx], 0 + + jmp HEX (F000) : HEX (FFF0) -_format_path.loop: +;****************************************************************************** +; @function _process_line +;****************************************************************************** +global _process_line +_process_line: - mov ax, di - sub ax, dx + push bp + mov bp, sp - cmp ax, 250 - ja _format_path.done + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + + mov ax, cs + mov es, ax + +.L102: + + mov di, offset _formatted_command + push di + + xor al, al + + mov cx, 255 + rep stosb + + mov bx, word ptr [bp + 4] + push bx + + call _expand_vars + add sp, 4 + + mov ax, cs + mov ds, ax + + mov bx, offset _formatted_command + + call _get_command + jc .L23 + + mov si, bx + xor ax, ax lodsb and al, al - jz _format_path.done + jz .L101 - cmp al, 127 - ja _format_path.done + push bx + xor bx, bx - cmp al, 32 - jb _format_path.done + or al, HEX (20) + mov bl, al + +.L28: + + lodsb - jmp short _format_path.store + or al, al + jz .L31 + + mov cl, 5 + rol bx, cl + + or al, HEX (20) + xor bx, ax + + jmp .L28 -_format_path.done: +.L31: - pop dx - pop cx + mov di, bx pop bx - pop ax - ret + + mov si, offset _cmd_table + mov cx, offset _cmd_count -;****************************************************************************** -; @function _get_command -;****************************************************************************** -_get_command: +.L29: - push bp + lodsw - mov bp, sp - sub sp, 2 + cmp di, ax + je .L30 - push si - push ax - push dx + lodsw + lodsw + loop .L29 - mov word ptr [bp - 2], 0 - mov si, offset _formatted_command + jmp .L23 -_get_command.loop: +.L30: - lodsb + push bx - and al, al - jz _get_command.done + call _strlen + add sp, 2 - cmp al, ' ' - jbe _get_command.null + add bx, ax + inc bx + +.L33: + + cmp byte ptr [bx], 0 + je .L32 - cmp al, ':' - je _get_command.not_internal + cmp byte ptr [bx], ' ' + ja .L32 - cmp al, '\\' - je _get_command.not_internal + inc bx + jmp .L33 + +.L32: + + lodsw - cmp al, '.' - je _get_command.not_internal + call cs:[si] + jmp .L101 -_get_command.check: +.L23: - xor ah, ah + mov di, offset _app_path - mov dx, ax - push dx + mov ax, '\\' + push ax - call _isalpha - add sp, 2 + mov si, bx + push bx + + call _strrchr + add sp, 4 and ax, ax - jz _get_command.loop + jz .L27 - push dx + mov bx, ax + mov byte ptr [bx], 0 - call _tolower - add sp, 2 + call _format_path - mov [si - 1], al - jmp _get_command.loop - -_get_command.not_internal: - - mov word ptr [bp - 2], 1 - jmp _get_command.loop - -_get_command.null: - - mov byte ptr [si - 1], 0 + mov al, '\\' + stosb + + inc bx -_get_command.done: +.L27: - mov bx, word ptr [bp - 2] - - pop dx - pop ax - pop si - - add sp, 2 - clc + mov ax, '.' + push ax - pop bp + mov si, bx + push bx - and bx, bx - jz _get_command.ret + call _strrchr + add sp, 4 - stc - -_get_command.ret: - - mov bx, offset _formatted_command - ret + and ax, ax + jnz .L24 -;****************************************************************************** -; @function _handle_backspace -;****************************************************************************** -_handle_backspace: +.L26: - and ch, ch - jz .L12 + push bx - xor ah, ah - mov al, cs:[_curr_col] + call _strlen + add sp, 2 - push bx - push cx - push dx + mov cx, ax + rep movsb - xor dx, dx + mov word ptr cs:[_need_ext], 1 + add bx, ax - mov cl, ch - xor ch, ch + push di - add ax, cx + mov al, '.' + stosb - mov cx, 80 - div cx + mov al, 'c' + stosb - xchg ax, dx - pop dx - pop cx - pop bx + mov al, 'o' + stosb - and ax, ax - jnz .L13 + mov al, 'm' + stosb + jmp .L25 + +.L24: + push ax push bx - push dx - push cx - mov ax, HEX (0300) - xor bx, bx - int HEX (10) + call _strlen + add sp, 2 - pop cx - dec dh + mov cx, ax + rep movsb - mov ax, HEX (0200) - xor bx, bx - mov dl, HEX (50) - int HEX (10) + add bx, ax + +.L25: + + xor al, al + stosb - call _erase_char + mov word ptr cs:[_in_batch], 0 - mov ax, HEX (0200) - xor bx, bx - mov dl, HEX (4F) - int HEX (10) + mov ax, offset _ext_batch + push ax - pop dx - pop bx - pop ax + call _strcmp + add sp, 4 - dec ch - dec di + and ax, ax + jnz .L104 - mov byte ptr es:[di], 0 - ret + mov word ptr cs:[_in_batch], 1 + + mov ax, 1 + push ax + + mov ax, offset _app_path + push ax + + call _read_batch + jc .L107 + + add sp, 4 + jmp .L101 -.L13: +.L104: - call _erase_char + push bx - dec ch - dec di + mov dx, offset _app_path + inc bx + mov di, bx - mov byte ptr es:[di], 0 + mov bx, offset _param_blk + + mov word ptr [bx + 2], di + mov word ptr [bx + 4], ds + + mov ax, HEX (4B00) + int HEX (21) + pop bx + jnc .L101 + + jmp .L103 -.L12: +.L107: - ret + add sp, 4 -;****************************************************************************** -; @function _handler_cls -;****************************************************************************** -_handler_cls: +.L103: - mov ax, HEX (0600) - mov bh, HEX (07) - xor cx, cx - mov dx, HEX (184F) - int HEX (10) + mov ax, '\\' + push ax - mov ax, HEX (0200) - xor bx, bx - xor dx, dx - int HEX (10) + mov ax, offset _app_path + push ax - ret + call _strrchr + add sp, 4 + + and ax, ax + jnz .L98 -;****************************************************************************** -; @function _handler_echo -;****************************************************************************** -_handler_echo: +.L99: + call _get_paths + push ax - push dx - push si + push bx + push cx + push di + push es - mov si, bx + mov ax, cs:[_vec_paths] + mov es, ax + mov cx, cs:[_vec_paths + 4] + + xor di, di -_handler_echo.check: +.L96: - cmp word ptr cs:[_cbreak], 1 - je _handler_echo.done + and cx, cx + jz .L97 - lodsb + mov ax, offset _app_path + push ax - and al, al - jz _handler_echo.newline + mov ax, es:[di] + push ax - mov ah, HEX (02) - mov dl, al - int HEX (21) + cmp word ptr cs:[_in_batch], 1 + jne .L105 - jmp _handler_echo.check + call _concat_read + jnc .L100 + add sp, 4 + + add di, 2 + dec cx + + jmp .L96 -_handler_echo.newline: +.L105: - mov ah, HEX (02) - mov dl, HEX (0D) - int HEX (21) + call _concat_exec + jnc .L100 + add sp, 4 + + add di, 2 + dec cx + + jmp .L96 + +.L100: + + add sp, 4 - mov ah, HEX (02) - mov dl, HEX (0A) - int HEX (21) + pop es + pop di + pop cx + pop bx + pop ax + + jmp .L101 -_handler_echo.done: +.L97: - pop si - pop dx + pop es + pop di + pop cx + pop bx pop ax - ret -;****************************************************************************** -; @function _handler_help -;****************************************************************************** -_handler_help: +.L98: + mov bx, offset _err_invalid + call _writestr + + cmp word ptr cs:[_need_ext], 1 + jb .L34 + + mov ax, '.' push ax + + mov bx, offset _app_path push bx - push ds - mov ax, cs - mov ds, ax + call _strrchr + add sp, 4 - mov bx, offset _handler_help.msg + mov bx, ax + mov byte ptr [bx], 0 + +.L34: + + mov bx, offset _app_path call _writestr + call _crlf -_handler_help.done: +.L101: pop ds + pop es + pop di + pop si + pop dx + pop cx pop bx pop ax + pop bp ret -_handler_help.msg: - - db "CD Change the current directory to the specified path.", HEX (0D), HEX (0A) - db "CLS Clears the screen.", HEX (0D), HEX (0A) - db "DATE Displays the system date.", HEX (0D), HEX (0A) - db "DEL Delete the specified files.", HEX (0D), HEX (0A) - db "DIR Displays a list of files and subdirectories in a directory.", HEX (0D), HEX (0A) - db "ECHO Specifies the text to display to the screen.", HEX (0D), HEX (0A) - db "EXIT Exit the current shell if it's not the last instance.", HEX (0D), HEX (0A) - db "MKDIR Create a new directory.", HEX (0D), HEX (0A) - db "REBOOT Reboots the machine.", HEX (0D), HEX (0A) - db "RMDIR Delete an empty directory.", HEX (0D), HEX (0A) - db "SET Display, enable or disable environment variables.", HEX (0D), HEX (0A) - db "TIME Displays the system time.", HEX (0D), HEX (0A) - db "TOUCH Create a new file if it doesn't already exist.", HEX (0D), HEX (0A) - db "TYPE Displays the contents of a text file.", HEX (0D), HEX (0A) - - db HEX (00) - -;****************************************************************************** -; @function _handler_reboot -;****************************************************************************** -_handler_reboot: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Disable interrupts. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cli - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Stop floppy motor. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov dx, HEX (03F2) - xor al, al - out dx, al - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Reset console. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, HEX (0003) - int HEX (10) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Cold reboot. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - mov es, ax - - mov bx, HEX (0472) - mov word ptr es:[bx], 0 - - jmp HEX (F000) : HEX (FFF0) - ;****************************************************************************** ; @function _prompt ;****************************************************************************** @@ -2347,6 +2512,201 @@ _prompt: pop ax ret +;****************************************************************************** +; @function _read_batch +;****************************************************************************** +global _read_batch +_read_batch: + + push bp + + mov bp, sp + sub sp, 6 + + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + + mov word ptr [bp - 6], 0 + mov word ptr [bp - 4], 0 + mov word ptr [bp - 2], 0 + +_read_batch.open: + + mov ax, offset _batch_flags + push ax + + mov ax, word ptr [bp + 4] + push ax + + call _fopen + add sp, 4 + + and ax, ax + jz _read_batch.err + + mov word ptr [bp - 4], ax + +_read_batch.parse: + + call _load_line_create_internal_data + + and ax, ax + jz _read_batch.close + + mov word ptr [bp - 2], ax + +_read_batch.read_line: + + mov ax, word ptr [bp - 2] + push ax + + mov ax, word ptr [bp - 4] + push ax + + xor ax, ax + push ax + push ax + + lea ax, word ptr [bp - 6] + push ax + + call _load_line + add sp, 10 + + and ax, ax + jnz _read_batch.close + + push ax + push bx + push ds + + mov ax, word ptr [bp - 6] + mov ds, ax + xor bx, bx + +_read_batch.skip: + + cmp byte ptr [bx], ' ' + jne _read_batch.check + + inc bx + jmp _read_batch.skip + +_read_batch.check: + + cmp byte ptr [bx], HEX (0A) + je _read_batch.next + + mov ax, ds + mov es, ax + + mov di, bx + push di + + call _strlen + add sp, 2 + + add di, ax + dec di + + xor al, al + stosb + + cmp word ptr [bp + 6], 0 + je _read_batch.process + + cmp byte ptr [bx], '@' + jne _read_batch.echo + + inc bx + +_read_batch.skip2: + + cmp byte ptr [bx], ' ' + jne _read_batch.process + + inc bx + jmp _read_batch.skip2 + +_read_batch.echo: + + call _writestr + call _crlf + +_read_batch.process: + + push bx + + call _process_line + add sp, 2 + +_read_batch.next: + + pop ds + pop bx + pop ax + + jmp _read_batch.read_line + +_read_batch.close: + + push word ptr [bp - 4] + + call _fclose + add sp, 2 + +_read_batch.free: + + mov ax, word ptr [bp - 2] + + and ax, ax + jz _read_batch.done + + push ax + + call _load_line_destroy_internal_data + add sp, 2 + +_read_batch.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + + add sp, 6 + clc + + pop bp + ret + +_read_batch.err: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + + add sp, 6 + stc + + pop bp + ret + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Includes. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2371,20 +2731,28 @@ _scratch: db 257 dup (0) _app_path: db 256 dup (0) _param_blk: db 16 dup (0) -_full_path: db 256 dup (0) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Error messages. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +_err_segmentation: db "Segmentation fault", HEX (0D), HEX (0A), HEX (00) _err_invalid: db "Bad command or file name - ", HEX (00) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data area. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; _formatted_command: db 256 dup (0) -_fn_wild: db "*.*", HEX (00) +_full_path: db 256 dup (0) _temp: db 257 dup (0) +_autoexec: db "AUTOEXEC.BAT", HEX (00) +_batch_flags: db "r", HEX (00) + +_in_batch: dw HEX (0000) +_ext_batch: db ".bat", HEX (00) + +_ll_scratch: dw HEX (0000) +_fn_wild: db "*.*", HEX (00) + _dta_addr: dw HEX (0000) _insert: dw HEX (0000) diff --git a/src/apps/pcomm/xrealloc.asm b/src/apps/pcomm/xrealloc.asm new file mode 100644 index 0000000..e5692c4 --- /dev/null +++ b/src/apps/pcomm/xrealloc.asm @@ -0,0 +1,45 @@ +;****************************************************************************** +; @file xrealloc.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _xrealloc +;****************************************************************************** +global _xrealloc +_xrealloc: + + push bp + mov bp, sp + + push word ptr [bp + 8] + push word ptr [bp + 6] + push word ptr [bp + 4] + + call _realloc + add sp, 6 + + and ax, ax + jnz _xrealloc.done + +_xrealloc.error: + + pop bp + + mov ax, cs + mov ds, ax + + mov bx, offset _err_realloc + call _writestr + + mov ax, HEX (4C01) + int HEX (21) + +_xrealloc.done: + + pop bp + ret + +_err_realloc: db "Memory full (realloc)", HEX (0D), HEX (0A), HEX (00) diff --git a/src/boot/freeldr/core/ll.asm b/src/boot/freeldr/core/ll.asm index 9c0c4cb..fc46e45 100644 --- a/src/boot/freeldr/core/ll.asm +++ b/src/boot/freeldr/core/ll.asm @@ -610,7 +610,6 @@ _load_line: global _load_line_create_internal_data _load_line_create_internal_data: - push ax push dx .L19: @@ -627,7 +626,6 @@ _load_line_create_internal_data: .L20: pop dx - pop ax ret ;****************************************************************************** diff --git a/src/kernel/disk.asm b/src/kernel/disk.asm index 7c42816..8529e35 100644 --- a/src/kernel/disk.asm +++ b/src/kernel/disk.asm @@ -954,7 +954,8 @@ _read_sectors.success: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Loop until cx is zero. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - loop _read_sectors.next + dec cx + jnz _read_sectors.next _read_sectors.done: diff --git a/src/kernel/file.asm b/src/kernel/file.asm index 091aef0..8cdd429 100644 --- a/src/kernel/file.asm +++ b/src/kernel/file.asm @@ -75,7 +75,7 @@ _read_cluster.check: mov dx, cx call cs:[_convert_cluster] - jnc _read_cluster.read + jc _read_cluster.done _read_cluster.read: @@ -401,10 +401,9 @@ _close_file.ok: xor di, di ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Our file handle info contains a pointer to a buffer at offset - ;; 52 so we need to free it. + ;; Our file handle info contains a pointer to a buffer so free it. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, es:[di + 68] + mov ax, es:[di + 70] push es mov es, ax @@ -764,15 +763,10 @@ _open_file.got_handle: ;; Allocate memory for a buffer that will be used to keep track of ;; the current data read. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push si - xor si, si - - mov ax, es:[si + 50] + mov ax, cs:[_clustsize] xor dx, dx call _kmalloc - pop si - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Store the value. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/kernel/int21.asm b/src/kernel/int21.asm index 4a9903d..aaec6ce 100644 --- a/src/kernel/int21.asm +++ b/src/kernel/int21.asm @@ -3221,6 +3221,10 @@ _int21_3F.copy: lodsw mov cs:[_curr_cluster + 2], ax + push di + push es + push ax + mov di, offset _fat_bpb mov ax, cs mov es, ax @@ -3228,6 +3232,10 @@ _int21_3F.copy: mov cx, 25 rep movsb + pop ax + pop es + pop di + lodsb mov cs:[_drive_no], al diff --git a/src/kernel/kernel.asm b/src/kernel/kernel.asm index 8f21869..5f452d4 100644 --- a/src/kernel/kernel.asm +++ b/src/kernel/kernel.asm @@ -54,6 +54,18 @@ _all_read: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov [_drive_no], dl + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the initial cluster size. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ch, ch + mov cl, byte ptr [bp - 62] + + mov ax, word ptr [bp - 64] + xor dx, dx + + mul cx + mov cs:[_clustsize], ax + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Initialize the stack segment with the value stored in bx. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/kernel/krealloc.asm b/src/kernel/krealloc.asm index 82d3ec0..0a08af2 100644 --- a/src/kernel/krealloc.asm +++ b/src/kernel/krealloc.asm @@ -121,10 +121,10 @@ _krealloc.alloc: mov cx, word ptr es:[di + 3] mov es, ax - cmp cx, bx + cmp cx, si jb _krealloc.copy - mov cx, bx + mov cx, si _krealloc.copy: diff --git a/src/kernel/mem.asm b/src/kernel/mem.asm index 2bd24a0..9798ad1 100644 --- a/src/kernel/mem.asm +++ b/src/kernel/mem.asm @@ -5,12 +5,22 @@ % define HEX(y) 0x##y %endif +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Include our fat.inc. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%include "fat.inc" + ;****************************************************************************** ; @function _alloc_mem ;****************************************************************************** global _alloc_mem _alloc_mem: + push bp + + mov bp, sp + sub sp, 20 + push cx push dx push si @@ -21,13 +31,12 @@ _alloc_mem: mov es, ax push es - mov ax, bx - xor di, di _alloc_mem.search: mov cx, es + xor di, di cmp cx, cs:[_free_seg] jb _alloc_mem.error @@ -101,9 +110,120 @@ _alloc_mem.retry: _alloc_mem.success: - xor di, di pop es + xor si, si + mov di, 1 + + mov ax, es + xor dx, dx + + mov cx, 16 + mul cx + + mov cx, 1 + push cx + + push di + push si + push dx + push ax + + call _udivmodsi4 + add sp, 10 + + mov word ptr [bp - 4], ax + + xor si, si + mov di, 1 + + mov ax, es + inc ax + xor dx, dx + + mov cx, 16 + mul cx + + add ax, cs:[_clustsize] + adc dx, 0 + + mov cx, 1 + push cx + + push di + push si + push dx + push ax + + call _udivmodsi4 + add sp, 10 + + cmp word ptr [bp - 4], ax + je _alloc_mem.ok + + mov ax, es + xor dx, dx + + mov cx, 16 + mul cx + + mov di, ax + mov si, dx + + xor ax, ax + mov dx, 1 + + mov cx, di + add cx, ax + + mov word ptr [bp - 12], cx + + mov cx, si + adc cx, dx + + mov word ptr [bp - 10], cx + + mov ax, word ptr [bp - 12] + add ax, -1 + + mov word ptr [bp - 16], ax + + mov ax, word ptr [bp - 10] + adc ax, -1 + + mov word ptr [bp - 14], ax + + ;xor ax, ax + ;push ax + + mov ax, 1 + push ax + push ax + + xor ax, ax + push ax + + push word ptr [bp - 14] + push word ptr [bp - 16] + + call _udivmodsi4 + add sp, 10 + + xchg ax, dx + + mov cx, 16 + div cx + + mov es, ax + push es + + mov ax, bx + jmp _alloc_mem.search + +_alloc_mem.ok: + + xor di, di + mov byte ptr es:[di], 'M' mov byte ptr es:[di + 1], 'C' mov byte ptr es:[di + 2], 'B' @@ -115,7 +235,6 @@ _alloc_mem.success: mov ax, es inc ax - clc jmp short _alloc_mem.done _alloc_mem.error: @@ -124,8 +243,18 @@ _alloc_mem.error: pop ax sub bx, ax - mov ax, 8 + pop es + pop di + pop si + pop dx + pop cx + + add sp, 20 stc + pop bp + + mov ax, 8 + ret _alloc_mem.done: @@ -134,6 +263,11 @@ _alloc_mem.done: pop si pop dx pop cx + + add sp, 20 + clc + pop bp + ret ;****************************************************************************** @@ -317,20 +451,6 @@ _resize_mem.ins: _resize_mem.got_seg: - pop es - - mov ax, es - sub bx, ax - - push es - - mov di, es - dec di - mov es, di - - xor di, di - mov word ptr es:[di + 3], bx - mov ax, 8 stc diff --git a/src/lib/crt/stdio/flags.asm b/src/lib/crt/stdio/flags.asm index 64efd06..c24be27 100644 --- a/src/lib/crt/stdio/flags.asm +++ b/src/lib/crt/stdio/flags.asm @@ -87,11 +87,11 @@ _sflags.loop: lodsb - or al, al + and al, al jz _sflags.done cmp al, '+' - jne _sflags.next + jne _sflags.loop mov di, __SRD | __SWR not di @@ -104,9 +104,7 @@ _sflags.loop: and cx, di or cx, O_RDWR - -_sflags.next: - + jmp short _sflags.loop _sflags.done: diff --git a/src/lib/crt/udivmodsi4.asm b/src/lib/crt/udivmodsi4.asm index 7a99176..e8c8d1e 100644 --- a/src/lib/crt/udivmodsi4.asm +++ b/src/lib/crt/udivmodsi4.asm @@ -11,12 +11,14 @@ global _udivmodsi4 _udivmodsi4: - push si push bp mov bp, sp sub sp, 12 + push bx + push si + mov word ptr [bp - 4], 1 mov word ptr [bp - 2], 0 mov word ptr [bp - 8], 0 @@ -147,7 +149,10 @@ _udivmodsi4: .L13: + pop si + pop bx + add sp, 12 pop bp - pop si + ret -- 2.34.1