From: Robert Pengelly Date: Thu, 22 Aug 2024 15:30:38 +0000 (+0100) Subject: Parse all disks in freeldr and bug fixes X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=3bc911f5bcac3bf643bdc95785031d808183616e;p=chimaera.git Parse all disks in freeldr and bug fixes --- diff --git a/build/chimaera.img b/build/chimaera.img index 8e2c89e..4066ef5 100644 Binary files a/build/chimaera.img and b/build/chimaera.img differ diff --git a/build/chimaera.vhd b/build/chimaera.vhd index 213446b..ef100c9 100644 Binary files a/build/chimaera.vhd and b/build/chimaera.vhd differ diff --git a/src/Makefile.unix b/src/Makefile.unix index 1d5aab0..db0dd9c 100644 --- a/src/Makefile.unix +++ b/src/Makefile.unix @@ -50,5 +50,5 @@ chimaera.vhd: all # utils/dosfstools/mcopy --arca --offset 17 -i $@ apps/hello/hello.com ::hello.com run-qemu: chimaera.img chimaera.vhd -# qemu-system-i386 -cpu 486 -drive file="chimaera.img",format=raw,if=floppy,index=0 -m 4M + qemu-system-i386 -cpu 486 -drive file="chimaera.img",format=raw,if=floppy,index=0 -m 4M qemu-system-i386 -cpu 486 -drive file="chimaera.vhd",format=raw,if=ide,index=0 -m 4M diff --git a/src/boot/freeldr/Makefile.unix b/src/boot/freeldr/Makefile.unix index 19e4d5d..a538927 100644 --- a/src/boot/freeldr/Makefile.unix +++ b/src/boot/freeldr/Makefile.unix @@ -1,7 +1,7 @@ #****************************************************************************** # @file Makefile.unix #****************************************************************************** -TARGETS := bootsect libc core +TARGETS := bootsect lib core OBJDIR ?= $(CURDIR) SRCDIR ?= $(CURDIR) diff --git a/src/boot/freeldr/Makefile.w32 b/src/boot/freeldr/Makefile.w32 index 849742c..fc6004a 100644 --- a/src/boot/freeldr/Makefile.w32 +++ b/src/boot/freeldr/Makefile.w32 @@ -1,7 +1,7 @@ #****************************************************************************** # @file Makefile.w32 #****************************************************************************** -TARGETS := bootsect libc core +TARGETS := bootsect lib core OBJDIR ?= $(CURDIR) SRCDIR ?= $(CURDIR) diff --git a/src/boot/freeldr/core/Makefile.unix b/src/boot/freeldr/core/Makefile.unix index 3afab38..9ce688e 100644 --- a/src/boot/freeldr/core/Makefile.unix +++ b/src/boot/freeldr/core/Makefile.unix @@ -13,7 +13,7 @@ clean: for f in *.lst; do if [ -f $$f ]; then rm -rf $$f; fi; done if [ -f freeldr.sys ]; then rm -rf freeldr.sys; fi -freeldr.sys: bootstrap.o config.o crlf.o disk.o error.o fat.o file.o freeldr.o int21.o ll.o mangle.o mem.o menu.o screen.o search.o vector.o walk.o writechr.o writedec.o writehex.o writestr.o xmalloc.o xrealloc.o ../libc/libc.a +freeldr.sys: bootstrap.o config.o crlf.o disk.o divide.o error.o fat.o file.o free.o freeldr.o int21.o invalid.o ll.o mangle.o mem.o menu.o screen.o search.o vector.o walk.o writechr.o writedec.o writehex.o writestr.o xmalloc.o xrealloc.o ../lib/crt/libc.a ../../../utils/binutils/slink --oformat binary -o $@ $^ %.o: %.asm diff --git a/src/boot/freeldr/core/Makefile.w32 b/src/boot/freeldr/core/Makefile.w32 index 7141a47..f1a920c 100644 --- a/src/boot/freeldr/core/Makefile.w32 +++ b/src/boot/freeldr/core/Makefile.w32 @@ -13,7 +13,7 @@ clean: for %%f in (*.lst) do ( if exist %%f ( del /q %%f ) ) if exist freeldr.sys ( del /q freeldr.sys ) -freeldr.sys: bootstrap.o config.o crlf.o disk.o error.o fat.o file.o freeldr.o int21.o ll.o mangle.o mem.o menu.o screen.o search.o vector.o walk.o writechr.o writedec.o writehex.o writestr.o xmalloc.o xrealloc.o ../libc/libc.a +freeldr.sys: bootstrap.o config.o crlf.o disk.o divide.o error.o fat.o file.o free.o freeldr.o int21.o invalid.o ll.o mangle.o mem.o menu.o screen.o search.o vector.o walk.o writechr.o writedec.o writehex.o writestr.o xmalloc.o xrealloc.o ../lib/crt/libc.a ../../../utils/binutils/slink --oformat binary -o $@ $^ %.o: %.asm diff --git a/src/boot/freeldr/core/config.asm b/src/boot/freeldr/core/config.asm index 33916fe..0652296 100644 --- a/src/boot/freeldr/core/config.asm +++ b/src/boot/freeldr/core/config.asm @@ -973,8 +973,8 @@ _parse_config.got_carry: _error_kernel_without_label: db "kernel specified outside label", HEX (0D), HEX (0A), HEX (00) _error_title_without_label: db "title specified outside label", HEX (0D), HEX (0A), HEX (00) -_error_noparam: db "missing parameter in lilo.cfg", HEX (0D), HEX (0A), HEX (00) -_error_badcfg: db "unknown keyword in lilo.cfg", HEX (0D), HEX (0A), HEX (00) +_error_noparam: db "missing parameter", HEX (0D), HEX (0A), HEX (00) +_error_badcfg: db "unknown keyword", HEX (0D), HEX (0A), HEX (00) _error_junk: db "junk '", HEX (00), "' at the end of line", HEX (0D), HEX (0A), HEX (00) _filename: dw HEX (0000) diff --git a/src/boot/freeldr/core/disk.asm b/src/boot/freeldr/core/disk.asm index 21e8920..7e762ef 100644 --- a/src/boot/freeldr/core/disk.asm +++ b/src/boot/freeldr/core/disk.asm @@ -10,6 +10,738 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; %include "fat.inc" +;****************************************************************************** +; @function _read_boot_sector +;****************************************************************************** +_read_boot_sector: + + push ax + push bx + push cx + push dx + push si + push di + push ds + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Check if we have disk extensions. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ah, HEX (41) + mov bx, HEX (55AA) + stc + int HEX (13) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the carry flag is set then disk extensions a unavailable. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jc _read_boot_sector.standard_bios + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Bit 1 in the cx register should be set if disk extensions + ;; are present. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + shr cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Test for carry (from shr) too. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + sbb bx, HEX (AA55) - 1 + jne _read_boot_sector.standard_bios + +_read_boot_sector.lba_bios: + + mov cs:[_read_boot_sector.bios_lba_address_packet + 6], es + + mov ax, es:[si + 8] + mov cs:[_read_boot_sector.bios_lba_low], ax + + mov ax, es:[si + 10] + mov cs:[_read_boot_sector.bios_lba_high], ax + + mov ax, cs + mov ds, ax + + mov ax, HEX (4200) + mov si, offset _read_boot_sector.bios_lba_address_packet + + stc + int HEX (13) + + jmp _read_boot_sector.check + +_read_boot_sector.standard_bios: + + mov ax, HEX (0201) + xor bx, bx + + mov cx, es:[si + 2] + mov dh, es:[si + 1] + + stc + int HEX (13) + +_read_boot_sector.check: + + cmp byte ptr es:[bx], HEX (EB) + je _read_boot_sector.check2 + + stc + jmp _read_boot_sector.done + +_read_boot_sector.check2: + + cmp byte ptr es:[bx + 2], HEX (90) + je _read_boot_sector.done + + stc + +_read_boot_sector.done: + + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + +_read_boot_sector.bios_lba_address_packet: + + db HEX (10) + db HEX (00) + db HEX (01) + db HEX (00) + dw HEX (0000) + dw HEX (0000) + +_read_boot_sector.bios_lba_low: + + dw HEX (0000) + +_read_boot_sector.bios_lba_high: + + dw HEX (0000) + dw HEX (0000), HEX (0000) + +;****************************************************************************** +; @function _get_partition_info +;****************************************************************************** +global _get_partition_info +_get_partition_info: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Set the base pointer to the stack pointer and reserve some space. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + sub sp, 30 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push ds + push bx + push si + push di + push dx + push cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clear the stack space. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov word ptr [bp - 2], 0 + mov word ptr [bp - 4], 0 + mov word ptr [bp - 6], 0 + mov word ptr [bp - 8], 0 + mov word ptr [bp - 10], 0 + mov word ptr [bp - 12], 0 + mov word ptr [bp - 14], 0 + mov word ptr [bp - 16], 0 + mov word ptr [bp - 18], 0 + mov word ptr [bp - 20], 0 + mov word ptr [bp - 22], 0 + mov word ptr [bp - 24], 0 + mov word ptr [bp - 26], 0 + mov word ptr [bp - 28], 0 + mov word ptr [bp - 30], 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; MBR partitions start at offset 0x01BE and are 16 bytes in length. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 6] + xor dx, dx + + mov cx, 16 + mul cx + + mov si, ax + add si, HEX (01BE) + +.L8: + + mov dx, word ptr [bp + 4] + + mov ah, HEX (10) + stc + int HEX (13) + jc .L21 + +.L9: + + push cx + push dx + + mov bx, ss + mov es, bx + xor bx, bx + + mov ax, HEX (0201) + mov cx, HEX (0001) + xor dh, dh + stc + int HEX (13) + + pop dx + pop cx + jc .L21 + +.L10: + + cmp byte ptr es:[bx + 0], HEX (EB) + jne .L11 + + cmp byte ptr es:[bx + 2], HEX (90) + jne .L11 + + jmp .L12 + +.L11: + + cmp byte ptr es:[si], 128 + je .L13 + + cmp byte ptr es:[si], 0 + jne .L21 + +.L13: + + xor ch, ch + mov cl, cs:[_drive_no] + + cmp word ptr [bp + 4], cx + jne .L23 + + cmp byte ptr es:[si], 128 + jne .L23 + + mov word ptr [bp - 2], 1 + +.L23: + + mov bx, ss + mov es, bx + xor bx, bx + + call _read_boot_sector + jc .L21 + +.L14: + + cmp byte ptr es:[bx + 0], HEX (EB) + jne .L21 + + cmp byte ptr es:[bx + 2], HEX (90) + jne .L21 + + cmp byte ptr es:[bx + 1], HEX (58) + jne .L12 + + mov al, es:[bx + 1] + mov cs:[_fat_jump + 1], al + + mov ax, es:[bx + 48] + mov word ptr [bp - 26], ax + + mov ax, es:[bx + 44] + mov dx, es:[bx + 46] + + mov word ptr [bp - 4], ax + mov word ptr [bp - 6], dx + + xor ax, ax + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the offset of the first FAT. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, es:[bx + 28] + mov di, es:[bx + 30] + + add si, es:[bx + 14] + adc di, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov word ptr [bp - 22], si + mov word ptr [bp - 24], di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the sectors per FAT. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx + 36] + mov word ptr [bp - 28], ax + + mov ax, es:[bx + 38] + mov word ptr [bp - 30], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate how many sectors both FATs require. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov al, es:[bx + 16] + cbw + + push ax + + mul word ptr [bp - 30] + add di, ax + + pop ax + mul word ptr [bp - 28] + + add ax, si + adc dx, di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the offset for later use. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov word ptr [bp - 8], ax + mov word ptr [bp - 10], dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the sector mask. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx + 11] + shr ax + shr ax + dec ax + + mov word ptr [bp - 12], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the sector shift. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor cx, cx + + xchg ax, cx + inc cx + +.L26: + + inc ax + shr cx + + cmp cx, 1 + jne .L26 + + mov word ptr [bp - 14], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Jump passed the oldfat calculations. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jmp .L25 + +.L12: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the offset of the first FAT. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, es:[bx + 28] + mov di, es:[bx + 30] + + add si, es:[bx + 14] + adc di, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov word ptr [bp - 22], si + mov word ptr [bp - 24], di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate how many sectors both FATs require. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov al, es:[bx + 16] + cbw + mul word ptr es:[bx + 22] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Adjust the FAT offset to get the root directory offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add si, ax + adc di, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the offset for later use. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov word ptr [bp - 16], si + mov word ptr [bp - 18], di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate how many sectors the root directory requires. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, HEX (0020) + mul word ptr es:[bx + 17] + div word ptr es:[bx + 11] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Adjust the root offset to get the data offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add si, ax + adc di, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the offset for later use. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov word ptr [bp - 8], si + mov word ptr [bp - 10], di + +.L25: + + xor di, di + + mov ax, HEX (80) + push ax + + xor ax, ax + push ax + + call _xmalloc + add sp, 4 + + mov es, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; First, thing we need is a place to store the current directory. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, 65 + push ax + + xor ax, ax + push ax + + call _xmalloc + add sp, 4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Start in the root of the disk. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp - 28] + stosw + + mov ax, word ptr [bp - 30] + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We need a scratch buffer for the disk so allocate one. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, ss:[bx + 11] + xor dx, dx + + xor ch, ch + mov cl, ss:[bx + 13] + + mul cx + mov word ptr [bp - 20], ax + +.L24: + + push ax + push dx + + call _xmalloc + add sp, 4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + stosw + + mov ax, ss + mov ds, ax + + mov si, bx + add si, 11 + + mov cx, 25 + rep movsb + + mov ax, word ptr [bp + 4] + stosb + + mov ax, word ptr [bp - 4] + stosw + + mov ax, word ptr [bp - 6] + stosw + + mov ax, word ptr [bp - 22] + stosw + + mov ax, word ptr [bp - 24] + stosw + + mov ax, word ptr [bp - 16] + stosw + + mov ax, word ptr [bp - 18] + stosw + + mov ax, word ptr [bp - 8] + stosw + + mov ax, word ptr [bp - 10] + stosw + + mov ax, word ptr [bp - 12] + stosw + + mov ax, word ptr [bp - 14] + stosw + + mov ax, word ptr [bp - 20] + stosw + + mov ax, word ptr [bp - 26] + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get drive parameters. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dx, word ptr [bp + 4] + + mov ah, HEX (08) ; clobbers AX, BL, CX, DX, ES:DI + int HEX (13) + jc .L7 + + and cx, HEX (3F) + mov es:[HEX (0015)], cx + + mov cl, dh + inc cx + mov es:[HEX (0017)], cx + +.L7: + + mov ax, es + jmp .L19 + +.L21: + + xor ax, ax + +.L19: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop cx + pop dx + pop di + pop si + pop bx + pop ds + pop es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Check if the partiton is active. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp word ptr [bp - 2], 1 + je .L22 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clear the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 30 + clc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +.L22: + + add sp, 30 + stc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _get_hard_disk_partitions +;****************************************************************************** +global _get_hard_disk_partitions +_get_hard_disk_partitions: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer and make some room + ;; for variables within this function. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + sub sp, 10 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push ax + push bx + push cx + push dx + push si + push di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push di + + mov ax, ss + mov es, ax + + lea di, [bp - 10] + xor al, al + + mov cx, 10 + rep stosb + + pop di + pop es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Set up our loop variables. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + mov word ptr [bp - 4], ax + +.L3: + + cmp word ptr [bp - 4], 4 + jae .L1 + + mov dx, word ptr [bp - 4] + add dx, HEX (80) + + xor ax, ax + mov word ptr [bp - 2], ax + +.L5: + + cmp word ptr [bp - 2], 4 + jae .L6 + + mov ax, word ptr [bp - 2] + push ax + + mov ax, dx + push ax + + call _get_partition_info + jnc .L17 + + add sp, 4 + + and ax, ax + jz .L15 + + mov es, ax + xor bx, bx + + cmp es:[bx + 33], dl + jne .L16 + + cmp word ptr cs:[_selected_disk], 0 + ja .L16 + + mov cx, cs:[_vec_parts + 4] + inc cx + mov cs:[_selected_disk], cx + + jmp .L16 + +.L17: + + add sp, 4 + +.L16: + + push ax + + mov ax, offset _vec_parts + push ax + + call _vec_push + add sp, 4 + + jmp .L15 + +.L15: + + add word ptr [bp - 2], 1 + jmp .L5 + +.L6: + + add word ptr [bp - 4], 1 + jmp .L3 + +.L1: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clean up the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 10 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Pop the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + + ;****************************************************************************** ; @function _read_sectors ;****************************************************************************** @@ -236,3 +968,9 @@ _edd_available: dw HEX (0000) global _disk_scratch _disk_scratch: dw HEX (0000) + +global _selected_disk +_selected_disk: dw HEX (0000) + +global _vec_parts +_vec_parts: db 6 dup (0) diff --git a/src/boot/freeldr/core/divide.asm b/src/boot/freeldr/core/divide.asm new file mode 100644 index 0000000..8f0200d --- /dev/null +++ b/src/boot/freeldr/core/divide.asm @@ -0,0 +1,125 @@ +;****************************************************************************** +; @file invalid.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _divide_handler +;****************************************************************************** +global _divide_handler +_divide_handler: + + push bp + mov bp, sp + + push ax + push bx + +_divide_handler.clear: + + mov ax, HEX (0600) + mov bh, HEX (1F) + xor cx, cx + mov dx, HEX (1850) + int HEX (10) + + mov ah, HEX (02) + xor bh, bh + xor dx, dx + int HEX (10) + + jmp _divide_handler.init + +_divide_handler.no_clear: + + call _crlf + +_divide_handler.init: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure the data segment is the dame as the code segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs + mov ds, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Print our first message. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, offset _divide_handler.msg + call _writestr + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Print a newline. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _crlf + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the si register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor si, si + +_divide_handler.loop: + + cmp si, 12 * 2 + jae _divide_handler.done + + mov ax, si + xor dx, dx + + mov cx, 12 + div cx + + and dx, dx + jnz _divide_handler.print + + call _crlf + + mov al, ' ' + call _writechr + call _writechr + call _writechr + call _writechr + +_divide_handler.print: + + mov ax, word ptr [bp + si] + call _writehex + + inc si + inc si + + mov ax, si + xor dx, dx + + mov cx, 12 + div cx + + and dx, dx + jz _divide_handler.loop + + mov al, ' ' + call _writechr + call _writechr + call _writechr + call _writechr + + jmp _divide_handler.loop + +_divide_handler.done: + + call _crlf + call _crlf + +_divide_handler.reboot: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Call error with our ending message. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _error + db "Press any key to reboot...", HEX (00) + +_divide_handler.msg: + + db "Trap to vector 0: Divide overflow", HEX (00) diff --git a/src/boot/freeldr/core/fat.asm b/src/boot/freeldr/core/fat.asm index 73ed6c9..7833313 100644 --- a/src/boot/freeldr/core/fat.asm +++ b/src/boot/freeldr/core/fat.asm @@ -115,6 +115,109 @@ _convert_cluster32.c3: ret +;****************************************************************************** +; @function _getfattype +;****************************************************************************** +global _getfattype +_getfattype: + + push ax + push bx + push cx + push dx + push si + push di + + xor ax, ax + xor dx, dx + +_getfattype.init: + + mov al, cs:[_sectors_per_cluster] + cbw + mov si, ax + + mov di, cs:[_bytes_per_sector] + + xor dx, dx + xor cx, cx + + mov ax, cs:[_total_sectors16] + and ax, ax + jnz _getfattype.have_secs + + mov ax, cs:[_total_sectors32] + mov dx, cs:[_total_sectors32 + 2] + +_getfattype.have_secs: + + sub ax, cs:[_reserved_sectors] + sbb dx, 0 + + mov cl, cs:[_number_of_fats] + +_getfattype.sec_fat_loop: + + sub ax, cs:[_sectors_per_fat] + sbb dx, 0 + loop _getfattype.sec_fat_loop + + push ax + push dx + + mov ax, cs:[_root_entries] + + mov bx, 32 + mul bx + + add ax, di + adc dx, 0 + + sub ax, 1 + sbb dx, 0 + + div di + mov bx, ax + + pop dx + pop ax + + sub ax, bx + sbb dx, 0 + + div si + + cmp ax, 4096 + ja _getfattype.fat16 + +_getfattype.fat12: + + mov ax, offset _convert_cluster12 + mov cs:[_convert_cluster], ax + + mov ax, offset _nextcluster_fat12 + mov cs:[_next_cluster], ax + + jmp short _getfattype.done + +_getfattype.fat16: + + mov ax, offset _convert_cluster16 + mov cs:[_convert_cluster], ax + + mov ax, offset _nextcluster_fat16 + mov cs:[_next_cluster], ax + +_getfattype.done: + + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + ;****************************************************************************** ; @function _nextcluster_fat12 ;****************************************************************************** @@ -388,7 +491,7 @@ global _fat_jump _fat_jump: db HEX (EB) - db HEX (00) + db HEX (3C) db HEX (90) global _fat_seg diff --git a/src/boot/freeldr/core/file.asm b/src/boot/freeldr/core/file.asm index fa437ba..e6bbf2a 100644 --- a/src/boot/freeldr/core/file.asm +++ b/src/boot/freeldr/core/file.asm @@ -38,226 +38,57 @@ _read_cluster: push ds push si push di - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve the cluster. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - push cx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; We need to preserve the data segment and the ax register. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push ax - push ds - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve the extra segment and the si register. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push es - push si - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the data segment with the code segment and initialize the - ;; si register with the offset of our BPB. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs - mov ds, ax - mov si, offset _fat_bpb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the extra segment with the stack segment and load the - ;; address that we're saving at. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, ss - mov es, ax - lea di, [bp - 36] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Copy the BPB. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 25 - rep movsb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Also save the drive number and the edd flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, cs:[_drive_no] - stosb - - mov ax, cs:[_edd_available] - stosw - - mov ax, cs:[_fat_start] - stosw - - mov ax, cs:[_fat_start + 2] - stosw - - mov ax, cs:[_data_start] - stosw - - mov ax, cs:[_data_start + 2] - stosw - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the si register and the extra segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop si - pop es - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve the extra segment and the si register again. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push es - push si - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Set the data segment to the extra segment and add 4 to si. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, es - mov ds, ax - add si, 4 - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Set the extra segment to the code segment and set the di register - ;; to the offset of our BPB. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs - mov es, ax - mov di, offset _fat_bpb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Copy the BPB info. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 25 - rep movsb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the si register and the extra segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop si - pop es - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the data segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop ds - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the drive number and edd available flag from the info. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, es:[si + 29] - mov cs:[_drive_no], al - - mov ax, es:[si + 44] - mov cs:[_fat_start], ax - - mov ax, es:[si + 46] - mov cs:[_fat_start + 2], ax - - mov ax, es:[si + 48] - mov cs:[_data_start], ax - - mov ax, es:[si + 50] - mov cs:[_data_start + 2], ax - - mov ax, es:[si + 52] - mov cs:[_edd_available], ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the ax register. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop ax - -_read_cluster.find: - - push si - - mov bx, es:[si + 54] _read_cluster.walk: and ax, ax - jz _read_cluster.read + jz _read_cluster.check + + push ax + push dx + + mov ax, bx + mov dx, cx - call bx + call cs:[_next_cluster] jnc _read_cluster.found - pop si - pop cx - pop bx + pop dx + pop ax jmp _read_cluster.done _read_cluster.found: + mov bx, ax + mov cx, dx + + pop dx + pop ax + dec ax jnz _read_cluster.walk -_read_cluster.read: +_read_cluster.check: - pop si - pop dx - pop ax - - mov bx, es:[si + 56] - - call bx - jc _read_cluster.done + mov ax, bx + mov dx, cx - mov cx, bx + call cs:[_convert_cluster] + jnc _read_cluster.read + +_read_cluster.read: + + xor ch, ch + mov cl, es:[si + 6] - mov bx, es:[si + 58] + mov bx, es:[si + 70] mov es, bx xor bx, bx call _read_sectors _read_cluster.done: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the extra segment with the stack segment and load the - ;; address that we stored the BPB too. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, ss - mov ds, ax - lea si, [bp - 36] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the extra segment with the code segment and initialize the - ;; si register with the offset of our BPB. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs - mov es, ax - mov di, offset _fat_bpb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Copy the BPB. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 25 - rep movsb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the drive number and edd available flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - lodsb - mov cs:[_drive_no], al - - lodsw - mov cs:[_edd_available], ax - - lodsw - mov cs:[_fat_start], ax - - lodsw - mov cs:[_fat_start + 2], ax - - lodsw - mov cs:[_data_start], ax - - lodsw - mov cs:[_data_start + 2], ax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Restore registers. @@ -301,60 +132,69 @@ _getc: _getc.is_eof: - mov ax, es:[si + 38] - mov dx, es:[si + 40] + mov ax, es:[si + 66] + mov dx, es:[si + 68] mov cx, ax + or cx, dx jz _getc.done _getc.check: - cmp dx, es:[si + 36] + cmp dx, es:[si + 64] ja _getc.check2 - cmp dx, es:[si + 36] + cmp dx, es:[si + 64] jne _getc.done - cmp ax, es:[si + 34] + cmp ax, es:[si + 62] jbe _getc.done _getc.check2: - mov ax, es:[si + 34] - mov dx, es:[si + 36] + mov ax, es:[si + 62] + mov dx, es:[si + 64] - mov cx, es:[si + 42] + mov cx, es:[si + 50] div cx + cmp word ptr es:[si + 54], 0 + je _getc.check_offset + + mov word ptr es:[si + 54], 0 + jmp short _getc.read + +_getc.check_offset: + and dx, dx jnz _getc.loaded - - mov bx, es:[si + 30] - mov cx, es:[si + 32] + +_getc.read: + + mov bx, es:[si + 58] + mov cx, es:[si + 60] call _read_cluster _getc.loaded: push es - mov bx, es:[si + 58] + mov bx, es:[si + 70] mov es, bx mov bx, dx mov al, es:[bx] mov bx, ds mov es, bx - stosb - - mov bx, es - mov ds, bx + stosb pop es + inc word ptr [bp - 2] - add word ptr es:[si + 34], 1 - adc word ptr es:[si + 36], 0 + add word ptr es:[si + 62], 1 + adc word ptr es:[si + 64], 0 _getc.done: @@ -557,24 +397,24 @@ _close_file.ok: mov ax, es:[bx] mov es, ax + xor di, di ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Our file handle info contains a pointer to a buffer so free it. + ;; Our file handle info contains a pointer to a buffer at offset + ;; 52 so we need to free it. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, es:[di + 58] - push ax + mov ax, es:[di + 68] + push es - call _free - add sp, 2 + mov es, ax + call _free_mem ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Free our entry. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push es - - call _free - add sp, 2 + pop es + call _free_mem ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Restore the extra segment. @@ -632,17 +472,6 @@ _open_file: push es push ds - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the di register with the file name. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov di, dx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out bh and set bl to the flags. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor bh, bh - mov bl, al - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Walk the path until we hit the last '\'. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -737,6 +566,8 @@ _open_file.found_dir: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; test cl, HEX (18) jz _open_file.got_file + + jmp _open_file.error _open_file.name_error: @@ -807,11 +638,11 @@ _open_file.got_handle: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Allocate memory for the file info. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, 64 - xor dx, dx + mov ax, 128 + push ax + xor ax, ax push ax - push dx call _xmalloc add sp, 4 @@ -819,17 +650,10 @@ _open_file.got_handle: mov es, ax xor di, di - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the value 1 as the first word to indicate that we need - ;; to be read - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, 1 + mov ax, cs:[_sectors_per_fat32] stosw - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the flags. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, bx + mov ax, cs:[_sectors_per_fat32 + 2] stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -862,96 +686,130 @@ _open_file.got_handle: pop si ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the drive number. + ;; Store other disk info. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov al, cs:[_drive_no] stosb - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the starting cluster. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[si + 0] + mov ax, cs:[_root_cluster] stosw - mov ax, cs:[si + 2] + mov ax, cs:[_root_cluster + 2] stosw - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; File pointer starts at zero. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax + mov ax, cs:[_fat_start] stosw + + mov ax, cs:[_fat_start + 2] stosw - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the file size. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[si + 4] + mov ax, cs:[_root_start] stosw - mov ax, cs:[si + 6] + mov ax, cs:[_root_start + 2] + stosw + + mov ax, cs:[_data_start] + stosw + + mov ax, cs:[_data_start + 2] + stosw + + mov ax, cs:[_fat_secmask] + stosw + + mov ax, cs:[_fat_secshift] stosw - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the size of a cluster. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax, cs:[_clustsize] stosw + xor ax, ax + ;mov ax, cs:[_info_sector] + stosw + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the FAT start. + ;; Store the value 1 as the first word to indicate that we need + ;; to be read ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_fat_start] + mov ax, 1 stosw - mov ax, cs:[_fat_start + 2] + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the flags. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, bx stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the data start. + ;; Store the starting cluster. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_data_start] + mov ax, cs:[si + 0] stosw - mov ax, cs:[_data_start + 2] + mov ax, cs:[si + 2] stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store wheither edd features are available. + ;; File pointer starts at zero. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_edd_available] + xor ax, ax + stosw stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the address of our next cluster function. + ;; Store the file size. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_next_cluster] + mov ax, cs:[si + 4] stosw - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the address of our convert cluster function. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_convert_cluster] + mov ax, cs:[si + 6] stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Allocate memory for a buffer that will be used to keep track of ;; the current data read. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_clustsize] - xor dx, dx + push si + xor si, si + mov ax, es:[si + 50] + push ax + + xor ax, ax push ax - push dx call _xmalloc add sp, 4 + pop si + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Store the value. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; stosw + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the ax register and store it. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store information about where the entry is located on disk. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs:[si + 10] + stosw + + mov ax, cs:[si + 12] + stosw + + mov ax, cs:[si + 14] + stosw + + mov ax, cs:[si + 16] + stosw + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Restore ax and re-push it to the stack. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -969,6 +827,9 @@ _open_file.check: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Nope, so add the file info to our vector. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs + mov ds, ax + push es mov bx, offset _vec_files @@ -992,6 +853,11 @@ _open_file.no_push: mov bx, cs:[_vec_files + 0] mov es, bx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Subtract 3 from ax to get the real index into our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + sub ax, 3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Zero out the dx register. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1031,7 +897,7 @@ _open_file.done: pop bx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Ckear the carry flag. + ;; Clear the carry flag. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; clc @@ -1073,64 +939,10 @@ _read_file: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov word ptr [bp - 2], 0 - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Check if we have any open files. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cmp word ptr cs:[_vec_files + 2], 0 - je _close_file.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Make sure we have a valid file handle. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cmp bx, 3 - jb _close_file.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the correct file offset by subtracting 3. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - sub bx, 3 - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Calculate the offset into our vector. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push dx - push cx - - mov ax, bx - xor dx, dx - - mov cx, 2 - mul cx - - mov bx, ax - pop cx - pop dx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Intialize the es register with address of our vector entries - ;; and zero out bx for the counter. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_vec_files + 0] - mov es, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; If the vector entry is zero then the file handle is invalid. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cmp word ptr es:[bx], 0 - je _read_file.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Re-initialize the extra segment but this time with the address - ;; of the vector entry. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, es:[bx] - mov es, ax - xor si, si - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Make sure we're not write-only. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cmp word ptr es:[si + 2], 1 + cmp word ptr es:[si + 56], 1 je _read_file.error ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1140,6 +952,9 @@ _read_file: _read_file.loop: + and cx, cx + jz _read_file.done + call _getc jc _read_file.error @@ -1147,7 +962,9 @@ _read_file.loop: jz _read_file.done inc word ptr [bp - 2] - loop _read_file.loop + + dec cx + jnz _read_file.loop _read_file.done: @@ -1204,4 +1021,5 @@ _read_file.error: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data area. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +global _vec_files _vec_files: db 6 dup (0) diff --git a/src/boot/freeldr/core/free.asm b/src/boot/freeldr/core/free.asm new file mode 100644 index 0000000..3084077 --- /dev/null +++ b/src/boot/freeldr/core/free.asm @@ -0,0 +1,35 @@ +;****************************************************************************** +; @file free.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _free +;****************************************************************************** +global _free +_free: + + push bp + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ax + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Free the blocks. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, word ptr [bp + 4] + call _free_mem + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop ax + pop bp + ret diff --git a/src/boot/freeldr/core/freeldr.asm b/src/boot/freeldr/core/freeldr.asm index 38ca233..5b3cc46 100644 --- a/src/boot/freeldr/core/freeldr.asm +++ b/src/boot/freeldr/core/freeldr.asm @@ -6,9 +6,16 @@ %endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Includes. +;; Interrupt vectors. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -%include "fat.inc" +%define DIVIDE_VECTOR 0x00 ; Divide Interrupt Vector. +%define INVALID_VECTOR 0x06 ; Invalid Opcode Interrupt Vector. +%define REBOOT_VECTOR 0x19 ; Warm Reboot Interrupt Vector. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS Interrupt Vectors. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%define INT21_VECTOR 0x21 ; DOS API Vector. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Memory layout. @@ -21,8 +28,6 @@ Mem.Kernel: equ HEX (0600) global _all_read _all_read: - jnc _not_fat32 - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Disable interrupts and clear the direction flag. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -34,74 +39,12 @@ _all_read: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov bx, es - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the extra segment with the code segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs - mov es, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the offset of our _fat_bpb in the di register (where we want to - ;; copy the BPB to). - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov di, offset _fat_bpb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the data segment with the stack segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, ss - mov ds, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Load the address of the base pointer minus 64 (start of the BPB). - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - lea si, [bp - 64] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Copy the BPB to our _fat_bpb offset - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 25 - rep movsb - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Initialize the data segment with the code segment. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax, cs mov ds, ax - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Copy some other variables. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, HEX (58) - mov [_fat_jump + 1], al - - mov ax, word ptr [bp - 39] - mov [_sectors_per_fat32], ax - - mov ax, word ptr [bp - 37] - mov [_sectors_per_fat32 + 2], ax - - mov ax, word ptr [bp - 35] - mov [_root_cluster], ax - - mov ax, word ptr [bp - 33] - mov [_root_cluster + 2], ax - - mov ax, word ptr [bp - 28] - mov [_edd_available], ax - - mov ax, word ptr [bp - 24] - mov [_fat_start], ax - - mov ax, word ptr [bp - 22] - mov [_fat_start + 2], ax - - mov ax, word ptr [bp - 20] - mov [_data_start], ax - - mov ax, word ptr [bp - 18] - mov [_data_start + 2], ax - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Save the drive no. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -114,255 +57,15 @@ _all_read: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; We should only need a little room for the stack so set the - ;; stack pointer to 512. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov sp, HEX (0200) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Calculate the sector mask. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_bytes_per_sector] - shr ax - shr ax - dec ax - - mov cs:[_fat_secmask], ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Calculate the sector shift. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor cx, cx - xchg ax, cx - -.L5: - - inc ax - shr cx - - cmp cx, 1 - jne .L5 - - mov cs:[_fat_secshift], ax - dec cx - -; mov cs:[_fat_sector], cx -; mov cs:[_fat_sector + 2], cx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Set our next cluster. + ;; stack pointer to 2048. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, offset _nextcluster_fat32 - mov cs:[_next_cluster], ax + mov sp, HEX (0800) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Set our convert cluster. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, offset _convert_cluster32 - mov cs:[_convert_cluster], ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Jump to our main code. + ;; Jump to out main code. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; jmp _real_start -_not_fat32: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Disable interrupts and clear the direction flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cli - cld - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Save the value that's in the extra segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov bx, es - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the extra segment with the code segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs - mov es, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the offset of our _fat_bpb in the di register (where we want to - ;; copy the BPB to). - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov di, offset _fat_bpb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the data segment with the stack segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, ss - mov ds, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Load the address of the base pointer minus 64 (start of the BPB). - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - lea si, [bp - 64] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Copy the BPB to our _fat_bpb offset - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 25 - rep movsb - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the data segment with the code segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs - mov ds, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Save the drive no. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov [_drive_no], dl - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Copy some other variables. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, HEX (3C) - mov [_fat_jump + 1], al - - mov ax, word ptr [bp - 28] - mov [_edd_available], ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the stack segment with the value stored in bx. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ss, bx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; We should only need a little room for the stack so set the - ;; stack pointer to 512. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov sp, HEX (0200) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the next cluster FAT type. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push ax - push bx - push cx - push dx - push si - push di - - mov al, [_sectors_per_cluster] - cbw - mov si, ax - - mov di, [_bytes_per_sector] - - xor dx, dx - xor cx, cx - - mov ax, [_total_sectors16] - and ax, ax - jnz .L1 - - mov ax, [_total_sectors32] - mov dx, [_total_sectors32 + 2] - -.L1: - - sub ax, [_reserved_sectors] - sbb dx, 0 - - mov cl, [_number_of_fats] - -.L2: - - sub ax, [_sectors_per_fat] - sbb dx, 0 - loop .L2 - - push ax - push dx - - mov ax, [_root_entries] - mov bx, 32 - mul bx - - add ax, di - adc dx, 0 - - sub ax, 1 - sbb dx, 0 - - div di - mov bx, ax - - pop dx - pop ax - - sub ax, bx - sbb dx, 0 - - div si - - cmp ax, 4096 - ja .L3 - - mov ax, offset _nextcluster_fat12 - mov cs:[_next_cluster], ax - - mov ax, offset _convert_cluster12 - mov cs:[_convert_cluster], ax - - jmp short .L4 - -.L3: - - mov ax, offset _nextcluster_fat16 - mov cs:[_next_cluster], ax - - mov ax, offset _convert_cluster16 - mov cs:[_convert_cluster], ax - -.L4: - - xor ax, ax - xor dx, dx - - mov si, [_hidden_sectors] - mov di, [_hidden_sectors + 2] - - add si, [_reserved_sectors] - adc di, 0 - - mov [_fat_start], si - mov [_fat_start + 2], di - - mov al, [_number_of_fats] - cbw - mul word ptr [_sectors_per_fat] - - add si, ax - adc di, dx - - mov [_root_start], si - mov [_root_start + 2], di - - mov ax, 32 - mul word ptr [_root_entries] - div word ptr [_bytes_per_sector] - - add si, ax - adc si, dx - - mov [_data_start], si - mov [_data_start + 2], di - - pop di - pop si - pop dx - pop cx - pop bx - pop ax - - jmp _real_start - ;****************************************************************************** ; @function _restore_and_jump ;****************************************************************************** @@ -499,41 +202,87 @@ _clear_kbd.done: ret ;****************************************************************************** -; @function _int19_handler +; @function _reboot_handler ;****************************************************************************** -_int19_handler: +_reboot_handler: + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Disable interrupts and clear the direction flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cli cld + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push ds + push si + push di + push ax + push cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the data and extra segments with the code segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax, cs mov ds, ax - xor ax, ax - mov es, ax - + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Setup si and bx to point to our list and list end. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov si, offset _interrupts_list mov bx, offset _interrupts_list_end - cli + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the extra segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + mov es, ax -_int19_handler.next: +_reboot_handler.loop: + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we're not at the end of our interrupts list. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cmp si, bx - je _int19_handler.done + je _reboot_handler.done + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Load a byte from DS:SI to the al register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; lodsb + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the value into the DI register and multiple by 4 to get the + ;; correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov di, ax shl di shl di + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the value of DS:SI to ES:DI twice. + ;; + ;; Note: This will increment both the SI and DI registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; movsw movsw - jmp short _int19_handler.next + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Loop back for the next entry (if there is one). + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jmp short _reboot_handler.loop -_int19_handler.done: +_reboot_handler.done: + pop cx + pop ax + pop di + pop si + pop ds + pop es + int HEX (19) ;****************************************************************************** @@ -542,186 +291,502 @@ _int19_handler.done: _real_start: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Re-enable interrupts. + ;; Make sure that the keyboard buffer is cleared. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _clear_kbd + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the screen size. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _adjust_screen + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure the data segment is initialized to the code segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;mov ax, cs + ;mov ds, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; First we'll move the value in the stack pointer into the ax register + ;; and clear the dx register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, sp + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get the segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Do we have any left over bytes (size % 16). + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Nope, so we got the right segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jz .L8 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Yep, we have linguring bytes so increase the segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + inc ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the zero flag is set then we have overflowed + ;; (greater than 65535 bytes) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jnz .L8 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Just for good measure set the data segment to the code segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs + mov ds, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Print an error. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _error + db "segment overflow", HEX (0D), HEX (0A), HEX (00) + +.L8: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Now that we have the amount of segments that the stack pointer takes + ;; up we need to add the stack segment to get the first available segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, ss + add ax, bx + + mov [_free_seg], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the total memory (in KBs) and convert it to paragrahps for the + ;; maximum segment value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + int HEX (12) + + mov cl, 6 + shl ax, cl + + mov [_max_seg], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the di register with our free segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov di, [_free_seg] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the ax register ready for stosw. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + +_clear_memory: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If we've reached out max segment then we've cleared all our + ;; free memory. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp di, [_max_seg] + je _check_disks + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve some registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push cx + push di + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the extra segment with the value in the di register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the di register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor di, di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We'll be clearing 128 words (i.e 128 * 2) at a time. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 128 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the value in the ax register into es:di unitl cx is zero. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + rep stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore our registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop di + pop cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add 16 to get the next segment. + ;; + ;; E.g. (0050:00ff -> 0x05ff) + 1 = 0060:0000 -> 0x0600. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add di, 16 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Loop back to the clear the segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jmp short _clear_memory + +_check_disks: + + mov cx, 2 + +.L1: + + and cx, cx + jz .L2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; The very first thing we do is allocate at least 1 disk for use + ;; with floppies. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, HEX (80) + push ax + + xor ax, ax + push ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Try to allocate memory, this should never return if it fails. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _xmalloc + add sp, 4 + + mov es, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Push the address to the vector. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ax + + mov ax, offset _vec_parts + push ax + + call _vec_push + add sp, 4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We'll start adding info to the segment starting at 0. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor di, di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; First, thing we need is a place to store the current directory. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, 65 + push ax + + xor ax, ax + push ax + + call _xmalloc + add sp, 4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the value. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - sti + stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Make sure that the keyboard buffer is cleared. + ;; Start in the root of the disk. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - call _clear_kbd + xor ax, ax + stosw + stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Convert the sectors per cluster to a word. + ;; We need a scratch buffer for the disk so allocate one. + ;; + ;; Floppies are typically 512 bytes per sector and there's + ;; usually no more than 2 sectors per cluster so + ;; allocating 1024 (2 sectors) should be fine. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, [_sectors_per_cluster] - cbw - mov [_secsperclust], ax + mov ax, 1024 + push ax + + xor ax, ax + push ax + + call _xmalloc + add sp, 4 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; How big is a cluster, really? + ;; Store the value. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mul word ptr [_bytes_per_sector] - mov [_clustsize], ax + stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the screen size. + ;; Decrement cx and loop back for next drive. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - call _adjust_screen + dec cx + jnz .L1 -_setup_malloc: +.L2: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; First we'll move the value in the stack pointer into the ax register - ;; and clear the dx register. + ;; Zero out ah and put the drive number in al. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, sp - xor dx, dx + xor ah, ah + mov al, cs:[_drive_no] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Divide by 16 to get the segment. + ;; Are we booted from a floppy or hard disk? ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 16 - div cx + test al, HEX (80) + jnz .L6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Do we have any left over bytes (size % 16). + ;; Set the selected disk as the drive number. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - and dx, dx + mov cs:[_selected_disk], ax + inc word ptr cs:[_selected_disk] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Nope, so we got the right segment. + ;; Okay, we are booted from a floppy so we need to figure out which + ;; address it is within our _Vec_parts "structure". ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - jz _segment_ok + xor dx, dx + + mov cx, 2 + mul cx + + mov bx, ax + + mov ax, cs:[_vec_parts] + mov es, ax + + mov ax, es:[bx] + mov es, ax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Yep, we have linguring bytes so increase the segment. + ;; Try and read the drive. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - inc ax + push es + + mov ax, ss + mov es, ax + xor bx, bx + + mov ax, HEX (0201) + mov cx, HEX (0001) + xor dh, dh + mov dl, cs:[_drive_no] + stc + int HEX (13) + pop es + jnc .L3 + + call _error + db "panic: failed to read boot drive", HEX (0D), HEX (0A), HEX (00) + +.L3: + + cmp byte ptr ss:[bx + 0], HEX (EB) + jne .L14 + cmp byte ptr ss:[bx + 2], HEX (90) + jne .L14 + + jmp .L15 + +.L14: + + call _error + db "panic: seleteced disk does not have a valid/supported parition", HEX (0D), HEX (0A), HEX (00) + +.L15: + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; If the zero flag is set then we have overflowed - ;; (greater than 65535 bytes) + ;; Copy the BPB to our "structure". ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - jnz _segment_ok + push ds + + mov ax, ss + mov ds, ax + + mov si, bx + add si, 11 + + mov cx, 25 + rep movsb + + pop ds ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Just for good measure set the data segment to the code segment. + ;; Store the drive number. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs - mov ds, ax + mov al, cs:[_drive_no] + stosb ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print an error. + ;; Floppies should be FAT12 so pad with zeros. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - call _error - db "segment overflow", HEX (0D), HEX (0A), HEX (00) - -_segment_ok: - + xor ax, ax + stosw + stosw + + xor dx, dx + push di + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Now that we have the amount of segments that the stack pointer takes - ;; up we need to add the stack segment to get the first available segment. + ;; Calculate the offset of the first FAT. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov bx, ss - add ax, bx + mov si, ss:[bx + 28] + mov di, ss:[bx + 30] - mov [_free_seg], ax + add si, ss:[bx + 14] + adc di, 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the total memory (in KBs) and convert it to paragrahps for the - ;; maximum segment value. + ;; Move the value in di to dx and restore di. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - int HEX (12) + mov cx, di + pop di - mov cl, 6 - shl ax, cl + push ax - mov [_max_seg], ax + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the offset for later use. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, si + stosw + + mov ax, cx + stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the di register with our free segment. + ;; Repush di and reset the di register. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov di, [_free_seg] + pop ax + + push di + mov di, cx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out the ax register ready for stosw. + ;; Calculate how many sectors both FATs require. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - -_clear_memory: - + mov al, ss:[bx + 16] + cbw + mul word ptr ss:[bx + 22] + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; If we've reached out max segment then we've cleared all our - ;; free memory. + ;; Adjust the FAT offset to get the root directory offset. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cmp di, [_max_seg] - je _setup_interrupts + add si, ax + adc di, dx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve some registers. + ;; Move the value in di to dx and restore di. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push cx - push di - push es + mov cx, di + pop di + + push ax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the extra segment with the value in the di register. + ;; Save the offset for later use. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov es, di + mov ax, si + stosw + + mov ax, cx + stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out the di register. + ;; Repush di and reset the di register. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor di, di + pop ax + + push di + mov di, cx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; We'll be clearing 128 words (i.e 128 * 2) at a time. + ;; Calculate how many sectors the root directory requires. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 128 + mov ax, HEX (0020) + mul word ptr ss:[bx + 17] + div word ptr ss:[bx + 11] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the value in the ax register into es:di unitl cx is zero. + ;; Adjust the root offset to get the data offset. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - rep stosw + add si, ax + adc di, dx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore our registers. + ;; Move the value in di to dx and restore di. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop es + mov dx, di pop di - pop cx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Add 16 to get the next segment. - ;; - ;; E.g. (0050:00ff -> 0x05ff) + 1 = 0060:0000 -> 0x0600. + ;; Save the offset for later use. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - add di, 16 + mov ax, si + stosw + + mov ax, dx + stosw ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Loop back to the clear the segment. + ;; Floppies shouldn't have a sector mask or shift. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - jmp short _clear_memory + xor ax, ax + stosw + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Figure out how big a cluster is. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, ss:[bx + 11] + xor dx, dx + + xor ch, ch + mov cl, ss:[bx + 13] + + mul cx + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; No info sector. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + stosw -_setup_interrupts: +.L6: + + call _get_hard_disk_partitions + +.L7: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers. + ;; Reserve 1024 bytes for a fat segment. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, 1024 push ax - push bx - push dx - push si - push di - push es - push ds - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Disable interrupts while we set everything up. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cli + xor ax, ax + push ax + + call _xmalloc + add sp, 4 + mov cs:[_fat_seg], ax + +_setup_interrupts: + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setup si and bx to point to our list and list end. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -734,13 +799,13 @@ _setup_interrupts: xor ax, ax mov es, ax -.L6: +.L4: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Make sure we're not at the end of our interrupts list. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cmp si, bx - je .L7 + je .L5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Load a byte from DS:SI to the al register. @@ -795,9 +860,9 @@ _setup_interrupts: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Loop back for the next entry (if there is one). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - jmp short .L6 + jmp short .L4 -.L7: +.L5: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Re-enable interrupts. @@ -805,42 +870,37 @@ _setup_interrupts: sti ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. + ;; Make sure the data segment is actually initialized to the + ;; code segment. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop ds - pop es - pop di - pop si - pop dx - pop bx - pop ax - -_reserve_fat: - - mov ax, [_bytes_per_sector] - shl ax - xor dx, dx + mov ax, cs + mov ds, ax - push ax - push dx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We also want to make sure the extra segment is initialized to the + ;; code segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax - call _xmalloc - add sp, 4 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp - mov [_fat_seg], ax - -_reserve_scratch: - - mov ax, [_bytes_per_sector] + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out all other registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor si, si + xor di, di + xor ax, ax + xor bx, bx + xor cx, cx xor dx, dx - push ax - push dx - - call _xmalloc - add sp, 4 - - mov [_disk_scratch], ax + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Decrement the selected disk by 1. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + dec word ptr cs:[_selected_disk] _main: @@ -935,12 +995,12 @@ _config_ok: mov cx, cs:[_menu_entries + 4] and cx, cx - jnz .L8 + jnz .L11 call _error db "error: no entries found in config file", HEX (0D), HEX (0A), HEX (00) -.L8: +.L11: call _run_menu @@ -1279,13 +1339,13 @@ _segment_ok2: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Copy the jump. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs:[_fat_jump + 0] + mov al, cs:[_fat_jump + 0] stosb - mov ax, cs:[_fat_jump + 1] + mov al, cs:[_fat_jump + 1] stosb - mov ax, cs:[_fat_jump + 2] + mov al, cs:[_fat_jump + 2] stosb ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1371,12 +1431,16 @@ _freeldr_cfg3: db "/freeldr.cfg", HEX (00) _interrupts_list: - db HEX (19) - dw _int19_handler - dw HEX (0000) + db DIVIDE_VECTOR + dw _divide_handler, HEX (0000) + + db INVALID_VECTOR + dw _invalid_handler, HEX (0000) + + db REBOOT_VECTOR + dw _reboot_handler, HEX (0000) - db HEX (21) - dw _int21_dispatch - dw HEX (0000) + db INT21_VECTOR + dw _int21_dispatch, HEX (0000) _interrupts_list_end: diff --git a/src/boot/freeldr/core/int21.asm b/src/boot/freeldr/core/int21.asm index 0e5c2c6..4259003 100644 --- a/src/boot/freeldr/core/int21.asm +++ b/src/boot/freeldr/core/int21.asm @@ -5,6 +5,450 @@ % define HEX(y) 0x##y %endif +;****************************************************************************** +; @function _get_disk_info +;****************************************************************************** +_get_disk_info: + + push bp + + mov bp, sp + sub sp, 2 + + push ax + push bx + push cx + push dx + push di + push es + push ds + + mov ax, cs:[_selected_disk] + mov word ptr [bp - 2], ax + +_get_disk_info.check: + + push si + + call _strlen + add sp, 2 + + cmp ax, 2 + jb _get_disk_info.got_disk + + cmp byte ptr [si + 1], ':' + jne _get_disk_info.got_disk + + xor ah, ah + mov al, [si] + + push ax + + call _isalpha + mov cx, ax + + pop ax + + and cx, cx + jz _get_disk_info.got_disk + + add si, 2 + push ax + + call _toupper + add sp, 2 + + sub al, HEX (41) + + cmp ax, cs:[_selected_disk] + je _get_disk_info.got_disk + + mov word ptr [bp - 2], ax + inc ax + + cmp cs:[_vec_parts + 4], ax + jb _get_disk_info.error + + dec ax + + cmp ax, 2 + jae _get_disk_info.got_disk + + call _probe_disk + jc _get_disk_info.error + +_get_disk_info.got_disk: + + mov ax, word ptr [bp - 2] + xor dx, dx + + mov cx, 2 + mul cx + + mov bx, ax + + mov ax, cs:[_vec_parts] + mov es, ax + + mov ax, es:[bx] + +_get_disk_info.copy: + + push si + push ds + + xor si, si + mov ds, ax + + lodsw + + lodsw + mov cs:[_sectors_per_fat32], ax + + lodsw + mov cs:[_sectors_per_fat32 + 2], ax + + lodsw + mov cs:[_disk_scratch], ax + + mov di, offset _fat_bpb + push es + + mov ax, cs + mov es, ax + + mov cx, 25 + rep movsb + + pop es + + lodsb + mov cs:[_drive_no], al + + lodsw + mov cs:[_root_cluster], ax + + lodsw + mov cs:[_root_cluster + 2], ax + + lodsw + mov cs:[_fat_start], ax + + lodsw + mov cs:[_fat_start + 2], ax + + lodsw + mov cs:[_root_start], ax + + lodsw + mov cs:[_root_start + 2], ax + + lodsw + mov cs:[_data_start], ax + + lodsw + mov cs:[_data_start + 2], ax + + lodsw + mov cs:[_fat_secmask], ax + + lodsw + mov cs:[_fat_secshift], ax + + lodsw + mov cs:[_clustsize], ax + + pop ds + pop si + + mov bx, cs:[_root_cluster] + mov cx, cs:[_root_cluster + 2] + + or bx, cx + + and bx, bx + jnz _get_disk_info.fat32 + + call _getfattype + jmp _get_disk_info.done + +_get_disk_info.fat32: + + mov ax, offset _convert_cluster32 + mov cs:[_convert_cluster], ax + + mov ax, offset _nextcluster_fat32 + mov cs:[_next_cluster], ax + +_get_disk_info.done: + + mov word ptr cs:[_fat_sector], 0 + mov word ptr cs:[_fat_sector + 2], 0 + + pop ds + pop es + pop di + pop dx + pop cx + pop bx + pop ax + + add sp, 2 + clc + + pop bp + ret + +_get_disk_info.error: + + pop ds + pop es + pop di + pop dx + pop cx + pop bx + pop ax + + add sp, 2 + stc + + pop bp + ret + +;****************************************************************************** +; @function _probe_disk +;****************************************************************************** +_probe_disk: + + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + + mov dx, ax + +_probe_disk.read: + + push dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Okay, we are booted from a floppy so we need to figure out which + ;; address it is within our _Vec_parts "structure". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor dx, dx + + mov cx, 2 + mul cx + + mov bx, ax + + mov ax, cs:[_vec_parts] + mov es, ax + + mov ax, es:[bx] + mov es, ax + + pop dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Try and read the drive. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + + mov ax, es:[HEX (0006)] + mov es, ax + xor bx, bx + + mov ax, HEX (0201) + mov cx, HEX (0001) + stc + int HEX (13) + pop es + jc _probe_disk.error + + mov ax, es:[HEX (0006)] + mov ds, ax + +_probe_disk.check: + + cmp byte ptr [HEX (0000)], HEX (EB) + jne _probe_disk.error + + cmp byte ptr [HEX (0002)], HEX (90) + jne _probe_disk.error + +_probe_disk.calc: + + mov di, 8 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Next we'll copy the BPB to our "structure". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, bx + add si, 11 + + mov cx, 25 + rep movsb + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the drive number. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov al, dl + stosb + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Floppies should be FAT12 so pad with zeros. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + stosw + stosw + + xor dx, dx + push di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the offset of the first FAT. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, [HEX (001C)] + mov di, [HEX (001E)] + + add si, [HEX (000E)] + adc di, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the value in di to dx and restore di. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, di + pop di + + push ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the offset for later use. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, si + stosw + + mov ax, cx + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Repush di and reset the di register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop ax + + push di + mov di, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate how many sectors both FATs require. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov al, [HEX (0010)] + cbw + mul word ptr [HEX (0016)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Adjust the FAT offset to get the root directory offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add si, ax + adc di, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the value in di to dx and restore di. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, di + pop di + + push ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the offset for later use. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, si + stosw + + mov ax, cx + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Repush di and reset the di register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop ax + + push di + mov di, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate how many sectors the root directory requires. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, HEX (0020) + mul word ptr [HEX (0011)] + div word ptr [HEX (000B)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Adjust the root offset to get the data offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add si, ax + adc di, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the value in di to dx and restore di. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dx, di + pop di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the offset for later use. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, si + stosw + + mov ax, dx + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Floppies shouldn't have a sector mask or shift. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + stosw + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Figure out how big a cluster is. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, [HEX (000B)] + xor dx, dx + + xor ch, ch + mov cl, [HEX (000D)] + + mul cx + stosw + + clc + jmp _probe_disk.done + +_probe_disk.error: + + stc + +_probe_disk.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + + ;****************************************************************************** ; @function _int21_dispatch ;****************************************************************************** @@ -111,37 +555,19 @@ _int21_dispatch.list: ;; Open File Using Handle. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; db HEX (3D) - dw int21_3D + dw _int21_3D ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Close File Using Handle. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; db HEX (3E) - dw int21_3E + dw _int21_3E ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Read From File or Device Using Handle. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; db HEX (3F) - dw int21_3F - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Allocate Memory Blocks. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - db HEX (48) - dw int21_48 - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Free Allocated Memory Blocks. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - db HEX (49) - dw int21_49 - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Modify Allocated Memory Blocks. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - db HEX (4A) - dw int21_4A + dw _int21_3F _int21_dispatch.list_end: @@ -169,7 +595,7 @@ iretc.ret: ;****************************************************************************** -; @function int21_3D +; @function _int21_3D ; @brief Open File Using Handle ; ; @in AL -> Open access mode. @@ -177,25 +603,64 @@ iretc.ret: ; ; @out AX -> File handle. Error code if CF is set. ;****************************************************************************** -int21_3D: +_int21_3D: + + push bp + push bx + push cx + push dx + push si + push di + push es + push ds + + xor bh, bh + mov bl, al + + mov si, dx + + call _get_disk_info + jc _int21_3D.error + + mov di, si + +_int21_3D.open: call _open_file + jmp _int21_3D.done + +_int21_3D.error: + + mov ax, 3 + stc + +_int21_3D.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop bp + jmp iretc ;****************************************************************************** -; @function int21_3E +; @function _int21_3E ; @brief Close File Using Handle ; ; @in BX -> File handle to close.. ; @out AX -> Clear. Error code if CF is set. ;****************************************************************************** -int21_3E: +_int21_3E: call _close_file jmp iretc ;****************************************************************************** -; @function int21_3F +; @function _int21_3F ; @brief Read From File or Device Using Handle ; ; @in BX -> File handle.. @@ -204,52 +669,180 @@ int21_3E: ; ; @out AX -> Number of bytes read. Error code if CF is set. ;****************************************************************************** -int21_3F: +_int21_3F: - call _read_file - jmp iretc + push bp + push bx + push cx + push dx + push si + push di + push es + push ds + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Check if we have any open files. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp word ptr cs:[_vec_files + 2], 0 + je _int21_3F.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we have a valid file handle. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp bx, 3 + jb _int21_3F.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the correct file offset by subtracting 3. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + sub bx, 3 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the offset into our vector. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push dx + push cx + + mov ax, bx + xor dx, dx + + mov cx, 2 + mul cx + + mov bx, ax + pop cx + pop dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Intialize the es register with address of our vector entries + ;; and zero out bx for the counter. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs:[_vec_files + 0] + mov es, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the vector entry is zero then the file handle is invalid. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp word ptr es:[bx], 0 + je _int21_3F.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Re-initialize the extra segment but this time with the address + ;; of the vector entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] -;****************************************************************************** -; @function int21_48 -; @brief Allocate Memory Blocks -; -; @in BX -> Number of memory paragraphs requested. -; -; @out AX -> Segment address of allocated memory block -; (MCB + lpara). Error code if CF is set. -; @out BX -> Size in paras of the largets block of memory -; available if CF is set and AX = 08 (Not enough mem). -;****************************************************************************** -int21_48: +_int21_3F.copy: - call _alloc_mem - jmp iretc + push si + push ds + push ax + push cx + + mov ds, ax + xor si, si + + lodsw + mov cs:[_sectors_per_fat32], ax + + lodsw + mov cs:[_sectors_per_fat32 + 2], ax + + mov di, offset _fat_bpb + mov ax, cs + mov es, ax + + mov cx, 25 + rep movsb + + lodsb + mov cs:[_drive_no], al + + lodsw + mov cs:[_root_cluster], ax + + lodsw + mov cs:[_root_cluster + 2], ax + + lodsw + mov cs:[_fat_start], ax + + lodsw + mov cs:[_fat_start + 2], ax + + lodsw + mov cs:[_root_start], ax + + lodsw + mov cs:[_root_start + 2], ax + + lodsw + mov cs:[_data_start], ax + + lodsw + mov cs:[_data_start + 2], ax + + lodsw + mov cs:[_fat_secmask], ax + + lodsw + mov cs:[_fat_secshift], ax + + lodsw + mov cs:[_clustsize], ax + + lodsw + ;mov cs:[_info_sector], ax + + mov bx, cs:[_root_cluster] + mov cx, cs:[_root_cluster + 2] + + or bx, cx + + and bx, bx + jnz _int21_3F.fat32 + + call _getfattype + jmp _int21_3F.read -;****************************************************************************** -; @function int21_49 -; @brief Free Allocated Memeory Blocks -; -; @in ES -> Segment of the block to be returned (MCB + lpara). -; @out AX -> Clear. -;****************************************************************************** -int21_49: +_int21_3F.fat32: - call _free_mem - jmp iretc + mov ax, offset _convert_cluster32 + mov cs:[_convert_cluster], ax + + mov ax, offset _nextcluster_fat32 + mov cs:[_next_cluster], ax -;****************************************************************************** -; @function int21_4A -; @brief Resize Allocated Memory Blocks -; -; @in BX -> New requested block size in paragraphs. -; @in ES -> Segment of block to resize. -; -; @out AX -> Segment address of memory block (MCB + lpara). -; Error code if CF is set. -; @out BX -> Set to maximum block size possible if the request -; block size is greater than what available. -;****************************************************************************** -int21_4A: +_int21_3F.read: + + mov word ptr cs:[_fat_sector], 0 + mov word ptr cs:[_fat_sector + 2], 0 + + pop cx + pop ax + pop ds + pop si + mov es, ax + + xor si, si + call _read_file + + jmp _int21_3F.done + +_int21_3F.error: + + mov ax, 6 + stc - call _resize_mem +_int21_3F.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop bp + jmp iretc diff --git a/src/boot/freeldr/core/invalid.asm b/src/boot/freeldr/core/invalid.asm new file mode 100644 index 0000000..cbe419f --- /dev/null +++ b/src/boot/freeldr/core/invalid.asm @@ -0,0 +1,125 @@ +;****************************************************************************** +; @file invalid.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _invalid_handler +;****************************************************************************** +global _invalid_handler +_invalid_handler: + + push bp + mov bp, sp + + push ax + push bx + +_invalid_handler.clear: + + mov ax, HEX (0600) + mov bh, HEX (1F) + xor cx, cx + mov dx, HEX (1850) + int HEX (10) + + mov ah, HEX (02) + xor bh, bh + xor dx, dx + int HEX (10) + + jmp _invalid_handler.init + +_invalid_handler.no_clear: + + call _crlf + +_invalid_handler.init: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure the data segment is the dame as the code segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs + mov ds, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Print our first message. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, offset _invalid_handler.msg + call _writestr + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Print a newline. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _crlf + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the si register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor si, si + +_invalid_handler.loop: + + cmp si, 12 * 2 + jae _invalid_handler.done + + mov ax, si + xor dx, dx + + mov cx, 12 + div cx + + and dx, dx + jnz _invalid_handler.print + + call _crlf + + mov al, ' ' + call _writechr + call _writechr + call _writechr + call _writechr + +_invalid_handler.print: + + mov ax, word ptr [bp + si] + call _writehex + + inc si + inc si + + mov ax, si + xor dx, dx + + mov cx, 12 + div cx + + and dx, dx + jz _invalid_handler.loop + + mov al, ' ' + call _writechr + call _writechr + call _writechr + call _writechr + + jmp _invalid_handler.loop + +_invalid_handler.done: + + call _crlf + call _crlf + +_invalid_handler.reboot: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Call error with our ending message. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _error + db "Press any key to reboot...", HEX (00) + +_invalid_handler.msg: + + db "Trap to vector 6: Invalid opcode", HEX (00) diff --git a/src/boot/freeldr/core/xmalloc.asm b/src/boot/freeldr/core/xmalloc.asm index cb56c1e..9734782 100644 --- a/src/boot/freeldr/core/xmalloc.asm +++ b/src/boot/freeldr/core/xmalloc.asm @@ -30,14 +30,30 @@ _xmalloc: mov dx, [bp + 4] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Call malloc. + ;; Convert the size to paragraphs. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push ax - push dx + mov cx, 16 + div cx - call _malloc - add sp, 4 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If dx is non-zero then try to increase the count. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp dx, 0 + je _xmalloc.ok + +_xmalloc.inc: + + inc ax + jz _xmalloc.error + +_xmalloc.ok: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Try and allocate the memory. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, ax + call _alloc_mem jc _xmalloc.error push ax @@ -115,4 +131,4 @@ _xmalloc.error: ;; so just error out. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; call _error - db "Memory full (malloc)", HEX (0D), HEX (0A), HEX (00) + db "panic: failed to alloc memory in xmalloc", HEX (0D), HEX (0A), HEX (00) diff --git a/src/boot/freeldr/core/xrealloc.asm b/src/boot/freeldr/core/xrealloc.asm index 1443176..4785504 100644 --- a/src/boot/freeldr/core/xrealloc.asm +++ b/src/boot/freeldr/core/xrealloc.asm @@ -29,21 +29,159 @@ _xrealloc: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax, [bp + 8] mov dx, [bp + 6] - mov si, [bp + 4] + mov bx, [bp + 4] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Call realloc. + ;; Make sure we have valid memory as a pointer. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push ax - push dx - push si + and bx, bx + jz _xrealloc.calc + + mov di, bx + dec di + mov es, di + + xor di, di - call _realloc - add sp, 6 + cmp byte ptr es:[di], 'M' + jne _xrealloc.error - and ax, ax + cmp byte ptr es:[di + 1], 'C' + jne _xrealloc.error + + cmp byte ptr es:[di + 2], 'B' + jne _xrealloc.error + +_xrealloc.calc: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; The ax and dx registers should be setup with the size we want + ;; to allocate so convert it to paragraphs. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If dx is non-zero then try to increase the count. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp dx, 0 + je _xrealloc.ok + +_xrealloc.inc: + + inc ax jz _xrealloc.error +_xrealloc.ok: + + mov si, ax + + and bx, bx + jz _xrealloc.alloc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; First. lets try and resize the memory block. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push es + + mov es, bx + mov bx, si + call _resize_mem + + pop es + pop bx + jnc _xrealloc.done + +_xrealloc.alloc: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Try and allocate the memory. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + + mov bx, si + call _alloc_mem + + pop bx + jc _xrealloc.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Only copy existing data if there was an original pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov di, bx + + and di, di + jz _xrealloc.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers that copy will clobber. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push si + push ds + + mov di, bx + mov ds, di + + dec di + + mov es, di + xor di, di + + mov cx, word ptr es:[di + 3] + mov es, ax + + cmp cx, bx + jb _xrealloc.copy + + mov cx, bx + +_xrealloc.copy: + + xor si, si + xor di, di + + push cx + + mov cx, 16 + rep movsb + + pop cx + + mov si, es + inc si + mov es, si + + mov di, ds + inc di + mov ds, di + + loop _xrealloc.copy + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers that copy clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop ds + pop si + +_xrealloc.free: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the new pointer; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If we reached this point then free the original pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, bx + call _free_mem + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the new pointer; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop ax + _xrealloc.done: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -91,4 +229,4 @@ _xrealloc.error: ;; so just error out. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; call _error - db "Memory full (realloc)", HEX (0D), HEX (0A), HEX (00) + db "panic: failed to alloc memory in krealloc", HEX (0D), HEX (0A), HEX (00) diff --git a/src/boot/freeldr/freeldr.cfg b/src/boot/freeldr/freeldr.cfg index 2cf568e..ee79cff 100644 --- a/src/boot/freeldr/freeldr.cfg +++ b/src/boot/freeldr/freeldr.cfg @@ -1,6 +1,5 @@ default chimaera -#timeout 10 -timeout 0 +timeout 10 label chimaera title Chimaera OS diff --git a/src/boot/freeldr/lib/Makefile.unix b/src/boot/freeldr/lib/Makefile.unix new file mode 100644 index 0000000..a477ba8 --- /dev/null +++ b/src/boot/freeldr/lib/Makefile.unix @@ -0,0 +1,20 @@ +#****************************************************************************** +# @file Makefile.unix +#****************************************************************************** +TARGETS := crt + +OBJDIR ?= $(CURDIR) +SRCDIR ?= $(CURDIR) + +all: + for d in $(TARGETS); do \ + if [ ! -d "$(OBJDIR)/$$d" ]; then mkdir -p "$(OBJDIR)/$$d"; fi; \ + $(MAKE) -C "$(OBJDIR)/$$d" -f "$(SRCDIR)/$$d/Makefile.unix" OBJDIR="$(OBJDIR)/$$d" SRCDIR="$(SRCDIR)/$$d" all; \ + done + +clean: + for d in $(TARGETS); do \ + if [ -d "$(OBJDIR)/$$d" ]; then \ + $(MAKE) -C "$(OBJDIR)/$$d" -f "$(SRCDIR)/$$d/Makefile.unix" OBJDIR="$(OBJDIR)/$$d" SRCDIR="$(SRCDIR)/$$d" clean; \ + fi; \ + done diff --git a/src/boot/freeldr/lib/Makefile.w32 b/src/boot/freeldr/lib/Makefile.w32 new file mode 100644 index 0000000..08f1adf --- /dev/null +++ b/src/boot/freeldr/lib/Makefile.w32 @@ -0,0 +1,20 @@ +#****************************************************************************** +# @file Makefile.w32 +#****************************************************************************** +TARGETS := crt + +OBJDIR ?= $(CURDIR) +SRCDIR ?= $(CURDIR) + +all: + for %%d in ($(TARGETS)) do ( \ + ( if not exist "$(OBJDIR)/%%d" ( mkdir "$(OBJDIR)/%%d" ) ) & \ + $(MAKE) -C "$(OBJDIR)/%%d" -f "$(SRCDIR)/%%d/Makefile.w32" OBJDIR="$(OBJDIR)/%%d" SRCDIR="$(SRCDIR)/%%d" all \ + ) + +clean: + for %%d in ($(TARGETS)) do ( \ + if exist "$(OBJDIR)/%%d" ( \ + $(MAKE) -C "$(OBJDIR)/%%d" -f "$(SRCDIR)/%%d/Makefile.w32" OBJDIR="$(OBJDIR)/%%d" SRCDIR="$(SRCDIR)/%%d" clean \ + ) \ + ) diff --git a/src/boot/freeldr/lib/crt/Makefile.unix b/src/boot/freeldr/lib/crt/Makefile.unix new file mode 100644 index 0000000..5617cda --- /dev/null +++ b/src/boot/freeldr/lib/crt/Makefile.unix @@ -0,0 +1,25 @@ +#****************************************************************************** +# @file Makefile.unix +#****************************************************************************** +OBJDIR ?= $(CURDIR) +SRCDIR ?= $(CURDIR) + +VPATH := $(SRCDIR) + +ASMSRC := $(shell find "$(SRCDIR)" -type f -name '*.asm' ! -name 'crt0*') +ASMOBJ := $(patsubst $(SRCDIR)/%, %, $(ASMSRC:.asm=.o)) + +all: libc.a + +clean: + for f in `find . -name '*.o'`; do if [ -f $$f ]; then rm -rf $$f; fi; done + for f in `find . -name '*.lst'`; do if [ -f $$f ]; then rm -rf $$f; fi; done + if [ -f libc.a ]; then rm -rf libc.a; fi + +libc.a: $(ASMOBJ) + ../../../../utils/binutils/sar r $@ $^ + ../../../../utils/binutils/sar s $@ + +%.o: %.asm + if [ ! -d $(patsubst %/, %, $(dir $@)) ]; then mkdir -p $(patsubst %/, %, $(dir $@)); fi + ../../../../utils/binutils/sasm -I$(SRCDIR)/include -l $*.lst -o $@ $< diff --git a/src/boot/freeldr/lib/crt/Makefile.w32 b/src/boot/freeldr/lib/crt/Makefile.w32 new file mode 100644 index 0000000..bc7ba91 --- /dev/null +++ b/src/boot/freeldr/lib/crt/Makefile.w32 @@ -0,0 +1,25 @@ +#****************************************************************************** +# @file Makefile.w32 +#****************************************************************************** +OBJDIR ?= $(CURDIR) +SRCDIR ?= $(CURDIR) + +VPATH := $(SRCDIR) + +ASMSRC := $(subst \,/,$(shell dir /s /b "$(SRCDIR)\\*.asm" | find "crt0.asm" /v)) +ASMOBJ := $(patsubst $(SRCDIR)/%, %, $(ASMSRC:.asm=.o)) + +all: libc.a + +clean: + for /r %%f in (*.o) do ( if exist %%f ( del /q %%f ) ) + for /r %%f in (*.lst) do ( if exist %%f ( del /q %%f ) ) + if exist libc.a ( del /q libc.a ) + +libc.a: $(ASMOBJ) + ../../utils/binutils/sar r $@ $^ + ../../utils/binutils/sar s $@ + +%.o: %.asm + if not exist $(patsubst %/, %, $(dir $@)) ( mkdir $(patsubst %/, %, $(dir $@)) ) + ../../../utils/binutils/sasm -I$(SRCDIR)/include -l $*.lst -o $@ $< diff --git a/src/boot/freeldr/lib/crt/ctype.asm b/src/boot/freeldr/lib/crt/ctype.asm new file mode 100644 index 0000000..2bb0937 --- /dev/null +++ b/src/boot/freeldr/lib/crt/ctype.asm @@ -0,0 +1,1988 @@ +;****************************************************************************** +; @file ctype.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _isalnum +;****************************************************************************** +global _isalnum +_isalnum: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0001) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _isalpha +;****************************************************************************** +global _isalpha +_isalpha: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0002) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _iscntrl +;****************************************************************************** +global _iscntrl +_iscntrl: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0004) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _isdigit +;****************************************************************************** +global _isdigit +_isdigit: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0008) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _isgraph +;****************************************************************************** +global _isgraph +_isgraph: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0010) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _islower +;****************************************************************************** +global _islower +_islower: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0020) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _isprint +;****************************************************************************** +global _isprint +_isprint: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0040) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _ispunct +;****************************************************************************** +global _ispunct +_ispunct: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0080) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _isspace +;****************************************************************************** +global _isspace +_isspace: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0100) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _isupper +;****************************************************************************** +global _isupper +_isupper: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0200) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _isxdigit +;****************************************************************************** +global _isxdigit +_isxdigit: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __isbufR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; And the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, HEX (0400) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _tolower +;****************************************************************************** +global _tolower +_tolower: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __tolowR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;****************************************************************************** +; @function _toupper +;****************************************************************************** +global _toupper +_toupper: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the base pointer with the stack pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the ax register with the value of the stack and zero + ;; out dx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + xor dx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Multiple by two to get the correct offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 2 + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the offset of our "array". + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, offset __toupR + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add two to skip the first entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 2 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Divide by 16 to get a segment:offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, 16 + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the code segment to the value in ax to get the correct segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, cs + add ax, cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AX:DX should conatin the segment:offset of our "array" so + ;; set the extra segment to the calacaulted segment and dx to the + ;; calculated offset. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + mov bx, dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Data area. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +__isbufR: + + dw HEX (0000) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0104) + dw HEX (0104) + dw HEX (0104) + dw HEX (0104) + dw HEX (0104) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0004) + dw HEX (0140) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (0459) + dw HEX (0459) + dw HEX (0459) + dw HEX (0459) + dw HEX (0459) + dw HEX (0459) + dw HEX (0459) + dw HEX (0459) + dw HEX (0459) + dw HEX (0459) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (0653) + dw HEX (0653) + dw HEX (0653) + dw HEX (0653) + dw HEX (0653) + dw HEX (0653) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (0253) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (0473) + dw HEX (0473) + dw HEX (0473) + dw HEX (0473) + dw HEX (0473) + dw HEX (0473) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (0073) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (00D0) + dw HEX (0004) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + dw HEX (0000) + +__tolowR: + + dw HEX (FFFF) + dw HEX (0000) + dw HEX (0001) + dw HEX (0002) + dw HEX (0003) + dw HEX (0004) + dw HEX (0005) + dw HEX (0006) + dw HEX (0007) + dw HEX (0008) + dw HEX (0009) + dw HEX (000A) + dw HEX (000B) + dw HEX (000C) + dw HEX (000D) + dw HEX (000E) + dw HEX (000F) + dw HEX (0010) + dw HEX (0011) + dw HEX (0012) + dw HEX (0013) + dw HEX (0014) + dw HEX (0015) + dw HEX (0016) + dw HEX (0017) + dw HEX (0018) + dw HEX (0019) + dw HEX (001A) + dw HEX (001B) + dw HEX (001C) + dw HEX (001D) + dw HEX (001E) + dw HEX (001F) + dw HEX (0020) + dw HEX (0021) + dw HEX (0022) + dw HEX (0023) + dw HEX (0024) + dw HEX (0025) + dw HEX (0026) + dw HEX (0027) + dw HEX (0028) + dw HEX (0029) + dw HEX (002A) + dw HEX (002B) + dw HEX (002C) + dw HEX (002D) + dw HEX (002E) + dw HEX (002F) + dw HEX (0030) + dw HEX (0031) + dw HEX (0032) + dw HEX (0033) + dw HEX (0034) + dw HEX (0035) + dw HEX (0036) + dw HEX (0037) + dw HEX (0038) + dw HEX (0039) + dw HEX (003A) + dw HEX (003B) + dw HEX (003C) + dw HEX (003D) + dw HEX (003E) + dw HEX (003F) + dw HEX (0040) + dw HEX (0061) + dw HEX (0062) + dw HEX (0063) + dw HEX (0064) + dw HEX (0065) + dw HEX (0066) + dw HEX (0067) + dw HEX (0068) + dw HEX (0069) + dw HEX (006A) + dw HEX (006B) + dw HEX (006C) + dw HEX (006D) + dw HEX (006E) + dw HEX (006F) + dw HEX (0070) + dw HEX (0071) + dw HEX (0072) + dw HEX (0073) + dw HEX (0074) + dw HEX (0075) + dw HEX (0076) + dw HEX (0077) + dw HEX (0078) + dw HEX (0079) + dw HEX (007A) + dw HEX (005B) + dw HEX (005C) + dw HEX (005D) + dw HEX (005E) + dw HEX (005F) + dw HEX (0060) + dw HEX (0061) + dw HEX (0062) + dw HEX (0063) + dw HEX (0064) + dw HEX (0065) + dw HEX (0066) + dw HEX (0067) + dw HEX (0068) + dw HEX (0069) + dw HEX (006A) + dw HEX (006B) + dw HEX (006C) + dw HEX (006D) + dw HEX (006E) + dw HEX (006F) + dw HEX (0070) + dw HEX (0071) + dw HEX (0072) + dw HEX (0073) + dw HEX (0074) + dw HEX (0075) + dw HEX (0076) + dw HEX (0077) + dw HEX (0078) + dw HEX (0079) + dw HEX (007A) + dw HEX (007B) + dw HEX (007C) + dw HEX (007D) + dw HEX (007E) + dw HEX (007F) + dw HEX (0080) + dw HEX (0081) + dw HEX (0082) + dw HEX (0083) + dw HEX (0084) + dw HEX (0085) + dw HEX (0086) + dw HEX (0087) + dw HEX (0088) + dw HEX (0089) + dw HEX (008A) + dw HEX (008B) + dw HEX (008C) + dw HEX (008D) + dw HEX (008E) + dw HEX (008F) + dw HEX (0090) + dw HEX (0091) + dw HEX (0092) + dw HEX (0093) + dw HEX (0094) + dw HEX (0095) + dw HEX (0096) + dw HEX (0097) + dw HEX (0098) + dw HEX (0099) + dw HEX (009A) + dw HEX (009B) + dw HEX (009C) + dw HEX (009D) + dw HEX (009E) + dw HEX (009F) + dw HEX (00A0) + dw HEX (00A1) + dw HEX (00A2) + dw HEX (00A3) + dw HEX (00A4) + dw HEX (00A5) + dw HEX (00A6) + dw HEX (00A7) + dw HEX (00A8) + dw HEX (00A9) + dw HEX (00AA) + dw HEX (00AB) + dw HEX (00AC) + dw HEX (00AD) + dw HEX (00AE) + dw HEX (00AF) + dw HEX (00B0) + dw HEX (00B1) + dw HEX (00B2) + dw HEX (00B3) + dw HEX (00B4) + dw HEX (00B5) + dw HEX (00B6) + dw HEX (00B7) + dw HEX (00B8) + dw HEX (00B9) + dw HEX (00BA) + dw HEX (00BB) + dw HEX (00BC) + dw HEX (00BD) + dw HEX (00BE) + dw HEX (00BF) + dw HEX (00C0) + dw HEX (00C1) + dw HEX (00C2) + dw HEX (00C3) + dw HEX (00C4) + dw HEX (00C5) + dw HEX (00C6) + dw HEX (00C7) + dw HEX (00C8) + dw HEX (00C9) + dw HEX (00CA) + dw HEX (00CB) + dw HEX (00CC) + dw HEX (00CD) + dw HEX (00CE) + dw HEX (00CF) + dw HEX (00D0) + dw HEX (00D1) + dw HEX (00D2) + dw HEX (00D3) + dw HEX (00D4) + dw HEX (00D5) + dw HEX (00D6) + dw HEX (00D7) + dw HEX (00D8) + dw HEX (00D9) + dw HEX (00DA) + dw HEX (00DB) + dw HEX (00DC) + dw HEX (00DD) + dw HEX (00DE) + dw HEX (00DF) + dw HEX (00E0) + dw HEX (00E1) + dw HEX (00E2) + dw HEX (00E3) + dw HEX (00E4) + dw HEX (00E5) + dw HEX (00E6) + dw HEX (00E7) + dw HEX (00E8) + dw HEX (00E9) + dw HEX (00EA) + dw HEX (00EB) + dw HEX (00EC) + dw HEX (00ED) + dw HEX (00EE) + dw HEX (00EF) + dw HEX (00F0) + dw HEX (00F1) + dw HEX (00F2) + dw HEX (00F3) + dw HEX (00F4) + dw HEX (00F5) + dw HEX (00F6) + dw HEX (00F7) + dw HEX (00F8) + dw HEX (00F9) + dw HEX (00FA) + dw HEX (00FB) + dw HEX (00FC) + dw HEX (00FD) + dw HEX (00FE) + dw HEX (00FF) + +__toupR: + + dw HEX (FFFF) + dw HEX (0000) + dw HEX (0001) + dw HEX (0002) + dw HEX (0003) + dw HEX (0004) + dw HEX (0005) + dw HEX (0006) + dw HEX (0007) + dw HEX (0008) + dw HEX (0009) + dw HEX (000A) + dw HEX (000B) + dw HEX (000C) + dw HEX (000D) + dw HEX (000E) + dw HEX (000F) + dw HEX (0010) + dw HEX (0011) + dw HEX (0012) + dw HEX (0013) + dw HEX (0014) + dw HEX (0015) + dw HEX (0016) + dw HEX (0017) + dw HEX (0018) + dw HEX (0019) + dw HEX (001A) + dw HEX (001B) + dw HEX (001C) + dw HEX (001D) + dw HEX (001E) + dw HEX (001F) + dw HEX (0020) + dw HEX (0021) + dw HEX (0022) + dw HEX (0023) + dw HEX (0024) + dw HEX (0025) + dw HEX (0026) + dw HEX (0027) + dw HEX (0028) + dw HEX (0029) + dw HEX (002A) + dw HEX (002B) + dw HEX (002C) + dw HEX (002D) + dw HEX (002E) + dw HEX (002F) + dw HEX (0030) + dw HEX (0031) + dw HEX (0032) + dw HEX (0033) + dw HEX (0034) + dw HEX (0035) + dw HEX (0036) + dw HEX (0037) + dw HEX (0038) + dw HEX (0039) + dw HEX (003A) + dw HEX (003B) + dw HEX (003C) + dw HEX (003D) + dw HEX (003E) + dw HEX (003F) + dw HEX (0040) + dw HEX (0041) + dw HEX (0042) + dw HEX (0043) + dw HEX (0044) + dw HEX (0045) + dw HEX (0046) + dw HEX (0047) + dw HEX (0048) + dw HEX (0049) + dw HEX (004A) + dw HEX (004B) + dw HEX (004C) + dw HEX (004D) + dw HEX (004E) + dw HEX (004F) + dw HEX (0050) + dw HEX (0051) + dw HEX (0052) + dw HEX (0053) + dw HEX (0054) + dw HEX (0055) + dw HEX (0056) + dw HEX (0057) + dw HEX (0058) + dw HEX (0059) + dw HEX (005A) + dw HEX (005B) + dw HEX (005C) + dw HEX (005D) + dw HEX (005E) + dw HEX (005F) + dw HEX (0060) + dw HEX (0041) + dw HEX (0042) + dw HEX (0043) + dw HEX (0044) + dw HEX (0045) + dw HEX (0046) + dw HEX (0047) + dw HEX (0048) + dw HEX (0049) + dw HEX (004A) + dw HEX (004B) + dw HEX (004C) + dw HEX (004D) + dw HEX (004E) + dw HEX (004F) + dw HEX (0050) + dw HEX (0051) + dw HEX (0052) + dw HEX (0053) + dw HEX (0054) + dw HEX (0055) + dw HEX (0056) + dw HEX (0057) + dw HEX (0058) + dw HEX (0059) + dw HEX (005A) + dw HEX (007B) + dw HEX (007C) + dw HEX (007D) + dw HEX (007E) + dw HEX (007F) + dw HEX (0080) + dw HEX (0081) + dw HEX (0082) + dw HEX (0083) + dw HEX (0084) + dw HEX (0085) + dw HEX (0086) + dw HEX (0087) + dw HEX (0088) + dw HEX (0089) + dw HEX (008A) + dw HEX (008B) + dw HEX (008C) + dw HEX (008D) + dw HEX (008E) + dw HEX (008F) + dw HEX (0090) + dw HEX (0091) + dw HEX (0092) + dw HEX (0093) + dw HEX (0094) + dw HEX (0095) + dw HEX (0096) + dw HEX (0097) + dw HEX (0098) + dw HEX (0099) + dw HEX (009A) + dw HEX (009B) + dw HEX (009C) + dw HEX (009D) + dw HEX (009E) + dw HEX (009F) + dw HEX (00A0) + dw HEX (00A1) + dw HEX (00A2) + dw HEX (00A3) + dw HEX (00A4) + dw HEX (00A5) + dw HEX (00A6) + dw HEX (00A7) + dw HEX (00A8) + dw HEX (00A9) + dw HEX (00AA) + dw HEX (00AB) + dw HEX (00AC) + dw HEX (00AD) + dw HEX (00AE) + dw HEX (00AF) + dw HEX (00B0) + dw HEX (00B1) + dw HEX (00B2) + dw HEX (00B3) + dw HEX (00B4) + dw HEX (00B5) + dw HEX (00B6) + dw HEX (00B7) + dw HEX (00B8) + dw HEX (00B9) + dw HEX (00BA) + dw HEX (00BB) + dw HEX (00BC) + dw HEX (00BD) + dw HEX (00BE) + dw HEX (00BF) + dw HEX (00C0) + dw HEX (00C1) + dw HEX (00C2) + dw HEX (00C3) + dw HEX (00C4) + dw HEX (00C5) + dw HEX (00C6) + dw HEX (00C7) + dw HEX (00C8) + dw HEX (00C9) + dw HEX (00CA) + dw HEX (00CB) + dw HEX (00CC) + dw HEX (00CD) + dw HEX (00CE) + dw HEX (00CF) + dw HEX (00D0) + dw HEX (00D1) + dw HEX (00D2) + dw HEX (00D3) + dw HEX (00D4) + dw HEX (00D5) + dw HEX (00D6) + dw HEX (00D7) + dw HEX (00D8) + dw HEX (00D9) + dw HEX (00DA) + dw HEX (00DB) + dw HEX (00DC) + dw HEX (00DD) + dw HEX (00DE) + dw HEX (00DF) + dw HEX (00E0) + dw HEX (00E1) + dw HEX (00E2) + dw HEX (00E3) + dw HEX (00E4) + dw HEX (00E5) + dw HEX (00E6) + dw HEX (00E7) + dw HEX (00E8) + dw HEX (00E9) + dw HEX (00EA) + dw HEX (00EB) + dw HEX (00EC) + dw HEX (00ED) + dw HEX (00EE) + dw HEX (00EF) + dw HEX (00F0) + dw HEX (00F1) + dw HEX (00F2) + dw HEX (00F3) + dw HEX (00F4) + dw HEX (00F5) + dw HEX (00F6) + dw HEX (00F7) + dw HEX (00F8) + dw HEX (00F9) + dw HEX (00FA) + dw HEX (00FB) + dw HEX (00FC) + dw HEX (00FD) + dw HEX (00FE) + dw HEX (00FF) diff --git a/src/boot/freeldr/lib/crt/stdio/fclose.asm b/src/boot/freeldr/lib/crt/stdio/fclose.asm new file mode 100644 index 0000000..27bcbed --- /dev/null +++ b/src/boot/freeldr/lib/crt/stdio/fclose.asm @@ -0,0 +1,90 @@ +;****************************************************************************** +; @file fclose.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _fclose +;****************************************************************************** +global _fclose +_fclose: + + push bp + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push es + push si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the pointer from the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, word ptr [bp + 4] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we actaully have some value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and bx, bx + jz _fclose.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Set up the extra segment and si register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, bx + xor si, si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the file handle from the pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, es:[si] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Call int 21h/ah=3E to close the file. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ah, HEX (3E) + int HEX (21) + jc _fclose.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Free our pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push word ptr [bp + 4] + + call _free + add sp, 2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the ax register and clear the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + clc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop es + pop bx + pop bp + ret + +_fclose.error: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Set the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + stc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop es + pop bx + pop bp + ret diff --git a/src/boot/freeldr/lib/crt/stdio/feof.asm b/src/boot/freeldr/lib/crt/stdio/feof.asm new file mode 100644 index 0000000..7ca588d --- /dev/null +++ b/src/boot/freeldr/lib/crt/stdio/feof.asm @@ -0,0 +1,92 @@ +;****************************************************************************** +; @file feof.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _feof +;****************************************************************************** +global _feof +_feof: + + push bp + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push es + push si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the ax register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the pointer from the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, word ptr [bp + 4] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we actaully have some value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and bx, bx + jz _feof.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Set up the extra segment and si register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, bx + xor si, si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the flags from the pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, es:[si + 2] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Have we reached EOF? + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and bx, HEX (0100) + jz _feof.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Return 1 to indicate that we reached EOF. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, 1 + +_feof.done: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clear the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + clc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop es + pop bx + pop bp + ret + +_feof.error: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Set the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + stc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers and return. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop es + pop bx + pop bp + ret diff --git a/src/boot/freeldr/lib/crt/stdio/fopen.asm b/src/boot/freeldr/lib/crt/stdio/fopen.asm new file mode 100644 index 0000000..32dc079 --- /dev/null +++ b/src/boot/freeldr/lib/crt/stdio/fopen.asm @@ -0,0 +1,129 @@ +;****************************************************************************** +; @file fopen.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _fopen +;****************************************************************************** +global _fopen +_fopen: + + push bp + mov bp, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push es + push si + push di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Call int 21h/ah=3D to open the file. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dx, word ptr [bp + 4] + + mov ax, HEX (3D00) + int HEX (21) + jc _fopen.error + +_fopen.success: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the file handle in ax. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Allocate some memory for a pointer (i.e. FILE *). + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, 16 + xor dx, dx + + push ax + push dx + + call _xmalloc + add sp, 4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure the malloc didn't fail. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, ax + jz _fopen.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We'll use es:di to store the values. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov es, ax + xor di, di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store the file handle. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop ax + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We're not handling files (at least so far) so just push a null word. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We're not EOF yet. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + stosw + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the value in the extra segment into ax. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es + clc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop di + pop si + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +_fopen.error: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop di + pop si + pop es + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the ax register and set the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + stc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret diff --git a/src/boot/freeldr/lib/crt/stdio/fread.asm b/src/boot/freeldr/lib/crt/stdio/fread.asm new file mode 100644 index 0000000..a59e3e1 --- /dev/null +++ b/src/boot/freeldr/lib/crt/stdio/fread.asm @@ -0,0 +1,209 @@ +;****************************************************************************** +; @file fread.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _fread +;****************************************************************************** +global _fread +_fread: + + push bp + + mov bp, sp + sub sp, 2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the reserved stack value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov word ptr [bp - 2], 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the buffer off the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, word ptr [bp + 4] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we have actually buffer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;and si, si + ;jz _fread.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the pointer off the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, word ptr [bp + 10] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we actually have a pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and si, si + jz _fread.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the amount of bytes to read. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 8] + xor dx, dx + + mov cx, word ptr [bp + 6] + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the number of bytes are zero then we're done. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and cx, cx + jz _fread.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get our file handle from the pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push di + + mov es, si + xor di, di + + mov bx, es:[di + 0] + mov dx, es:[di + 2] + + pop di + pop es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Have we reached the end of the file? + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + test dx, HEX (0100) + jnz _fread.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the number of bytes into the cx register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the dx register with the address of the buffer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dx, word ptr [bp + 4] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Read # no of bytes into the buffer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ah, HEX (3F) + int HEX (21) + jc _fread.error + + and ax, ax + jnz _fread.read_ok + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add an EOF marker to the flags, + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push di + + mov es, si + xor di, di + + or word ptr es:[di + 2], HEX (0100) + pop di + pop es + + jmp short _fread.zero + +_fread.read_ok: + + cmp cx, ax + je _fread.size_ok + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add an EOF marker to the flags, + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push di + + mov es, si + xor di, di + + or word ptr es:[di + 2], HEX (0100) + pop di + pop es + +_fread.size_ok: + + cmp word ptr [bp + 6], 0 + je _fread.zero + + xor dx, dx + + mov cx, word ptr [bp + 6] + div cx + + mov word ptr [bp - 2], ax + jmp _fread.done + +_fread.zero: + + mov word ptr [bp - 2], 0 + +_fread.done: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Return the count. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp - 2] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clean up the stack and clear the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 2 + clc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +_fread.error: + + xor ax, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clean up the stack and set the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 2 + stc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret diff --git a/src/boot/freeldr/lib/crt/string/memmove.asm b/src/boot/freeldr/lib/crt/string/memmove.asm new file mode 100644 index 0000000..ec8cb39 --- /dev/null +++ b/src/boot/freeldr/lib/crt/string/memmove.asm @@ -0,0 +1,91 @@ +;****************************************************************************** +; @file memmove.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _memmove +;****************************************************************************** +global _memmove +_memmove: + + push bp + mov bp, sp + + push si + push di + push bx + push cx + + mov di, word ptr [bp + 4] + mov si, word ptr [bp + 6] + mov cx, word ptr [bp + 8] + +.L3: + + cmp di, si + ja .L2 + +.L4: + + and cx, cx + jz .L1 + + movsb + dec cx + + jmp .L4 + + jmp .L1 + +.L2: + + and cx, cx + jz .L1 + + dec cx + +.L6: + + and cx, cx + jz .L5 + + mov bx, si + add bx, cx + + mov al, [si] + + mov bx, di + add bx, cx + + mov es:[di], al + + dec cx + jmp .L6 + +.L5: + + mov bx, si + add bx, cx + + mov al, [si] + + mov bx, di + add bx, cx + + mov es:[di], al + +.L1: + + pop cx + pop bx + pop di + pop si + + mov ax, word ptr [bp + 4] + clc + + pop bp + ret diff --git a/src/boot/freeldr/lib/crt/string/strlen.asm b/src/boot/freeldr/lib/crt/string/strlen.asm new file mode 100644 index 0000000..273730b --- /dev/null +++ b/src/boot/freeldr/lib/crt/string/strlen.asm @@ -0,0 +1,42 @@ +;****************************************************************************** +; @file strlen.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _strlen +;****************************************************************************** +global _strlen +_strlen: + + push bp + mov bp, sp + + push cx + push si + push di + + mov si, word ptr [bp + 4] + xor cx, cx + +_strlen.loop: + + lodsb + + or al, al + jz _strlen.done + + inc cx + jmp short _strlen.loop + +_strlen.done: + + mov ax, cx + + pop di + pop si + pop cx + pop bp + ret diff --git a/src/boot/freeldr/libc/Makefile.unix b/src/boot/freeldr/libc/Makefile.unix deleted file mode 100644 index b3b5803..0000000 --- a/src/boot/freeldr/libc/Makefile.unix +++ /dev/null @@ -1,35 +0,0 @@ -#****************************************************************************** -# @file Makefile.unix -#****************************************************************************** -TARGETS := stdio stdlib string - -OBJDIR ?= $(CURDIR) -SRCDIR ?= $(CURDIR) - -VPATH := $(SRCDIR) - -all: libc.a - -clean: - for f in `find . -name '*.o'`; do if [ -f $$f ]; then rm -rf $$f; fi; done - for f in `find . -name '*.lst'`; do if [ -f $$f ]; then rm -rf $$f; fi; done - if [ -f libc.a ]; then rm -rf libc.a; fi - -libc.a: stdio/fclose.o stdio/feof.o stdio/fopen.o stdio/fread.o stdlib/free.o stdlib/malloc.o stdlib/realloc.o string/memmove.o string/strlen.o - ../../../utils/binutils/sar r libc.a $^ - ../../../utils/binutils/sar s libc.a - -stdio/%.o: stdio/%.asm - if [ ! -d "stdio" ]; then mkdir -p "stdio"; fi - ../../../utils/binutils/sasm -I$(SRCDIR)/include -l stdio/$*.lst -o $@ $< - -stdlib/%.o: stdlib/%.asm - if [ ! -d "stdlib" ]; then mkdir -p "stdlib"; fi - ../../../utils/binutils/sasm -l stdlib/$*.lst -o $@ $< - -string/%.o: string/%.asm - if [ ! -d "string" ]; then mkdir -p "string"; fi - ../../../utils/binutils/sasm -l string/$*.lst -o $@ $< - -%.o: %.asm - ../../../utils/binutils/sasm -l $*.lst -o $@ $< diff --git a/src/boot/freeldr/libc/Makefile.w32 b/src/boot/freeldr/libc/Makefile.w32 deleted file mode 100644 index d4f502c..0000000 --- a/src/boot/freeldr/libc/Makefile.w32 +++ /dev/null @@ -1,35 +0,0 @@ -#****************************************************************************** -# @file Makefile.w32 -#****************************************************************************** -TARGETS := stdio stdlib string - -OBJDIR ?= $(CURDIR) -SRCDIR ?= $(CURDIR) - -VPATH := $(SRCDIR) - -all: libc.a - -clean: - for /r %%f in (*.o) do ( if exist %%f ( del /q %%f ) ) - for /r %%f in (*.lst) do ( if exist %%f ( del /q %%f ) ) - if exist libc.a ( del /q libc.a ) - -libc.a: stdio/fclose.o stdio/feof.o stdio/fopen.o stdio/fread.o stdlib/free.o stdlib/malloc.o stdlib/realloc.o string/memmove.o string/strlen.o - ../../../utils/binutils/sar r libc.a $^ - ../../../utils/binutils/sar s libc.a - -stdio/%.o: stdio/%.asm - if not exist "stdio" ( mkdir "stdio" ) - ../../../utils/binutils/sasm -I$(SRCDIR)/include -l stdio/$*.lst -o $@ $< - -stdlib/%.o: stdlib/%.asm - if not exist "stdlib" ( mkdir "stdlib" ) - ../../../utils/binutils/sasm -l stdlib/$*.lst -o $@ $< - -string/%.o: string/%.asm - if not exist "string" ( mkdir "string" ) - ../../../utils/binutils/sasm -l string/$*.lst -o $@ $< - -%.o: %.asm - ../../../utils/binutils/sasm -l $*.lst -o $@ $< diff --git a/src/boot/freeldr/libc/stdio/fclose.asm b/src/boot/freeldr/libc/stdio/fclose.asm deleted file mode 100644 index 27bcbed..0000000 --- a/src/boot/freeldr/libc/stdio/fclose.asm +++ /dev/null @@ -1,90 +0,0 @@ -;****************************************************************************** -; @file fclose.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _fclose -;****************************************************************************** -global _fclose -_fclose: - - push bp - mov bp, sp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - push es - push si - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the pointer from the stack. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov bx, word ptr [bp + 4] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Make sure we actaully have some value. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - and bx, bx - jz _fclose.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Set up the extra segment and si register. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov es, bx - xor si, si - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the file handle from the pointer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov bx, es:[si] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Call int 21h/ah=3E to close the file. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ah, HEX (3E) - int HEX (21) - jc _fclose.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Free our pointer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push word ptr [bp + 4] - - call _free - add sp, 2 - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out the ax register and clear the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - clc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers and return. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop si - pop es - pop bx - pop bp - ret - -_fclose.error: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Set the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - stc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers and return. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop si - pop es - pop bx - pop bp - ret diff --git a/src/boot/freeldr/libc/stdio/feof.asm b/src/boot/freeldr/libc/stdio/feof.asm deleted file mode 100644 index 7ca588d..0000000 --- a/src/boot/freeldr/libc/stdio/feof.asm +++ /dev/null @@ -1,92 +0,0 @@ -;****************************************************************************** -; @file feof.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _feof -;****************************************************************************** -global _feof -_feof: - - push bp - mov bp, sp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - push es - push si - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out the ax register. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the pointer from the stack. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov bx, word ptr [bp + 4] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Make sure we actaully have some value. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - and bx, bx - jz _feof.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Set up the extra segment and si register. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov es, bx - xor si, si - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the flags from the pointer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov bx, es:[si + 2] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Have we reached EOF? - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - and bx, HEX (0100) - jz _feof.done - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Return 1 to indicate that we reached EOF. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, 1 - -_feof.done: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Clear the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - clc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers and return. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop si - pop es - pop bx - pop bp - ret - -_feof.error: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Set the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - stc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers and return. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop si - pop es - pop bx - pop bp - ret diff --git a/src/boot/freeldr/libc/stdio/fopen.asm b/src/boot/freeldr/libc/stdio/fopen.asm deleted file mode 100644 index 32dc079..0000000 --- a/src/boot/freeldr/libc/stdio/fopen.asm +++ /dev/null @@ -1,129 +0,0 @@ -;****************************************************************************** -; @file fopen.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _fopen -;****************************************************************************** -global _fopen -_fopen: - - push bp - mov bp, sp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - push cx - push dx - push es - push si - push di - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Call int 21h/ah=3D to open the file. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov dx, word ptr [bp + 4] - - mov ax, HEX (3D00) - int HEX (21) - jc _fopen.error - -_fopen.success: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve the file handle in ax. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Allocate some memory for a pointer (i.e. FILE *). - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, 16 - xor dx, dx - - push ax - push dx - - call _xmalloc - add sp, 4 - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Make sure the malloc didn't fail. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - and ax, ax - jz _fopen.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; We'll use es:di to store the values. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov es, ax - xor di, di - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Store the file handle. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop ax - stosw - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; We're not handling files (at least so far) so just push a null word. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - stosw - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; We're not EOF yet. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - stosw - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Move the value in the extra segment into ax. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, es - clc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop di - pop si - pop es - pop dx - pop cx - pop bx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the base pointer and return to caller. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop bp - ret - -_fopen.error: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop di - pop si - pop es - pop dx - pop cx - pop bx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out the ax register and set the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - stc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the base pointer and return to caller. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop bp - ret diff --git a/src/boot/freeldr/libc/stdio/fread.asm b/src/boot/freeldr/libc/stdio/fread.asm deleted file mode 100644 index a59e3e1..0000000 --- a/src/boot/freeldr/libc/stdio/fread.asm +++ /dev/null @@ -1,209 +0,0 @@ -;****************************************************************************** -; @file fread.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _fread -;****************************************************************************** -global _fread -_fread: - - push bp - - mov bp, sp - sub sp, 2 - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - push cx - push dx - push si - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out the reserved stack value. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov word ptr [bp - 2], 0 - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the buffer off the stack. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov si, word ptr [bp + 4] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Make sure we have actually buffer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;and si, si - ;jz _fread.done - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the pointer off the stack. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov si, word ptr [bp + 10] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Make sure we actually have a pointer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - and si, si - jz _fread.done - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Calculate the amount of bytes to read. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, word ptr [bp + 8] - xor dx, dx - - mov cx, word ptr [bp + 6] - mul cx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; If the number of bytes are zero then we're done. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - and cx, cx - jz _fread.done - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get our file handle from the pointer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push es - push di - - mov es, si - xor di, di - - mov bx, es:[di + 0] - mov dx, es:[di + 2] - - pop di - pop es - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Have we reached the end of the file? - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - test dx, HEX (0100) - jnz _fread.done - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Move the number of bytes into the cx register. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Initialize the dx register with the address of the buffer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov dx, word ptr [bp + 4] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Read # no of bytes into the buffer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ah, HEX (3F) - int HEX (21) - jc _fread.error - - and ax, ax - jnz _fread.read_ok - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Add an EOF marker to the flags, - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push es - push di - - mov es, si - xor di, di - - or word ptr es:[di + 2], HEX (0100) - pop di - pop es - - jmp short _fread.zero - -_fread.read_ok: - - cmp cx, ax - je _fread.size_ok - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Add an EOF marker to the flags, - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push es - push di - - mov es, si - xor di, di - - or word ptr es:[di + 2], HEX (0100) - pop di - pop es - -_fread.size_ok: - - cmp word ptr [bp + 6], 0 - je _fread.zero - - xor dx, dx - - mov cx, word ptr [bp + 6] - div cx - - mov word ptr [bp - 2], ax - jmp _fread.done - -_fread.zero: - - mov word ptr [bp - 2], 0 - -_fread.done: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Return the count. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, word ptr [bp - 2] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop si - pop dx - pop cx - pop bx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Clean up the stack and clear the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - add sp, 2 - clc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the base pointer and return to caller. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop bp - ret - -_fread.error: - - xor ax, ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop si - pop dx - pop cx - pop bx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Clean up the stack and set the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - add sp, 2 - stc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the base pointer and return to caller. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop bp - ret diff --git a/src/boot/freeldr/libc/stdlib/free.asm b/src/boot/freeldr/libc/stdlib/free.asm deleted file mode 100644 index d165740..0000000 --- a/src/boot/freeldr/libc/stdlib/free.asm +++ /dev/null @@ -1,37 +0,0 @@ -;****************************************************************************** -; @file free.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _free -;****************************************************************************** -global _free -_free: - - push bp - mov bp, sp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push ax - push es - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Call int 21h/ah=49 to free the blocks. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov es, word ptr [bp + 4] - - mov ah, HEX (49) - int HEX (21) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers and return. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop es - pop ax - pop bp - ret diff --git a/src/boot/freeldr/libc/stdlib/malloc.asm b/src/boot/freeldr/libc/stdlib/malloc.asm deleted file mode 100644 index bebd0ec..0000000 --- a/src/boot/freeldr/libc/stdlib/malloc.asm +++ /dev/null @@ -1,90 +0,0 @@ -;****************************************************************************** -; @file malloc.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _malloc -;****************************************************************************** -global _malloc -_malloc: - - push bp - mov bp, sp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - push cx - push dx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the size (in bytes) from the stack. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, word ptr [bp + 6] - mov dx, word ptr [bp + 4] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Convert the size to paragraphs. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 16 - div cx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; If dx is non-zero then try to increase the count. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cmp dx, 0 - je _malloc.ok - -_malloc.inc: - - inc ax - jz _malloc.error - -_malloc.ok: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Call int 21h/ah=48 to allocate the blocks. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov bx, ax - - mov ah, HEX (48) - int HEX (21) - jc _malloc.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop dx - pop cx - pop bx - pop bp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Clear the carry flag and return. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ret - -_malloc.error: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out the ax register and set the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - stc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop dx - pop cx - pop bx - pop bp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Return to caller. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ret diff --git a/src/boot/freeldr/libc/stdlib/realloc.asm b/src/boot/freeldr/libc/stdlib/realloc.asm deleted file mode 100644 index 2e43b97..0000000 --- a/src/boot/freeldr/libc/stdlib/realloc.asm +++ /dev/null @@ -1,233 +0,0 @@ -;****************************************************************************** -; @file realloc.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _realloc -;****************************************************************************** -global _realloc -_realloc: - - push bp - mov bp, sp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - push cx - push si - push di - push dx - push es - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the size (in bytes) from the stack as well as the pointer to - ;; re-allocate. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, word ptr [bp + 8] - mov dx, word ptr [bp + 6] - mov bx, word ptr [bp + 4] - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Make sure we have valid memory as a pointer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - and bx, bx - jz _realloc.calc - - mov di, bx - dec di - mov es, di - - xor di, di - - cmp byte ptr es:[di], 'M' - jne _realloc.error - - cmp byte ptr es:[di + 1], 'C' - jne _realloc.error - - cmp byte ptr es:[di + 2], 'B' - jne _realloc.error - -_realloc.calc: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Convert the size to paragraphs. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov cx, 16 - div cx - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; If dx is non-zero then try to increase the count. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cmp dx, 0 - je _realloc.ok - -_realloc.inc: - - inc ax - jz _realloc.error - -_realloc.ok: - - mov si, ax - - and bx, bx - jz _realloc.alloc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; First. lets try and resize the memory block. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - push es - - mov es, bx - mov bx, si - - mov ah, HEX (4A) - int HEX (21) - pop es - pop bx - jnc _realloc.done - -_realloc.alloc: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Call int 21h/ah=48 to allocate the blocks. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push bx - mov bx, si - - mov ah, HEX (48) - int HEX (21) - pop bx - jc _realloc.error - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Only copy existing data if there was an original pointer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov di, bx - - and di, di - jz _realloc.done - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve registers that copy will clobber. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push si - push ds - - mov di, bx - mov ds, di - - dec di - - mov es, di - xor di, di - - mov cx, word ptr es:[di + 3] - mov es, ax - - cmp cx, bx - jb _realloc.copy - - mov cx, bx - -_realloc.copy: - - xor si, si - xor di, di - - push cx - - mov cx, 16 - rep movsb - - pop cx - - mov si, es - inc si - mov es, si - - mov di, ds - inc di - mov ds, di - - loop _realloc.copy - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers that copy clobbered. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop ds - pop si - -_realloc.free: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Preserve the new pointer; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - push ax - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; If we reached this point then free the original pointer. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov es, bx - - mov ah, HEX (49) - int HEX (21) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore the new pointer; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop ax - -_realloc.done: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Clear the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - clc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop es - pop dx - pop di - pop si - pop cx - pop bx - pop bp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Clear the carry flag and return. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ret - -_realloc.error: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Zero out the ax register and set the carry flag. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor ax, ax - stc - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Restore registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop es - pop dx - pop di - pop si - pop cx - pop bx - pop bp - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Return to caller. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ret diff --git a/src/boot/freeldr/libc/string/memmove.asm b/src/boot/freeldr/libc/string/memmove.asm deleted file mode 100644 index ec8cb39..0000000 --- a/src/boot/freeldr/libc/string/memmove.asm +++ /dev/null @@ -1,91 +0,0 @@ -;****************************************************************************** -; @file memmove.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _memmove -;****************************************************************************** -global _memmove -_memmove: - - push bp - mov bp, sp - - push si - push di - push bx - push cx - - mov di, word ptr [bp + 4] - mov si, word ptr [bp + 6] - mov cx, word ptr [bp + 8] - -.L3: - - cmp di, si - ja .L2 - -.L4: - - and cx, cx - jz .L1 - - movsb - dec cx - - jmp .L4 - - jmp .L1 - -.L2: - - and cx, cx - jz .L1 - - dec cx - -.L6: - - and cx, cx - jz .L5 - - mov bx, si - add bx, cx - - mov al, [si] - - mov bx, di - add bx, cx - - mov es:[di], al - - dec cx - jmp .L6 - -.L5: - - mov bx, si - add bx, cx - - mov al, [si] - - mov bx, di - add bx, cx - - mov es:[di], al - -.L1: - - pop cx - pop bx - pop di - pop si - - mov ax, word ptr [bp + 4] - clc - - pop bp - ret diff --git a/src/boot/freeldr/libc/string/strlen.asm b/src/boot/freeldr/libc/string/strlen.asm deleted file mode 100644 index 273730b..0000000 --- a/src/boot/freeldr/libc/string/strlen.asm +++ /dev/null @@ -1,42 +0,0 @@ -;****************************************************************************** -; @file strlen.asm -;****************************************************************************** -%ifndef HEX -% define HEX(y) 0x##y -%endif - -;****************************************************************************** -; @function _strlen -;****************************************************************************** -global _strlen -_strlen: - - push bp - mov bp, sp - - push cx - push si - push di - - mov si, word ptr [bp + 4] - xor cx, cx - -_strlen.loop: - - lodsb - - or al, al - jz _strlen.done - - inc cx - jmp short _strlen.loop - -_strlen.done: - - mov ax, cx - - pop di - pop si - pop cx - pop bp - ret diff --git a/src/kernel/disk.asm b/src/kernel/disk.asm index ded082d..56ab33c 100644 --- a/src/kernel/disk.asm +++ b/src/kernel/disk.asm @@ -543,15 +543,17 @@ _get_partition_info: add sp, 26 clc - jmp .L20 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret .L22: add sp, 26 stc - -.L20: - + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Restore the base pointer and return to caller. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -634,17 +636,17 @@ _get_hard_disk_partitions: push ax call _get_partition_info + jnc .L20 + add sp, 4 and ax, ax jz .L15 - jnc .L16 - mov es, ax xor bx, bx - cmp es:[bx + 29], dl + cmp es:[bx + 33], dl jne .L16 .L17: @@ -659,6 +661,10 @@ _get_hard_disk_partitions: jmp .L15 +.L20: + + add sp, 4 + .L16: push ds diff --git a/src/kernel/divide.asm b/src/kernel/divide.asm index 0018abf..447935a 100644 --- a/src/kernel/divide.asm +++ b/src/kernel/divide.asm @@ -60,189 +60,65 @@ _divide_handler.init: mov bx, offset _divide_handler.msg call _writestr - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print the segment of the error. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, word ptr [bp + 4] - call _writehex - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print a colon. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, ':' - call _writechr - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print the offset of the error. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, word ptr [bp + 2] - call _writehex - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Print a newline. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; call _crlf - call _crlf - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Indent with 4 spaces. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print the code segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, cs - call _writehex - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Indent with 4 spaces. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print the data segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, ds - call _writehex - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Indent with 4 spaces. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print the extra segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, es - call _writehex ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Indent with 4 spaces. + ;; Zero out the si register. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print the stack segmennt segment. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, ss - call _writehex - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Indent with 4 spaces. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr + xor si, si + +_divide_handler.loop: + + cmp si, 12 * 2 + jae _divide_handler.done - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print the stack and base pointers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, word ptr [bp + 2] - add ax, 3 * 2 ; return address, offset, segment. - call _writehex + mov ax, si + xor dx, dx - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr + mov cx, 12 + div cx - mov ax, word ptr [bp] - call _writehex + and dx, dx + jnz _divide_handler.print - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print a newline. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; call _crlf - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Indent with 4 spaces. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Print the general purpose registers. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, si - call _writehex - mov al, ' ' call _writechr call _writechr call _writechr call _writechr - - mov ax, di - call _writehex - - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr - - pop ax + +_divide_handler.print: + + mov ax, word ptr [bp + si] call _writehex - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr + inc si + inc si - pop ax - call _writehex + mov ax, si + xor dx, dx - mov al, ' ' - call _writechr - call _writechr - call _writechr - call _writechr + mov cx, 12 + div cx - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Get the value of bx off the stack and print it. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop ax - call _writehex + and dx, dx + jz _divide_handler.loop - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Indent with 4 spaces. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov al, ' ' call _writechr call _writechr call _writechr call _writechr - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Finally, get the value of ax off the stack and print it. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - pop ax - call _writehex - + jmp _divide_handler.loop + +_divide_handler.done: + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Print a newline. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -272,4 +148,4 @@ _divide_handler.reboot: _divide_handler.msg: - db "Trap to vector 0: Divide overflow at ", HEX (00) + db "Trap to vector 0: Divide overflow", HEX (00) diff --git a/src/kernel/kernel.asm b/src/kernel/kernel.asm index 70afdd2..2f8689b 100644 --- a/src/kernel/kernel.asm +++ b/src/kernel/kernel.asm @@ -401,7 +401,7 @@ _check_disks: ;; Decrement cx and loop back for next drive. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dec cx - jmp .L10 + jnz .L10 .L13: @@ -463,11 +463,20 @@ _check_disks: .L11: cmp byte ptr ss:[bx + 0], HEX (EB) - jne .L10 + jne .L15 cmp byte ptr ss:[bx + 2], HEX (90) - jne .L10 + jne .L15 + jmp .L18 + +.L15: + + call _error + db "panic: seleteced disk does not have a valid/supported parition", HEX (0D), HEX (0A), HEX (00) + +.L18: + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Next we'll copy the BPB to our "structure". ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;