# 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
#******************************************************************************
# @file Makefile.unix
#******************************************************************************
-TARGETS := bootsect libc core
+TARGETS := bootsect lib core
OBJDIR ?= $(CURDIR)
SRCDIR ?= $(CURDIR)
#******************************************************************************
# @file Makefile.w32
#******************************************************************************
-TARGETS := bootsect libc core
+TARGETS := bootsect lib core
OBJDIR ?= $(CURDIR)
SRCDIR ?= $(CURDIR)
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
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
_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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%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
;******************************************************************************
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)
--- /dev/null
+;******************************************************************************
+; @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)
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
;******************************************************************************
_fat_jump:
db HEX (EB)
- db HEX (00)
+ db HEX (3C)
db HEX (90)
global _fat_seg
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.
_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:
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.
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 '\'.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
test cl, HEX (18)
jz _open_file.got_file
+
+ jmp _open_file.error
_open_file.name_error:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Nope, so add the file info to our vector.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ mov ax, cs
+ mov ds, ax
+
push es
mov bx, offset _vec_files
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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pop bx
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Ckear the carry flag.
+ ;; Clear the carry flag.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
clc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_read_file.loop:
+ and cx, cx
+ jz _read_file.done
+
call _getc
jc _read_file.error
jz _read_file.done
inc word ptr [bp - 2]
- loop _read_file.loop
+
+ dec cx
+ jnz _read_file.loop
_read_file.done:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data area.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+global _vec_files
_vec_files: db 6 dup (0)
--- /dev/null
+;******************************************************************************
+; @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
%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.
global _all_read
_all_read:
- jnc _not_fat32
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Disable interrupts and clear the direction flag.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
;******************************************************************************
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)
;******************************************************************************
_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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loop back for the next entry (if there is one).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- jmp short .L6
+ jmp short .L4
-.L7:
+.L5:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Re-enable 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:
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_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:
% 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
;******************************************************************************
;; 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:
;******************************************************************************
-; @function int21_3D
+; @function _int21_3D
; @brief Open File Using Handle
;
; @in AL -> Open access mode.
;
; @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..
;
; @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
--- /dev/null
+;******************************************************************************
+; @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)
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
;; 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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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)
default chimaera
-#timeout 10
-timeout 0
+timeout 10
label chimaera
title Chimaera OS
--- /dev/null
+#******************************************************************************
+# @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
--- /dev/null
+#******************************************************************************
+# @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 \
+ ) \
+ )
--- /dev/null
+#******************************************************************************
+# @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 $@ $<
--- /dev/null
+#******************************************************************************
+# @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 $@ $<
--- /dev/null
+;******************************************************************************
+; @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)
--- /dev/null
+;******************************************************************************
+; @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
--- /dev/null
+;******************************************************************************
+; @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
--- /dev/null
+;******************************************************************************
+; @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
--- /dev/null
+;******************************************************************************
+; @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
--- /dev/null
+;******************************************************************************
+; @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
--- /dev/null
+;******************************************************************************
+; @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
+++ /dev/null
-#******************************************************************************
-# @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 $@ $<
+++ /dev/null
-#******************************************************************************
-# @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 $@ $<
+++ /dev/null
-;******************************************************************************
-; @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
+++ /dev/null
-;******************************************************************************
-; @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
+++ /dev/null
-;******************************************************************************
-; @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
+++ /dev/null
-;******************************************************************************
-; @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
+++ /dev/null
-;******************************************************************************
-; @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
+++ /dev/null
-;******************************************************************************
-; @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
+++ /dev/null
-;******************************************************************************
-; @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
+++ /dev/null
-;******************************************************************************
-; @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
+++ /dev/null
-;******************************************************************************
-; @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
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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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:
jmp .L15
+.L20:
+
+ add sp, 4
+
.L16:
push ds
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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_divide_handler.msg:
- db "Trap to vector 0: Divide overflow at ", HEX (00)
+ db "Trap to vector 0: Divide overflow", HEX (00)
;; Decrement cx and loop back for next drive.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dec cx
- jmp .L10
+ jnz .L10
.L13:
.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".
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;