forked from KolibriOS/kolibrios
16-bit rubbish cleaning
git-svn-id: svn://kolibrios.org@3176 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
b9b90b4740
commit
fd0e46d25e
@ -15,72 +15,6 @@ $Revision$
|
|||||||
|
|
||||||
boot_dev db 0 ; 0=floppy, 1=hd
|
boot_dev db 0 ; 0=floppy, 1=hd
|
||||||
|
|
||||||
;==========================================================================
|
|
||||||
;
|
|
||||||
; 16 BIT FUNCTIONS
|
|
||||||
;
|
|
||||||
;==========================================================================
|
|
||||||
|
|
||||||
|
|
||||||
boot_read_floppy:
|
|
||||||
push si
|
|
||||||
xor si, si
|
|
||||||
mov ah, 2 ; read
|
|
||||||
@@:
|
|
||||||
push ax
|
|
||||||
int 0x13
|
|
||||||
pop ax
|
|
||||||
jnc @f
|
|
||||||
inc si
|
|
||||||
cmp si, 10
|
|
||||||
jnb $
|
|
||||||
@@:
|
|
||||||
pop si
|
|
||||||
ret
|
|
||||||
|
|
||||||
sayerr_plain:
|
|
||||||
sayerr:
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
|
|
||||||
; convert abs. sector number (AX) to BIOS T:H:S
|
|
||||||
; sector number = (abs.sector%BPB_SecPerTrk)+1
|
|
||||||
; pre.track number = (abs.sector/BPB_SecPerTrk)
|
|
||||||
; head number = pre.track number%BPB_NumHeads
|
|
||||||
; track number = pre.track number/BPB_NumHeads
|
|
||||||
; Return: cl - sector number
|
|
||||||
; ch - track number
|
|
||||||
; dl - drive number (0 = a:)
|
|
||||||
; dh - head number
|
|
||||||
conv_abs_to_THS:
|
|
||||||
push bx
|
|
||||||
mov bx,word [BPB_SecPerTrk]
|
|
||||||
xor dx,dx
|
|
||||||
div bx
|
|
||||||
inc dx
|
|
||||||
mov cl, dl ; cl = sector number
|
|
||||||
mov bx,word [BPB_NumHeads]
|
|
||||||
xor dx,dx
|
|
||||||
div bx
|
|
||||||
; !!!!!!! ax = track number, dx = head number
|
|
||||||
mov ch,al ; ch=track number
|
|
||||||
xchg dh,dl ; dh=head number
|
|
||||||
mov dl,0 ; dl=0 (drive 0 (a:))
|
|
||||||
pop bx
|
|
||||||
retn
|
|
||||||
; needed variables
|
|
||||||
BPB_SecPerTrk dw 0 ; sectors per track
|
|
||||||
BPB_NumHeads dw 0 ; number of heads
|
|
||||||
BPB_FATSz16 dw 0 ; size of FAT
|
|
||||||
BPB_RootEntCnt dw 0 ; count of root dir. entries
|
|
||||||
BPB_BytsPerSec dw 0 ; bytes per sector
|
|
||||||
BPB_RsvdSecCnt dw 0 ; number of reserved sectors
|
|
||||||
BPB_TotSec16 dw 0 ; count of the sectors on the volume
|
|
||||||
BPB_SecPerClus db 0 ; number of sectors per cluster
|
|
||||||
BPB_NumFATs db 0 ; number of FAT tables
|
|
||||||
abs_sector_adj dw 0 ; adjustment to make abs. sector number
|
|
||||||
end_of_FAT dw 0 ; end of FAT table
|
|
||||||
FirstDataSector dw 0 ; begin of data
|
|
||||||
|
|
||||||
;=========================================================================
|
;=========================================================================
|
||||||
;
|
;
|
||||||
@ -92,23 +26,6 @@ diff16 "start_of_code: ",0,$
|
|||||||
|
|
||||||
start_of_code:
|
start_of_code:
|
||||||
cld
|
cld
|
||||||
; \begin{diamond}[02.12.2005]
|
|
||||||
; if bootloader sets ax = 'KL', then ds:si points to loader block
|
|
||||||
cmp ax, 'KL'
|
|
||||||
jnz @f
|
|
||||||
mov word [cs:cfgmanager.loader_block], si
|
|
||||||
mov word [cs:cfgmanager.loader_block+2], ds
|
|
||||||
@@:
|
|
||||||
; \end{diamond}[02.12.2005]
|
|
||||||
|
|
||||||
; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk
|
|
||||||
; (see comment to bx_from_load)
|
|
||||||
cmp cx, 'HA'
|
|
||||||
jnz no_hd_load
|
|
||||||
cmp dx,'RD'
|
|
||||||
jnz no_hd_load
|
|
||||||
mov word [cs:bx_from_load], bx ; {SPraid}[13.03.2007]
|
|
||||||
no_hd_load:
|
|
||||||
|
|
||||||
; set up stack
|
; set up stack
|
||||||
mov ax, 3000h
|
mov ax, 3000h
|
||||||
@ -122,181 +39,48 @@ no_hd_load:
|
|||||||
|
|
||||||
|
|
||||||
cpugood:
|
cpugood:
|
||||||
|
xor ax, ax
|
||||||
push 0
|
push ax
|
||||||
popf
|
popf
|
||||||
sti
|
sti
|
||||||
|
|
||||||
; set up esp
|
; set up esp
|
||||||
movzx esp, sp
|
movzx esp, sp
|
||||||
|
|
||||||
push 0
|
push ax
|
||||||
pop es
|
pop es
|
||||||
and word [es:0x9031], 0
|
mov [es:0x9031], ax
|
||||||
; \begin{Mario79}
|
|
||||||
; find HDD IDE DMA PCI device
|
|
||||||
; check for PCI BIOS
|
|
||||||
mov ax, 0xB101
|
|
||||||
int 0x1A
|
|
||||||
jc .nopci
|
|
||||||
cmp edx, 'PCI '
|
|
||||||
jnz .nopci
|
|
||||||
; find PCI class code
|
|
||||||
; class 1 = mass storage
|
|
||||||
; subclass 1 = IDE controller
|
|
||||||
; a) class 1, subclass 1, programming interface 0x80
|
|
||||||
mov ax, 0xB103
|
|
||||||
mov ecx, 1*10000h + 1*100h + 0x80
|
|
||||||
xor si, si ; device index = 0
|
|
||||||
int 0x1A
|
|
||||||
jnc .found
|
|
||||||
; b) class 1, subclass 1, programming interface 0x8A
|
|
||||||
mov ax, 0xB103
|
|
||||||
mov ecx, 1*10000h + 1*100h + 0x8A
|
|
||||||
xor si, si ; device index = 0
|
|
||||||
int 0x1A
|
|
||||||
jnc .found
|
|
||||||
; c) class 1, subclass 1, programming interface 0x85
|
|
||||||
mov ax, 0xB103
|
|
||||||
mov ecx, 1*10000h + 1*100h + 0x85
|
|
||||||
xor si, si
|
|
||||||
int 0x1A
|
|
||||||
jc .nopci
|
|
||||||
.found:
|
|
||||||
; get memory base
|
|
||||||
mov ax, 0xB10A
|
|
||||||
mov di, 0x20 ; memory base is config register at 0x20
|
|
||||||
int 0x1A
|
|
||||||
jc .nopci
|
|
||||||
and cx, 0xFFF0 ; clear address decode type
|
|
||||||
mov [es:0x9031], cx
|
|
||||||
.nopci:
|
|
||||||
; \end{Mario79}
|
|
||||||
|
|
||||||
; --------------- APM - removed--------------------
|
; --------------- APM - removed--------------------
|
||||||
and word [es:0x9044], 0 ; ver = 0.0 (APM not found)
|
and word [es:0x9044], 0 ; ver = 0.0 (APM not found)
|
||||||
if 0
|
|
||||||
mov ax, 0x5300
|
|
||||||
xor bx, bx
|
|
||||||
int 0x15
|
|
||||||
jc apm_end ; APM not found
|
|
||||||
test cx, 2
|
|
||||||
jz apm_end ; APM 32-bit protected-mode interface not supported
|
|
||||||
mov [es:0x9044], ax ; Save APM Version
|
|
||||||
mov [es:0x9046], cx ; Save APM flags
|
|
||||||
|
|
||||||
mov ax, 0x5304 ; Disconnect interface
|
|
||||||
xor bx, bx
|
|
||||||
int 0x15
|
|
||||||
mov ax, 0x5303 ; Connect 32 bit mode interface
|
|
||||||
xor bx, bx
|
|
||||||
int 0x15
|
|
||||||
|
|
||||||
mov [es:0x9040], ebx
|
|
||||||
mov [es:0x9050], ax
|
|
||||||
mov [es:0x9052], cx
|
|
||||||
mov [es:0x9054], dx
|
|
||||||
|
|
||||||
apm_end:
|
|
||||||
end if
|
|
||||||
|
|
||||||
;CHECK current of code
|
|
||||||
cmp [cfgmanager.loader_block], -1
|
|
||||||
jz noloaderblock
|
|
||||||
les bx, [cfgmanager.loader_block]
|
|
||||||
cmp byte [es:bx], 1
|
|
||||||
jnz sayerr
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
|
|
||||||
noloaderblock:
|
|
||||||
; DISPLAY VESA INFORMATION
|
|
||||||
; call print_vesa_info
|
|
||||||
; call calc_vmodes_table
|
|
||||||
; call check_first_parm ;check and enable cursor_pos
|
|
||||||
|
|
||||||
; \begin{diamond}[30.11.2005]
|
|
||||||
cfgmanager:
|
cfgmanager:
|
||||||
; settings:
|
|
||||||
; a) preboot_graph = graphical mode
|
|
||||||
; preboot_gprobe = probe this mode?
|
|
||||||
; b) preboot_dma = use DMA access?
|
|
||||||
; c) preboot_vrrm = use VRR?
|
|
||||||
; d) preboot_device = from what boot?
|
|
||||||
|
|
||||||
; determine default settings
|
|
||||||
; mov [.bSettingsChanged], 0
|
|
||||||
|
|
||||||
;.preboot_gr_end:
|
|
||||||
mov di, preboot_device
|
|
||||||
; if image in memory is present and [preboot_device] is uninitialized,
|
|
||||||
; set it to use this preloaded image
|
|
||||||
cmp byte [di], 0
|
|
||||||
jnz .preboot_device_inited
|
|
||||||
cmp [.loader_block], -1
|
|
||||||
jz @f
|
|
||||||
les bx, [.loader_block]
|
|
||||||
test byte [es:bx+1], 1
|
|
||||||
jz @f
|
|
||||||
mov byte [di], 3
|
|
||||||
jmp .preboot_device_inited
|
|
||||||
@@:
|
|
||||||
; otherwise, set [preboot_device] to 1 (default value - boot from floppy)
|
|
||||||
mov byte [di], 1
|
|
||||||
.preboot_device_inited:
|
|
||||||
; following 4 lines set variables to 1 if its current value is 0
|
|
||||||
cmp byte [di+preboot_dma-preboot_device], 1
|
|
||||||
adc byte [di+preboot_dma-preboot_device], 0
|
|
||||||
cmp byte [di+preboot_biosdisk-preboot_device], 1
|
|
||||||
adc byte [di+preboot_biosdisk-preboot_device], 0
|
|
||||||
|
|
||||||
; pop ax ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ??
|
|
||||||
jmp .continue
|
|
||||||
|
|
||||||
.loader_block dd -1
|
|
||||||
.continue:
|
|
||||||
sti
|
|
||||||
jmp .load
|
|
||||||
|
|
||||||
.loadc:
|
|
||||||
pop eax
|
|
||||||
.cont:
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
.load:
|
|
||||||
|
|
||||||
; ASK GRAPHICS MODE
|
|
||||||
|
|
||||||
; call set_vmode
|
|
||||||
|
|
||||||
; GRAPHICS ACCELERATION
|
|
||||||
; force yes
|
|
||||||
mov [es:0x901C], byte 1
|
|
||||||
|
|
||||||
; DMA ACCESS TO HD
|
; DMA ACCESS TO HD
|
||||||
|
|
||||||
mov al, [preboot_dma]
|
mov al, 1
|
||||||
mov [es:0x901F], al
|
mov [es:0x901F], al
|
||||||
|
|
||||||
|
; GRAPHICS ACCELERATION
|
||||||
|
; force yes
|
||||||
|
mov [es:0x901C], al
|
||||||
|
|
||||||
|
|
||||||
; VRR_M USE
|
; VRR_M USE
|
||||||
|
|
||||||
mov al,[preboot_vrrm]
|
mov [es:0x9030], byte 2
|
||||||
mov [es:0x9030], al
|
mov [es:0x901E], al
|
||||||
mov [es:0x901E], byte 1
|
|
||||||
|
|
||||||
; BOOT DEVICE
|
; BOOT DEVICE
|
||||||
|
|
||||||
mov al, [preboot_device]
|
xor ax, ax
|
||||||
dec al
|
|
||||||
mov [boot_dev], al
|
mov [boot_dev], al
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
|
||||||
; SET GRAPHICS
|
; SET GRAPHICS
|
||||||
|
|
||||||
xor ax, ax
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
; mov bx, [es:0x9008] ; vga & 320x200
|
|
||||||
mov ax, 0xA000 ; AtomBIOS Fn00
|
mov ax, 0xA000 ; AtomBIOS Fn00
|
||||||
mov cx, 0x550A ; 1024x768, 32bpp, ARGB8888
|
mov cx, 0x550A ; 1024x768, 32bpp, ARGB8888
|
||||||
setgr:
|
setgr:
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
$Revision$
|
|
||||||
|
|
||||||
|
|
||||||
; boot data: common strings (for all languages)
|
|
||||||
macro line_full_top {
|
|
||||||
db 201
|
|
||||||
times 78 db 205
|
|
||||||
db 187
|
|
||||||
}
|
|
||||||
macro line_full_bottom {
|
|
||||||
db 200
|
|
||||||
times 78 db 205
|
|
||||||
db 188
|
|
||||||
}
|
|
||||||
macro line_half {
|
|
||||||
db 186,' '
|
|
||||||
times 76 db 0xc4
|
|
||||||
db ' ',186
|
|
||||||
}
|
|
||||||
macro line_space {
|
|
||||||
db 186
|
|
||||||
times 78 db 32
|
|
||||||
db 186
|
|
||||||
}
|
|
||||||
d80x25_top:
|
|
||||||
line_full_top
|
|
||||||
cur_line_pos = 75
|
|
||||||
store byte ' ' at d80x25_top+cur_line_pos+1
|
|
||||||
rev_var = __REV__
|
|
||||||
while rev_var > 0
|
|
||||||
store byte rev_var mod 10 + '0' at d80x25_top+cur_line_pos
|
|
||||||
cur_line_pos = cur_line_pos - 1
|
|
||||||
rev_var = rev_var / 10
|
|
||||||
end while
|
|
||||||
store byte ' ' at d80x25_top+cur_line_pos
|
|
||||||
store dword ' SVN' at d80x25_top+cur_line_pos-4
|
|
||||||
|
|
||||||
space_msg: line_space
|
|
||||||
verstr:
|
|
||||||
; line_space
|
|
||||||
; version string
|
|
||||||
db 186,32
|
|
||||||
repeat 78
|
|
||||||
load a byte from version+%-1
|
|
||||||
if a = 13
|
|
||||||
break
|
|
||||||
end if
|
|
||||||
db a
|
|
||||||
end repeat
|
|
||||||
repeat 78 - ($-verstr)
|
|
||||||
db ' '
|
|
||||||
end repeat
|
|
||||||
db 32,186
|
|
||||||
line_half
|
|
||||||
d80x25_top_num = 4
|
|
@ -1,38 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
$Revision$
|
|
||||||
|
|
||||||
|
|
||||||
display_modechg db 0 ; display mode change for text, yes/no (0 or 2)
|
|
||||||
;
|
|
||||||
; !! Important note !!
|
|
||||||
;
|
|
||||||
; Must be set to 2, to avoid two screenmode
|
|
||||||
; changes within a very short period of time.
|
|
||||||
|
|
||||||
display_atboot db 0 ; show boot screen messages ( 2-no )
|
|
||||||
|
|
||||||
preboot_graph dw 0 ; graph mode
|
|
||||||
x_save dw 0 ; x
|
|
||||||
y_save dw 0 ; y
|
|
||||||
number_vm dw 0 ;
|
|
||||||
;pixel_save dw 0 ; per to pixel
|
|
||||||
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
|
|
||||||
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
|
|
||||||
preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never)
|
|
||||||
preboot_device db 0 ; boot device
|
|
||||||
; (1-floppy 2-harddisk 3-kernel restart 4-format ram disk)
|
|
||||||
;!!!! 0 - autodetect !!!!
|
|
||||||
preboot_blogesc = 0 ; start immediately after bootlog
|
|
||||||
preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no)
|
|
||||||
|
|
||||||
if $>0x200
|
|
||||||
ERROR: prebooting parameters must fit in first sector!!!
|
|
||||||
end if
|
|
||||||
;hdsysimage db 'KOLIBRI IMG' ; load from
|
|
||||||
;image_save db 'KOLIBRI IMG' ; save to
|
|
@ -1,51 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;; PCI16.INC ;;
|
|
||||||
;; ;;
|
|
||||||
;; 16 bit PCI driver code ;;
|
|
||||||
;; ;;
|
|
||||||
;; Version 0.2 December 21st, 2002 ;;
|
|
||||||
;; ;;
|
|
||||||
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
|
|
||||||
;; ;;
|
|
||||||
;; See file COPYING for details ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
$Revision$
|
|
||||||
|
|
||||||
|
|
||||||
init_pci_16:
|
|
||||||
|
|
||||||
pushad
|
|
||||||
|
|
||||||
xor ax,ax
|
|
||||||
mov es,ax
|
|
||||||
mov byte [es:0x9020],1 ;default mechanism:1
|
|
||||||
mov ax,0xb101
|
|
||||||
int 0x1a
|
|
||||||
or ah,ah
|
|
||||||
jnz pci16skip
|
|
||||||
|
|
||||||
mov [es:0x9021],cl ;last PCI bus in system
|
|
||||||
mov [es:0x9022],bx
|
|
||||||
mov [es:0x9024],edi
|
|
||||||
|
|
||||||
; we have a PCI BIOS, so check which configuration mechanism(s)
|
|
||||||
; it supports
|
|
||||||
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2)
|
|
||||||
test al,1
|
|
||||||
jnz pci16skip
|
|
||||||
test al,2
|
|
||||||
jz pci16skip
|
|
||||||
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2
|
|
||||||
|
|
||||||
pci16skip:
|
|
||||||
|
|
||||||
mov ax,0x1000
|
|
||||||
mov es,ax
|
|
||||||
|
|
||||||
popad
|
|
@ -12,8 +12,6 @@
|
|||||||
mov es, cx
|
mov es, cx
|
||||||
mov di, 0x9080
|
mov di, 0x9080
|
||||||
mov byte [es:di-1], cl
|
mov byte [es:di-1], cl
|
||||||
cmp [preboot_biosdisk], 1
|
|
||||||
jnz bdde
|
|
||||||
mov dl, 80h
|
mov dl, 80h
|
||||||
bdds:
|
bdds:
|
||||||
mov ah, 15h
|
mov ah, 15h
|
||||||
|
@ -88,7 +88,6 @@ pci_data_sel equ (pci_data_32-gdts)
|
|||||||
;;
|
;;
|
||||||
;; Kernel16.inc
|
;; Kernel16.inc
|
||||||
;; - Bootcode.inc Hardware setup
|
;; - Bootcode.inc Hardware setup
|
||||||
;; - Pci16.inc PCI functions
|
|
||||||
;;
|
;;
|
||||||
;; Kernel32.inc
|
;; Kernel32.inc
|
||||||
;; - Sys32.inc Process management
|
;; - Sys32.inc Process management
|
||||||
@ -117,15 +116,9 @@ use16
|
|||||||
|
|
||||||
version db 'Kolibri-A version 0.1.0.0 ',13,10,13,10,0
|
version db 'Kolibri-A version 0.1.0.0 ',13,10,13,10,0
|
||||||
|
|
||||||
diff16 "preboot start: ",0,$
|
|
||||||
include "boot/preboot.inc"
|
|
||||||
|
|
||||||
diff16 "bootcode start: ",0,$
|
diff16 "bootcode start: ",0,$
|
||||||
include "boot/bootcode.inc" ; 16 bit system boot code
|
include "boot/bootcode.inc" ; 16 bit system boot code
|
||||||
|
|
||||||
diff16 "pci16 start: ",0,$
|
|
||||||
include "bus/pci/pci16.inc"
|
|
||||||
|
|
||||||
diff16 "biosdisk start: ",0,$
|
diff16 "biosdisk start: ",0,$
|
||||||
include "detect/biosdisk.inc"
|
include "detect/biosdisk.inc"
|
||||||
|
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
Ñïåöèôèêàöèÿ íà ïåðâè÷íûé çàãðóç÷èê KordOS.
|
|
||||||
Çàãðóç÷èê äîëæåí ïðåäîñòàâëÿòü ñëåäóþùèå ñåðâèñû:
|
|
||||||
1. Ïðè çàãðóçêå êîìïüþòåðà, ïîëó÷èâ óïðàâëåíèå îò BIOS'à, çàãðóæàòü
|
|
||||||
ôàéë loader èç ïàïêè kord ïî àäðåñó 1000:0000.
|
|
||||||
Ðàçìåð ôàéëà loader íå ïðåâîñõîäèò 30000h = 192 Kb.
|
|
||||||
2. Ïðè ýòîì óñòàíàâëèâàòü ñëåäóþùèå ðåãèñòðû:
|
|
||||||
ax èäåíòèôèöèðóåò óñòðîéñòâî:
|
|
||||||
al = òèï:
|
|
||||||
'f' - ôëîïèê
|
|
||||||
'h' - HDD
|
|
||||||
'c' - CD/DVD
|
|
||||||
'u' - USB ôëåøêà
|
|
||||||
'?' - íåèçâåñòíîå óñòðîéñòâî
|
|
||||||
ah = íîìåð óñòðîéñòâà (ñðåäè âñåõ óñòðîéñòâ ôèêñèðîâàííîãî òèïà)
|
|
||||||
bx = òèï ôàéëîâîé ñèñòåìû:
|
|
||||||
'12' = FAT12
|
|
||||||
'16' = FAT16
|
|
||||||
'32' = FAT32
|
|
||||||
'nt' = NTFS
|
|
||||||
'is' = ISO-9660
|
|
||||||
ds:si = far-óêàçàòåëü íà callback-ñåðâèñ
|
|
||||||
3. Ïðåäîñòàâëÿòü callback-ñåðâèñ äëÿ âòîðè÷íîãî çàãðóç÷èêà - far-ïðîöåäóðó:
|
|
||||||
íà âõîäå: ax = çàïðàøèâàåìàÿ ôóíêöèÿ
|
|
||||||
íà âûõîäå: CF=1, åñëè ôóíêöèÿ íå ïîääåðæèâàåòñÿ; CF=0 èíà÷å
|
|
||||||
Çàãðóç÷èê ìîæåò ðàçðóøàòü âñå ðåãèñòðû, âêëþ÷àÿ ñåãìåíòíûå,
|
|
||||||
çà èñêëþ÷åíèåì ss è sp.
|
|
||||||
4. Âñåãäà äîëæíà ïîääåðæèâàòüñÿ callback-ôóíêöèÿ 1:
|
|
||||||
íàçíà÷åíèå: ïðî÷èòàòü ôàéë, ðàñïîëîæåííûé íà çàãðóçî÷íîì óñòðîéñòâå
|
|
||||||
íà âõîäå: ax = 1, ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó:
|
|
||||||
dw:dw far-óêàçàòåëü íà áóôåð,
|
|
||||||
ïåðâîå ñëîâî - ñìåùåíèå, âòîðîå - ñåãìåíò
|
|
||||||
dw ìàêñèìàëüíîå ÷èñëî 4Kb-áëîêîâ äëÿ ÷òåíèÿ (0x1000 áàéò)
|
|
||||||
äîëæíî áûòü íåíóëåâûì è ñòðîãî ìåíüøå 0x100
|
|
||||||
ASCIIZ èìÿ ôàéëà â ôîðìàòå "<ïàïêà1>/<ïàïêà2>/<ôàéë>"
|
|
||||||
Åñëè èìÿ ôàéëà ñîäåðæèò ñèìâîëû èç ñòàðøåé ïîëîâèíû
|
|
||||||
ASCIIZ-òàáëèöû èëè íå ÿâëÿåòñÿ 8.3-èìåíåì (â ñìûñëå, îäíà èç êîìïîíåíò
|
|
||||||
èìåíè ôàéëà èìååò èìÿ äëèííåå 8 ñèìâîëîâ èëè ðàñøèðåíèå äëèííåå 3),
|
|
||||||
çàãðóç÷èê ìîæåò íå íàéòè òàêîé ôàéë, äàæå åñëè îí åñòü
|
|
||||||
(à ìîæåò è íàéòè).
|
|
||||||
íà âûõîäå: bx = ñòàòóñ:
|
|
||||||
0 = óñïåøíî
|
|
||||||
1 = ôàéë îêàçàëñÿ ñëèøêîì áîëüøèì, áóôåð çàïîëíåí öåëèêîì
|
|
||||||
è åñòü åù¸ äàííûå ôàéëà
|
|
||||||
2 = ôàéë íå íàéäåí
|
|
||||||
3 = ïðîèçîøëà îøèáêà ÷òåíèÿ
|
|
||||||
dx:ax = ðàçìåð ôàéëà èëè FFFF:FFFF, åñëè ôàéë íå íàéäåí
|
|
||||||
5. Âñåãäà äîëæíà ïîääåðæèâàòüñÿ callback-ôóíêöèÿ 2:
|
|
||||||
íàçíà÷åíèå: ïðîäîëæèòü ÷òåíèå ôàéëà, ÷àñòè÷íî çàãðóæåííîãî ôóíêöèåé 1
|
|
||||||
íà âõîäå: ax = 2, ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó:
|
|
||||||
dw:dw far-óêàçàòåëü íà áóôåð,
|
|
||||||
ïåðâîå ñëîâî - ñìåùåíèå, âòîðîå - ñåãìåíò
|
|
||||||
dw ìàêñèìàëüíîå ÷èñëî 4Kb-áëîêîâ äëÿ ÷òåíèÿ (0x1000 áàéò)
|
|
||||||
äîëæíî áûòü íåíóëåâûì è ñòðîãî ìåíüøå 0x100
|
|
||||||
íà âûõîäå: bx = ñòàòóñ:
|
|
||||||
0 = óñïåøíî
|
|
||||||
1 = ôàéë îêàçàëñÿ ñëèøêîì áîëüøèì, áóôåð çàïîëíåí öåëèêîì
|
|
||||||
è åñòü åù¸ äàííûå ôàéëà
|
|
||||||
3 = ïðîèçîøëà îøèáêà ÷òåíèÿ
|
|
||||||
dx:ax = ðàçìåð ôàéëà
|
|
||||||
Ôóíêöèþ ìîæíî âûçûâàòü òîëüêî â ñëó÷àå, êîãäà ïîñëåäíèé âûçîâ ôóíêöèè
|
|
||||||
1 è âñå ïîñëåäóþùèå âûçîâû ôóíêöèè 2 âåðíóëè bx=1 (èíûìè ñëîâàìè,
|
|
||||||
òîëüêî äëÿ ïðîäîëæåíèÿ çàãðóçêè ôàéëà, êîòîðûé óæå áûë ÷àñòè÷íî
|
|
||||||
çàãðóæåí, íî åù¸ íå çàãðóæåí ïîëíîñòüþ).
|
|
||||||
Çàãðóç÷èê ìîæåò áûòü óâåðåí, ÷òî äàííûå â îáëàñòÿõ ïàìÿòè 0-9000 è
|
|
||||||
60000-A0000 íå áóäóò ìîäèôèöèðîâàíû ÿäðîì.
|
|
@ -1,2 +0,0 @@
|
|||||||
@fasm -m 65535 kordldr.win.asm kordldr.win
|
|
||||||
@pause
|
|
@ -1,509 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
; in: ss:bp = 0:dat
|
|
||||||
; in: es:bx = address to load file
|
|
||||||
; in: ds:si -> ASCIIZ name
|
|
||||||
; in: cx = limit in sectors
|
|
||||||
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file has been loaded, bx=2 - file not found
|
|
||||||
; out: dx:ax = file size (0xFFFFFFFF if file not found)
|
|
||||||
load_file_fat:
|
|
||||||
mov eax, [bp + root_clus - dat]
|
|
||||||
mov [bp + cur_obj - dat], root_string
|
|
||||||
push es
|
|
||||||
push bx
|
|
||||||
push cx
|
|
||||||
.parse_dir_loop:
|
|
||||||
; convert name to FAT name
|
|
||||||
push [bp + cur_obj - dat]
|
|
||||||
push ax
|
|
||||||
mov [bp + cur_obj - dat], si
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
; convert ASCIIZ filename to FAT name
|
|
||||||
mov di, fat_filename
|
|
||||||
push di
|
|
||||||
mov cx, 8+3
|
|
||||||
mov al, ' '
|
|
||||||
rep stosb
|
|
||||||
pop di
|
|
||||||
mov cl, 8 ; 8 symbols per name
|
|
||||||
mov bl, 1
|
|
||||||
.nameloop:
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz .namedone
|
|
||||||
cmp al, '/'
|
|
||||||
jz .namedone
|
|
||||||
cmp al, '.'
|
|
||||||
jz .namedot
|
|
||||||
dec cx
|
|
||||||
js .badname
|
|
||||||
cmp al, 'a'
|
|
||||||
jb @f
|
|
||||||
cmp al, 'z'
|
|
||||||
ja @f
|
|
||||||
sub al, 'a'-'A'
|
|
||||||
@@:
|
|
||||||
stosb
|
|
||||||
jmp .nameloop
|
|
||||||
.namedot:
|
|
||||||
inc bx
|
|
||||||
jp .badname
|
|
||||||
add di, cx
|
|
||||||
mov cl, 3
|
|
||||||
jmp .nameloop
|
|
||||||
.badname:
|
|
||||||
mov si, badname_msg
|
|
||||||
jmp find_error_si
|
|
||||||
.namedone:
|
|
||||||
; scan directory
|
|
||||||
pop ax ; eax = cluster of directory
|
|
||||||
; high word of eax is preserved by operations above
|
|
||||||
push ds
|
|
||||||
push si
|
|
||||||
; read a folder sector-by-sector and scan
|
|
||||||
; first, try to use the cache
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov bx, -2
|
|
||||||
mov cx, [bp + rootcache_size - dat]
|
|
||||||
cmp [bp + root_clus - dat], eax
|
|
||||||
jz .lookcache_root
|
|
||||||
mov di, foldcache_mark
|
|
||||||
xor bx, bx
|
|
||||||
mov cx, [bp + cachelimit - dat]
|
|
||||||
@@:
|
|
||||||
lea si, [di+bx]
|
|
||||||
mov edx, dword [foldcache_clus+si-foldcache_mark+bx]
|
|
||||||
cmp edx, eax
|
|
||||||
jz .cacheok
|
|
||||||
test edx, edx
|
|
||||||
jz .cacheadd ; the cache has place for new entry
|
|
||||||
inc bx
|
|
||||||
inc bx
|
|
||||||
dec cx
|
|
||||||
js @b
|
|
||||||
; the folder is not present in the cache, so add it
|
|
||||||
; the cache is full; find the oldest entry and replace it with the new one
|
|
||||||
mov bx, -2
|
|
||||||
mov dx, [bp + cachelimit - dat]
|
|
||||||
@@:
|
|
||||||
inc bx
|
|
||||||
inc bx
|
|
||||||
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
|
|
||||||
jnz @b
|
|
||||||
.cacheadd:
|
|
||||||
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
|
|
||||||
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
|
|
||||||
lea si, [di+bx]
|
|
||||||
mov dword [foldcache_clus+si-foldcache_mark+bx], eax
|
|
||||||
.cacheok:
|
|
||||||
; update cache marks
|
|
||||||
mov dx, [di+bx]
|
|
||||||
mov cx, [foldcache_size+di-foldcache_mark+bx]
|
|
||||||
mov di, [bp + cachelimit - dat]
|
|
||||||
add di, di
|
|
||||||
.cacheupdate:
|
|
||||||
cmp [foldcache_mark+di], dx
|
|
||||||
adc [foldcache_mark+di], 0
|
|
||||||
dec di
|
|
||||||
dec di
|
|
||||||
jns .cacheupdate
|
|
||||||
and [foldcache_mark+bx], 0
|
|
||||||
; done, bx contains (position in cache)*2
|
|
||||||
.lookcache_root:
|
|
||||||
; bx = (position in cache)*2 for non-root folders; bx = -2 for root folder
|
|
||||||
;mov dx, bx
|
|
||||||
;shl dx, 8
|
|
||||||
;add dx, 0x9200
|
|
||||||
lea dx, [bx + 0x92]
|
|
||||||
xchg dl, dh
|
|
||||||
mov ds, dx
|
|
||||||
mov si, fat_filename ; ss:si -> filename in FAT style
|
|
||||||
call fat_scan_for_filename
|
|
||||||
jz .lookup_done
|
|
||||||
; cache miss, read folder data from disk
|
|
||||||
; we are reading parent directory, it can result in disk read errors; restore [cur_obj]
|
|
||||||
mov di, sp
|
|
||||||
mov bx, [bp + cur_obj - dat]
|
|
||||||
xchg bx, [ss:di+4]
|
|
||||||
mov [bp + cur_obj - dat], bx
|
|
||||||
mov bx, cx
|
|
||||||
add bx, 0xF
|
|
||||||
shr bx, 4
|
|
||||||
shl cx, 5
|
|
||||||
mov di, cx ; es:di -> free space in cache entry
|
|
||||||
; external loop: scan clusters
|
|
||||||
.folder_next_cluster:
|
|
||||||
; internal loop: scan sectors in cluster
|
|
||||||
movzx ecx, byte [ss:0x320D] ; BPB_SecPerClus
|
|
||||||
push eax
|
|
||||||
; FAT12/16 root - special handling
|
|
||||||
test eax, eax
|
|
||||||
jnz .folder_notroot
|
|
||||||
mov cx, [ss:0x3211] ; BPB_RootEntCnt
|
|
||||||
mov dx, cx
|
|
||||||
add cx, 0xF
|
|
||||||
rcr cx, 1
|
|
||||||
shr cx, 3
|
|
||||||
mov eax, [bp + root_start - dat]
|
|
||||||
jmp .folder_next_sector
|
|
||||||
.folder_notroot:
|
|
||||||
mul ecx
|
|
||||||
add eax, [bp + data_start - dat]
|
|
||||||
.folder_next_sector:
|
|
||||||
sub dx, 0x10
|
|
||||||
; skip first bx sectors
|
|
||||||
dec bx
|
|
||||||
jns .folder_skip_sector
|
|
||||||
push cx
|
|
||||||
push es di
|
|
||||||
push 0x8000
|
|
||||||
pop es
|
|
||||||
xor bx, bx
|
|
||||||
mov cx, 1
|
|
||||||
push es
|
|
||||||
call read
|
|
||||||
jc ..found_disk_error
|
|
||||||
; copy data to the cache...
|
|
||||||
pop ds
|
|
||||||
pop di es
|
|
||||||
cmp di, 0x2000 ; ...if there is free space, of course
|
|
||||||
jae @f
|
|
||||||
pusha
|
|
||||||
mov cx, 0x100
|
|
||||||
xor si, si
|
|
||||||
rep movsw
|
|
||||||
mov di, es
|
|
||||||
shr di, 8
|
|
||||||
cmp di, 0x90
|
|
||||||
jz .update_rootcache_size
|
|
||||||
add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache
|
|
||||||
jmp .updated_cachesize
|
|
||||||
.update_rootcache_size:
|
|
||||||
mov cl, 0x10
|
|
||||||
cmp cx, dx
|
|
||||||
jb @f
|
|
||||||
mov cx, dx
|
|
||||||
@@:
|
|
||||||
add [bp + rootcache_size - dat], cx
|
|
||||||
.updated_cachesize:
|
|
||||||
popa
|
|
||||||
@@:
|
|
||||||
push es
|
|
||||||
mov cl, 0x10 ; ch=0 at this point
|
|
||||||
cmp cx, dx
|
|
||||||
jb @f
|
|
||||||
mov cx, dx
|
|
||||||
@@:
|
|
||||||
call fat_scan_for_filename
|
|
||||||
pop es
|
|
||||||
pop cx
|
|
||||||
jz .lookup_done_pop
|
|
||||||
.folder_skip_sector:
|
|
||||||
inc eax
|
|
||||||
loop .folder_next_sector
|
|
||||||
pop eax ; eax = current cluster
|
|
||||||
test eax, eax
|
|
||||||
jz @f
|
|
||||||
call [bp + get_next_cluster_ptr - dat]
|
|
||||||
jc .folder_next_cluster
|
|
||||||
@@:
|
|
||||||
stc
|
|
||||||
push eax
|
|
||||||
.lookup_done_pop:
|
|
||||||
pop eax
|
|
||||||
.lookup_done:
|
|
||||||
pop si
|
|
||||||
; CF=1 <=> failed
|
|
||||||
jnc .found
|
|
||||||
pop ds
|
|
||||||
pop [bp + cur_obj - dat]
|
|
||||||
mov si, error_not_found
|
|
||||||
jmp find_error_si
|
|
||||||
.found:
|
|
||||||
mov eax, [di+20-2]
|
|
||||||
mov edx, [di+28]
|
|
||||||
mov ax, [di+26] ; get cluster
|
|
||||||
test byte [di+11], 10h ; directory?
|
|
||||||
pop ds
|
|
||||||
pop [bp + cur_obj - dat] ; forget old [cur_obj]
|
|
||||||
jz .regular_file
|
|
||||||
cmp byte [si-1], 0
|
|
||||||
jnz .parse_dir_loop
|
|
||||||
..directory_error:
|
|
||||||
mov si, directory_string
|
|
||||||
jmp find_error_si
|
|
||||||
.regular_file:
|
|
||||||
cmp byte [si-1], 0
|
|
||||||
jz @f
|
|
||||||
..notdir_error:
|
|
||||||
mov si, notdir_string
|
|
||||||
jmp find_error_si
|
|
||||||
@@:
|
|
||||||
; ok, we have found a regular file and the caller requested it
|
|
||||||
; parse FAT chunk
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov di, 0x4005
|
|
||||||
mov byte [di-5], 1 ; non-resident attribute
|
|
||||||
mov dword [di-4], 1
|
|
||||||
stosd
|
|
||||||
pop cx
|
|
||||||
push cx
|
|
||||||
.parsefat:
|
|
||||||
call [bp + get_next_cluster_ptr - dat]
|
|
||||||
jnc .done
|
|
||||||
mov esi, [di-8]
|
|
||||||
add esi, [di-4]
|
|
||||||
cmp eax, esi
|
|
||||||
jz .contc
|
|
||||||
mov dword [di], 1
|
|
||||||
scasd
|
|
||||||
stosd
|
|
||||||
jmp @f
|
|
||||||
.contc:
|
|
||||||
inc dword [di-8]
|
|
||||||
@@:
|
|
||||||
sub cl, [0x320D]
|
|
||||||
sbb ch, 0
|
|
||||||
ja .parsefat
|
|
||||||
.done:
|
|
||||||
xor eax, eax
|
|
||||||
stosd
|
|
||||||
mov si, 0x4000
|
|
||||||
load_file_common_end:
|
|
||||||
xor ecx, ecx
|
|
||||||
pop cx
|
|
||||||
pop bx
|
|
||||||
pop es
|
|
||||||
mov [bp + filesize - dat], edx
|
|
||||||
mov [bp + sectors_read - dat], ecx
|
|
||||||
add edx, 0x1FF
|
|
||||||
shr edx, 9
|
|
||||||
mov [bp + filesize_sectors - dat], edx
|
|
||||||
cmp edx, ecx
|
|
||||||
seta al
|
|
||||||
mov ah, 0
|
|
||||||
push ax
|
|
||||||
call read_file_chunk
|
|
||||||
continue_load_common_end:
|
|
||||||
mov [bp + cur_chunk_ptr - dat], si
|
|
||||||
pop bx
|
|
||||||
mov ax, word [bp + filesize - dat]
|
|
||||||
mov dx, word [bp + filesize+2 - dat]
|
|
||||||
jnc @f
|
|
||||||
mov bl, 3 ; read error
|
|
||||||
@@:
|
|
||||||
ret
|
|
||||||
|
|
||||||
continue_load_file:
|
|
||||||
; es:bx -> buffer for output, ecx = cx = number of sectors
|
|
||||||
mov si, [bp + cur_chunk_ptr - dat]
|
|
||||||
push ecx
|
|
||||||
add ecx, [bp + sectors_read - dat]
|
|
||||||
mov [bp + sectors_read - dat], ecx
|
|
||||||
cmp [bp + filesize_sectors - dat], ecx
|
|
||||||
pop ecx
|
|
||||||
seta al
|
|
||||||
mov ah, 0
|
|
||||||
push ax
|
|
||||||
push continue_load_common_end
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
cmp [bp + cur_chunk_resident - dat], ah
|
|
||||||
jnz .nonresident
|
|
||||||
.resident:
|
|
||||||
mov ax, word [bp + num_sectors - dat]
|
|
||||||
jmp read_file_chunk.resident.continue
|
|
||||||
.nonresident:
|
|
||||||
mov eax, [bp + cur_cluster - dat]
|
|
||||||
mov edx, [bp + num_sectors - dat]
|
|
||||||
add eax, [bp + cur_delta - dat]
|
|
||||||
jmp read_file_chunk.nonresident.continue
|
|
||||||
|
|
||||||
fat_scan_for_filename:
|
|
||||||
; in: ss:si -> 11-bytes FAT name
|
|
||||||
; in: ds:0 -> part of directory data
|
|
||||||
; in: cx = number of entries
|
|
||||||
; out: if found: CF=0, ZF=1, es:di -> directory entry
|
|
||||||
; out: if not found, but continue required: CF=1 and ZF=0
|
|
||||||
; out: if not found and zero item reached: CF=1 and ZF=1
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
xor di, di
|
|
||||||
push cx
|
|
||||||
jcxz .noent
|
|
||||||
.loop:
|
|
||||||
cmp byte [di], 0
|
|
||||||
jz .notfound
|
|
||||||
test byte [di+11], 8 ; volume label?
|
|
||||||
jnz .cont ; ignore volume labels
|
|
||||||
pusha
|
|
||||||
mov cx, 11
|
|
||||||
repz cmps byte [ss:si], byte [es:di]
|
|
||||||
popa
|
|
||||||
jz .done
|
|
||||||
.cont:
|
|
||||||
add di, 0x20
|
|
||||||
loop .loop
|
|
||||||
.noent:
|
|
||||||
inc cx ; clear ZF flag
|
|
||||||
.notfound:
|
|
||||||
stc
|
|
||||||
.done:
|
|
||||||
pop cx
|
|
||||||
ret
|
|
||||||
|
|
||||||
fat12_get_next_cluster:
|
|
||||||
; in: ax = cluster (high word of eax is zero)
|
|
||||||
; out: if there is next cluster: CF=1, ax = next cluster
|
|
||||||
; out: if there is no next cluster: CF=0
|
|
||||||
push si
|
|
||||||
push ds
|
|
||||||
push 0x6000
|
|
||||||
pop ds
|
|
||||||
mov si, ax
|
|
||||||
shr si, 1
|
|
||||||
add si, ax
|
|
||||||
test al, 1
|
|
||||||
lodsw
|
|
||||||
jz @f
|
|
||||||
shr ax, 4
|
|
||||||
@@:
|
|
||||||
and ax, 0xFFF
|
|
||||||
cmp ax, 0xFF7
|
|
||||||
pop ds si
|
|
||||||
ret
|
|
||||||
|
|
||||||
fat16_get_next_cluster:
|
|
||||||
; in: ax = cluster (high word of eax is zero)
|
|
||||||
; out: if there is next cluster: CF=1, ax = next cluster
|
|
||||||
; out: if there is no next cluster: CF=0
|
|
||||||
; each sector contains 200h bytes = 100h FAT entries
|
|
||||||
; so ah = # of sector, al = offset in sector
|
|
||||||
push si
|
|
||||||
mov si, ax
|
|
||||||
shr si, 8
|
|
||||||
; calculate segment for this sector of FAT table
|
|
||||||
; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si)
|
|
||||||
; segment = 6000 + 20*si, offset = 0
|
|
||||||
push es
|
|
||||||
push si
|
|
||||||
shl si, 5
|
|
||||||
add si, 0x6000
|
|
||||||
mov es, si
|
|
||||||
pop si
|
|
||||||
cmp byte [ss:0x3400+si], 0 ; sector already loaded?
|
|
||||||
jnz .noread
|
|
||||||
; load corresponding sector, try all FATs if disk read error detected
|
|
||||||
pusha
|
|
||||||
movzx di, byte [ss:0x3210] ; BPB_NumFATs
|
|
||||||
xor bx, bx
|
|
||||||
mov ax, [ss:0x320E] ; BPB_RsvdSecCnt
|
|
||||||
xor dx, dx
|
|
||||||
add ax, si
|
|
||||||
adc dx, bx
|
|
||||||
@@:
|
|
||||||
push es
|
|
||||||
push dx ax
|
|
||||||
pop eax
|
|
||||||
mov cx, 1 ; read 1 sector
|
|
||||||
call read
|
|
||||||
pop es
|
|
||||||
jnc @f
|
|
||||||
add ax, [ss:0x3216] ; BPB_FATSz16
|
|
||||||
adc dx, bx
|
|
||||||
dec di
|
|
||||||
jnz @b
|
|
||||||
..found_disk_error:
|
|
||||||
mov si, disk_error_msg
|
|
||||||
jmp find_error_si
|
|
||||||
@@:
|
|
||||||
popa
|
|
||||||
.noread:
|
|
||||||
mov si, ax
|
|
||||||
and si, 0xFF
|
|
||||||
add si, si
|
|
||||||
mov ax, [es:si]
|
|
||||||
pop es
|
|
||||||
cmp ax, 0xFFF7
|
|
||||||
pop si
|
|
||||||
ret
|
|
||||||
|
|
||||||
fat32_get_next_cluster:
|
|
||||||
; in: eax = cluster
|
|
||||||
; out: if there is next cluster: CF=1, eax = next cluster
|
|
||||||
; out: if there is no next cluster: CF=0
|
|
||||||
push di
|
|
||||||
push ax
|
|
||||||
shr eax, 7
|
|
||||||
; eax = FAT sector number; look in cache
|
|
||||||
push si
|
|
||||||
mov si, cache1head
|
|
||||||
call cache_lookup
|
|
||||||
pop si
|
|
||||||
jnc .noread
|
|
||||||
; read FAT, try all FATs if disk read error detected
|
|
||||||
push es
|
|
||||||
pushad
|
|
||||||
movzx edx, word [ss:0x320E] ; BPB_RsvdSecCnt
|
|
||||||
add eax, edx
|
|
||||||
movzx si, byte [ss:0x3210] ; BPB_NumFATs
|
|
||||||
@@:
|
|
||||||
lea cx, [di - 0x3400 + (0x6000 shr (9-3))]
|
|
||||||
shl cx, 9-3
|
|
||||||
mov es, cx
|
|
||||||
xor bx, bx
|
|
||||||
mov cx, 1
|
|
||||||
call read
|
|
||||||
jnc @f
|
|
||||||
add eax, [ss:0x3224] ; BPB_FATSz32
|
|
||||||
dec si
|
|
||||||
jnz @b
|
|
||||||
jmp ..found_disk_error
|
|
||||||
@@:
|
|
||||||
popad
|
|
||||||
pop es
|
|
||||||
.noread:
|
|
||||||
; get requested item
|
|
||||||
lea ax, [di - 0x3400 + (0x6000 shr (9-3))]
|
|
||||||
pop di
|
|
||||||
and di, 0x7F
|
|
||||||
shl di, 2
|
|
||||||
shl ax, 9-3
|
|
||||||
push ds
|
|
||||||
mov ds, ax
|
|
||||||
and byte [di+3], 0x0F
|
|
||||||
mov eax, [di]
|
|
||||||
pop ds
|
|
||||||
pop di
|
|
||||||
;and eax, 0x0FFFFFFF
|
|
||||||
cmp eax, 0x0FFFFFF7
|
|
||||||
ret
|
|
@ -1,921 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
; KordOS bootloader, based on mtldr, KolibriOS bootloader, by diamond
|
|
||||||
; It is used when main bootloader is Windows loader.
|
|
||||||
|
|
||||||
; this code is loaded:
|
|
||||||
; NT/2k/XP: by ntldr to 0D00:0000
|
|
||||||
; 9x: by io.sys from config.sys to xxxx:0100
|
|
||||||
; Vista: by bootmgr to 0000:7C00
|
|
||||||
format binary
|
|
||||||
use16
|
|
||||||
|
|
||||||
; in any case, we relocate this code to 0000:0600
|
|
||||||
org 0x600
|
|
||||||
; entry point for 9x and Vista booting
|
|
||||||
call @f
|
|
||||||
db 'NTFS'
|
|
||||||
@@:
|
|
||||||
pop si
|
|
||||||
sub si, 3
|
|
||||||
cmp si, 100h
|
|
||||||
jnz boot_vista
|
|
||||||
mov si, load_question + 100h - 600h
|
|
||||||
call out_string
|
|
||||||
; mov si, answer + 100h - 0600h ; already is
|
|
||||||
xxy: mov ah, 0
|
|
||||||
int 16h
|
|
||||||
or al, 20h
|
|
||||||
mov [si], al
|
|
||||||
cmp al, 'y'
|
|
||||||
jz xxz
|
|
||||||
cmp al, 'n'
|
|
||||||
jnz xxy
|
|
||||||
; continue load Windows
|
|
||||||
; call out_string
|
|
||||||
; ret
|
|
||||||
out_string:
|
|
||||||
push bx
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz @f
|
|
||||||
mov ah, 0Eh
|
|
||||||
mov bx, 7
|
|
||||||
int 10h
|
|
||||||
jmp @b
|
|
||||||
@@:
|
|
||||||
pop bx
|
|
||||||
ret
|
|
||||||
xxz:
|
|
||||||
; boot KordOS
|
|
||||||
call out_string
|
|
||||||
; 9x bootloader has already hooked some interrupts; to correctly remove all DOS handlers,
|
|
||||||
; issue int 19h (reboot interrupt) and trace its DOS handler until original BIOS handler is reached
|
|
||||||
xor di, di
|
|
||||||
mov ds, di
|
|
||||||
mov word [di+4], new01handler + 100h - 600h
|
|
||||||
mov [di+6], cs
|
|
||||||
pushf
|
|
||||||
pop ax
|
|
||||||
or ah, 1
|
|
||||||
push ax
|
|
||||||
popf
|
|
||||||
; we cannot issue INT 19h directly, because INT command clears TF
|
|
||||||
; int 19h ; don't issue it directly, because INT command clears TF
|
|
||||||
; so instead we use direct call
|
|
||||||
; pushf ; there will be no IRET
|
|
||||||
call far [di + 19h*4]
|
|
||||||
xxt:
|
|
||||||
xor di, di
|
|
||||||
mov ds, di
|
|
||||||
cmp word [di + 8*4+2], 0F000h
|
|
||||||
jz @f
|
|
||||||
les bx, [di + 8*4]
|
|
||||||
mov eax, [es:bx+1]
|
|
||||||
mov [di + 8*4], eax
|
|
||||||
@@:
|
|
||||||
mov si, 100h
|
|
||||||
boot_vista:
|
|
||||||
; relocate cs:si -> 0000:0600
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
xor ax, ax
|
|
||||||
mov es, ax
|
|
||||||
mov di, 0x600
|
|
||||||
mov cx, 2000h/2
|
|
||||||
rep movsw
|
|
||||||
jmp 0:real_entry
|
|
||||||
|
|
||||||
load_question db 'Load KordOS? [y/n]: ',0
|
|
||||||
answer db ?
|
|
||||||
db 13,10,0
|
|
||||||
|
|
||||||
new01handler:
|
|
||||||
; [sp]=ip, [sp+2]=cs, [sp+4]=flags
|
|
||||||
push bp
|
|
||||||
mov bp, sp
|
|
||||||
push ds
|
|
||||||
lds bp, [bp+2]
|
|
||||||
cmp word [ds:bp], 19cdh
|
|
||||||
jz xxt
|
|
||||||
pop ds
|
|
||||||
pop bp
|
|
||||||
iret
|
|
||||||
|
|
||||||
; read from hard disk
|
|
||||||
; in: eax = absolute sector
|
|
||||||
; cx = number of sectors
|
|
||||||
; es:bx -> buffer
|
|
||||||
; out: CF=1 if error
|
|
||||||
read:
|
|
||||||
pushad
|
|
||||||
add eax, [bp + partition_start - dat]
|
|
||||||
cmp [bp + use_lba - dat], 0
|
|
||||||
jz .chs
|
|
||||||
; LBA read
|
|
||||||
push ds
|
|
||||||
.lbado:
|
|
||||||
push ax
|
|
||||||
push cx
|
|
||||||
cmp cx, 0x7F
|
|
||||||
jbe @f
|
|
||||||
mov cx, 0x7F
|
|
||||||
@@:
|
|
||||||
; create disk address packet on the stack
|
|
||||||
; dq starting LBA
|
|
||||||
push 0
|
|
||||||
push 0
|
|
||||||
push eax
|
|
||||||
; dd buffer
|
|
||||||
push es
|
|
||||||
push bx
|
|
||||||
; dw number of blocks to transfer (no more than 0x7F)
|
|
||||||
push cx
|
|
||||||
; dw packet size in bytes
|
|
||||||
push 10h
|
|
||||||
; issue BIOS call
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov si, sp
|
|
||||||
mov dl, [bp + boot_drive - dat]
|
|
||||||
mov ah, 42h
|
|
||||||
int 13h
|
|
||||||
jc .disk_error_lba
|
|
||||||
add sp, 10h ; restore stack
|
|
||||||
; increase current sector & buffer; decrease number of sectors
|
|
||||||
movzx esi, cx
|
|
||||||
mov ax, es
|
|
||||||
shl cx, 5
|
|
||||||
add ax, cx
|
|
||||||
mov es, ax
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
add eax, esi
|
|
||||||
sub cx, si
|
|
||||||
jnz .lbado
|
|
||||||
pop ds
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
.disk_error_lba:
|
|
||||||
add sp, 14h
|
|
||||||
pop ds
|
|
||||||
popad
|
|
||||||
stc
|
|
||||||
ret
|
|
||||||
|
|
||||||
.chs:
|
|
||||||
pusha
|
|
||||||
pop edi ; loword(edi) = di, hiword(edi) = si
|
|
||||||
push bx
|
|
||||||
|
|
||||||
; eax / (SectorsPerTrack) -> eax, remainder bx
|
|
||||||
movzx esi, [bp + sectors - dat]
|
|
||||||
xor edx, edx
|
|
||||||
div esi
|
|
||||||
mov bx, dx ; bx = sector-1
|
|
||||||
|
|
||||||
; eax -> dx:ax
|
|
||||||
push eax
|
|
||||||
pop ax
|
|
||||||
pop dx
|
|
||||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
|
||||||
div [bp + heads - dat]
|
|
||||||
|
|
||||||
; number of sectors: read no more than to end of track
|
|
||||||
sub si, bx
|
|
||||||
cmp cx, si
|
|
||||||
jbe @f
|
|
||||||
mov cx, si
|
|
||||||
@@:
|
|
||||||
|
|
||||||
inc bx
|
|
||||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector
|
|
||||||
; convert to int13 format
|
|
||||||
movzx edi, cx
|
|
||||||
mov dh, dl
|
|
||||||
mov dl, [bp + boot_drive - dat]
|
|
||||||
shl ah, 6
|
|
||||||
mov ch, al
|
|
||||||
mov al, cl
|
|
||||||
mov cl, bl
|
|
||||||
or cl, ah
|
|
||||||
pop bx
|
|
||||||
mov si, 3
|
|
||||||
mov ah, 2
|
|
||||||
@@:
|
|
||||||
push ax
|
|
||||||
int 13h
|
|
||||||
jnc @f
|
|
||||||
xor ax, ax
|
|
||||||
int 13h ; reset drive
|
|
||||||
pop ax
|
|
||||||
dec si
|
|
||||||
jnz @b
|
|
||||||
add sp, 12
|
|
||||||
popad
|
|
||||||
stc
|
|
||||||
ret
|
|
||||||
@@:
|
|
||||||
pop ax
|
|
||||||
mov ax, es
|
|
||||||
mov cx, di
|
|
||||||
shl cx, 5
|
|
||||||
add ax, cx
|
|
||||||
mov es, ax
|
|
||||||
push edi
|
|
||||||
popa
|
|
||||||
add eax, edi
|
|
||||||
sub cx, di
|
|
||||||
jnz .chs
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
disk_error2 db 'Fatal: cannot read partitions info: '
|
|
||||||
disk_error_msg db 'disk read error',0
|
|
||||||
disk_params_msg db 'Fatal: cannot get drive parameters',0
|
|
||||||
start_msg db 2,' KordOS bootloader',13,10,0
|
|
||||||
part_msg db 'looking at partition '
|
|
||||||
part_char db '0' ; will be incremented before writing message
|
|
||||||
db ' ... ',0
|
|
||||||
errfs_msg db 'unknown filesystem',13,10,0
|
|
||||||
fatxx_msg db 'FATxx'
|
|
||||||
newline db 13,10,0
|
|
||||||
ntfs_msg db 'NTFS',13,10,0
|
|
||||||
error_msg db 'Error'
|
|
||||||
colon db ': ',0
|
|
||||||
root_string db '\',0
|
|
||||||
nomem_msg db 'No memory',0
|
|
||||||
filesys_string db '(filesystem)',0
|
|
||||||
directory_string db 'is a directory',0
|
|
||||||
notdir_string db 'not a directory',0
|
|
||||||
|
|
||||||
; entry point for NT/2k/XP booting
|
|
||||||
; ntldr loads our code to 0D00:0000 and jumps to 0D00:0256
|
|
||||||
repeat 600h + 256h - $
|
|
||||||
db 1 ; any data can be here; 1 in ASCII is a nice face :)
|
|
||||||
end repeat
|
|
||||||
; cs=es=0D00, ds=07C0, ss=0
|
|
||||||
; esi=edi=ebp=0, esp=7C00
|
|
||||||
xor si, si
|
|
||||||
jmp boot_vista
|
|
||||||
|
|
||||||
real_entry:
|
|
||||||
; ax = 0
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
; our stack is 4 Kb: memory range 2000-3000
|
|
||||||
mov ss, ax
|
|
||||||
mov sp, 3000h
|
|
||||||
mov bp, dat
|
|
||||||
sti ; just for case
|
|
||||||
; say hi to user
|
|
||||||
mov si, start_msg
|
|
||||||
call out_string
|
|
||||||
; we are booting from hard disk identified by [boot_drive]
|
|
||||||
mov dl, [bp + boot_drive - dat]
|
|
||||||
; is LBA supported?
|
|
||||||
mov [bp + use_lba - dat], 0
|
|
||||||
mov ah, 41h
|
|
||||||
mov bx, 55AAh
|
|
||||||
int 13h
|
|
||||||
jc .no_lba
|
|
||||||
cmp bx, 0AA55h
|
|
||||||
jnz .no_lba
|
|
||||||
test cl, 1
|
|
||||||
jz .no_lba
|
|
||||||
inc [bp + use_lba - dat]
|
|
||||||
jmp disk_params_ok
|
|
||||||
.no_lba:
|
|
||||||
; get drive geometry
|
|
||||||
mov ah, 8
|
|
||||||
mov dl, [bp + boot_drive - dat]
|
|
||||||
int 13h
|
|
||||||
jnc @f
|
|
||||||
mov si, disk_params_msg
|
|
||||||
call out_string
|
|
||||||
jmp $
|
|
||||||
@@:
|
|
||||||
movzx ax, dh
|
|
||||||
inc ax
|
|
||||||
mov [bp + heads - dat], ax
|
|
||||||
and cx, 3Fh
|
|
||||||
mov [bp + sectors - dat], cx
|
|
||||||
disk_params_ok:
|
|
||||||
; determine size of cache for folders
|
|
||||||
int 12h ; ax = size of available base memory in Kb
|
|
||||||
sub ax, 94000h / 1024
|
|
||||||
jc nomem
|
|
||||||
shr ax, 3
|
|
||||||
mov [bp + cachelimit - dat], ax ; size of cache - 1
|
|
||||||
; scan all partitions
|
|
||||||
new_partition_ex:
|
|
||||||
xor eax, eax ; read first sector of current disk area
|
|
||||||
mov [bp + extended_part_cur - dat], eax ; no extended partition yet
|
|
||||||
mov [bp + cur_partition_ofs - dat], 31BEh ; start from first partition
|
|
||||||
push es
|
|
||||||
mov cx, 1
|
|
||||||
mov bx, 3000h
|
|
||||||
call read
|
|
||||||
pop es
|
|
||||||
jnc new_partition
|
|
||||||
mov si, disk_error2
|
|
||||||
call out_string
|
|
||||||
jmp $
|
|
||||||
new_partition:
|
|
||||||
mov bx, [bp + cur_partition_ofs - dat]
|
|
||||||
mov al, [bx+4] ; partition type
|
|
||||||
test al, al
|
|
||||||
jz next_partition
|
|
||||||
cmp al, 5
|
|
||||||
jz @f
|
|
||||||
cmp al, 0xF
|
|
||||||
jnz not_extended
|
|
||||||
@@:
|
|
||||||
; extended partition
|
|
||||||
mov eax, [bx+8] ; partition start
|
|
||||||
add eax, [bp + extended_part_start - dat]
|
|
||||||
mov [bp + extended_part_cur - dat], eax
|
|
||||||
next_partition:
|
|
||||||
add [bp + cur_partition_ofs - dat], 10h
|
|
||||||
cmp [bp + cur_partition_ofs - dat], 31FEh
|
|
||||||
jb new_partition
|
|
||||||
mov eax, [bp + extended_part_cur - dat]
|
|
||||||
test eax, eax
|
|
||||||
jz partitions_done
|
|
||||||
cmp [bp + extended_part_start - dat], 0
|
|
||||||
jnz @f
|
|
||||||
mov [bp + extended_part_start - dat], eax
|
|
||||||
@@:
|
|
||||||
mov [bp + extended_parent - dat], eax
|
|
||||||
mov [bp + partition_start - dat], eax
|
|
||||||
jmp new_partition_ex
|
|
||||||
partitions_done:
|
|
||||||
mov si, total_kaput
|
|
||||||
call out_string
|
|
||||||
jmp $
|
|
||||||
not_extended:
|
|
||||||
mov eax, [bx+8]
|
|
||||||
add eax, [bp + extended_parent - dat]
|
|
||||||
mov [bp + partition_start - dat], eax
|
|
||||||
; try to load from current partition
|
|
||||||
; inform user
|
|
||||||
mov si, part_msg
|
|
||||||
inc [si + part_char - part_msg]
|
|
||||||
call out_string
|
|
||||||
; read bootsector
|
|
||||||
xor eax, eax
|
|
||||||
mov [bp + cur_obj - dat], filesys_string
|
|
||||||
push es
|
|
||||||
mov cx, 1
|
|
||||||
mov bx, 3200h
|
|
||||||
call read
|
|
||||||
pop es
|
|
||||||
mov si, disk_error_msg
|
|
||||||
jc find_error_si
|
|
||||||
movzx si, byte [bx+13]
|
|
||||||
mov word [bp + sect_per_clust - dat], si
|
|
||||||
test si, si
|
|
||||||
jz unknown_fs
|
|
||||||
lea ax, [si-1]
|
|
||||||
test si, ax
|
|
||||||
jnz unknown_fs
|
|
||||||
; determine file system
|
|
||||||
; Number of bytes per sector == 0x200 (this loader assumes that physical sector size is 200h)
|
|
||||||
cmp word [bx+11], 0x200
|
|
||||||
jnz unknown_fs
|
|
||||||
; is it NTFS?
|
|
||||||
cmp dword [bx+3], 'NTFS'
|
|
||||||
jnz not_ntfs
|
|
||||||
cmp byte [bx+16], bl
|
|
||||||
jz ntfs
|
|
||||||
not_ntfs:
|
|
||||||
; is it FAT? FAT12/FAT16/FAT32?
|
|
||||||
; get count of sectors to dword in cx:si
|
|
||||||
mov si, [bx+19]
|
|
||||||
xor cx, cx
|
|
||||||
test si, si
|
|
||||||
jnz @f
|
|
||||||
mov si, [bx+32]
|
|
||||||
mov cx, [bx+34]
|
|
||||||
@@:
|
|
||||||
xor eax, eax
|
|
||||||
; subtract size of system area
|
|
||||||
sub si, [bx+14] ; BPB_ResvdSecCnt
|
|
||||||
sbb cx, ax
|
|
||||||
mov ax, [bx+17] ; BPB_RootEntCnt
|
|
||||||
add ax, 0xF
|
|
||||||
rcr ax, 1
|
|
||||||
shr ax, 3
|
|
||||||
sub si, ax
|
|
||||||
sbb cx, 0
|
|
||||||
push cx
|
|
||||||
push si
|
|
||||||
mov ax, word [bx+22]
|
|
||||||
test ax, ax
|
|
||||||
jnz @f
|
|
||||||
mov eax, [bx+36]
|
|
||||||
@@:
|
|
||||||
movzx ecx, byte [bx+16]
|
|
||||||
imul ecx, eax
|
|
||||||
pop eax
|
|
||||||
sub eax, ecx
|
|
||||||
; now eax = count of sectors in the data region
|
|
||||||
xor edx, edx
|
|
||||||
div [bp + sect_per_clust - dat]
|
|
||||||
; now eax = count of clusters in the data region
|
|
||||||
mov si, fatxx_msg
|
|
||||||
cmp eax, 0xFFF5
|
|
||||||
jae test_fat32
|
|
||||||
; test magic value in FAT bootsector - FAT12/16 bootsector has it at the offset +38
|
|
||||||
cmp byte [bx+38], 0x29
|
|
||||||
jnz not_fat
|
|
||||||
cmp ax, 0xFF5
|
|
||||||
jae fat16
|
|
||||||
fat12:
|
|
||||||
mov [bp + get_next_cluster_ptr - dat], fat12_get_next_cluster
|
|
||||||
mov di, cx ; BPB_NumFATs
|
|
||||||
mov ax, '12'
|
|
||||||
push ax ; save for secondary loader
|
|
||||||
mov word [si+3], ax
|
|
||||||
call out_string
|
|
||||||
movzx ecx, word [bx+22] ; BPB_FATSz16
|
|
||||||
; FAT12: read entire FAT table (it is no more than 0x1000*3/2 = 0x1800 bytes)
|
|
||||||
.fatloop:
|
|
||||||
; if first copy is not readable, try to switch to other copies
|
|
||||||
push 0x6000
|
|
||||||
pop es
|
|
||||||
xor bx, bx
|
|
||||||
movzx eax, word [0x320E] ; BPB_RsvdSecCnt
|
|
||||||
push cx
|
|
||||||
cmp cx, 12
|
|
||||||
jb @f
|
|
||||||
mov cx, 12
|
|
||||||
@@:
|
|
||||||
call read
|
|
||||||
pop cx
|
|
||||||
jnc fat1x_common
|
|
||||||
add eax, ecx ; switch to next copy of FAT
|
|
||||||
dec di
|
|
||||||
jnz .fatloop
|
|
||||||
mov si, disk_error_msg
|
|
||||||
jmp find_error_si
|
|
||||||
fat16:
|
|
||||||
mov [bp + get_next_cluster_ptr - dat], fat16_get_next_cluster
|
|
||||||
mov ax, '16'
|
|
||||||
push ax ; save for secondary loader
|
|
||||||
mov word [si+3], ax
|
|
||||||
call out_string
|
|
||||||
; FAT16: init FAT cache - no sectors loaded
|
|
||||||
mov di, 0x3400
|
|
||||||
xor ax, ax
|
|
||||||
mov cx, 0x100/2
|
|
||||||
rep stosw
|
|
||||||
fat1x_common:
|
|
||||||
mov bx, 0x3200
|
|
||||||
movzx eax, word [bx+22] ; BPB_FATSz16
|
|
||||||
xor esi, esi ; no root cluster
|
|
||||||
jmp fat_common
|
|
||||||
test_fat32:
|
|
||||||
; FAT32 bootsector has it at the offset +66
|
|
||||||
cmp byte [bx+66], 0x29
|
|
||||||
jnz not_fat
|
|
||||||
mov [bp + get_next_cluster_ptr - dat], fat32_get_next_cluster
|
|
||||||
mov ax, '32'
|
|
||||||
push ax ; save for secondary loader
|
|
||||||
mov word [si+3], ax
|
|
||||||
call out_string
|
|
||||||
; FAT32 - init cache for FAT table: no sectors loaded
|
|
||||||
lea si, [bp + cache1head - dat]
|
|
||||||
mov [si], si ; no sectors in cache:
|
|
||||||
mov [si+2], si ; 'prev' & 'next' links point to self
|
|
||||||
mov [bp + cache1end - dat], 3400h ; first free item = 3400h
|
|
||||||
mov [bp + cache1limit - dat], 3C00h
|
|
||||||
mov eax, [bx+36] ; BPB_FATSz32
|
|
||||||
mov esi, [bx+44] ; BPB_RootClus
|
|
||||||
jmp fat_common
|
|
||||||
not_fat:
|
|
||||||
unknown_fs:
|
|
||||||
mov si, errfs_msg
|
|
||||||
call out_string
|
|
||||||
jmp next_partition
|
|
||||||
fat_common:
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
movzx edx, byte [bx+16] ; BPB_NumFATs
|
|
||||||
mul edx
|
|
||||||
mov [bp + root_start - dat], eax ; this is for FAT1x
|
|
||||||
; eax = total size of all FAT tables, in sectors
|
|
||||||
movzx ecx, word [bx+17] ; BPB_RootEntCnt
|
|
||||||
add ecx, 0xF
|
|
||||||
shr ecx, 4
|
|
||||||
add eax, ecx
|
|
||||||
mov cx, word [bx+14] ; BPB_RsvdSecCnt
|
|
||||||
add [bp + root_start - dat], ecx ; this is for FAT1x
|
|
||||||
add eax, ecx
|
|
||||||
; cluster 2 begins from sector eax
|
|
||||||
movzx ebx, byte [bx+13] ; BPB_SecPerClus
|
|
||||||
sub eax, ebx
|
|
||||||
sub eax, ebx
|
|
||||||
mov [bp + data_start - dat], eax
|
|
||||||
; no clusters in folders cache
|
|
||||||
mov di, foldcache_clus - 2
|
|
||||||
xor ax, ax
|
|
||||||
mov cx, 7*8/2 + 1
|
|
||||||
rep stosw
|
|
||||||
mov [bp + root_clus - dat], esi
|
|
||||||
; load secondary loader
|
|
||||||
mov [bp + load_file_ptr - dat], load_file_fat
|
|
||||||
load_secondary:
|
|
||||||
push 0x1000
|
|
||||||
pop es
|
|
||||||
xor bx, bx
|
|
||||||
mov si, kernel_name
|
|
||||||
mov cx, 0x30000 / 0x200
|
|
||||||
call [bp + load_file_ptr - dat]
|
|
||||||
; say error if needed
|
|
||||||
mov si, error_too_big
|
|
||||||
dec bx
|
|
||||||
js @f
|
|
||||||
jz find_error_si
|
|
||||||
mov si, disk_error_msg
|
|
||||||
jmp find_error_si
|
|
||||||
@@:
|
|
||||||
; fill loader information and jump to secondary loader
|
|
||||||
mov al, 'h' ; boot device: hard drive
|
|
||||||
mov ah, [bp + boot_drive - dat]
|
|
||||||
sub ah, 80h ; boot device: identifier
|
|
||||||
pop bx ; restore file system ID ('12'/'16'/'32'/'nt')
|
|
||||||
mov si, callback
|
|
||||||
jmp 1000h:0000h
|
|
||||||
|
|
||||||
nomem:
|
|
||||||
mov si, nomem_msg
|
|
||||||
call out_string
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
ntfs:
|
|
||||||
push 'nt' ; save for secondary loader
|
|
||||||
mov si, ntfs_msg
|
|
||||||
call out_string
|
|
||||||
xor eax, eax
|
|
||||||
mov [bp + data_start - dat], eax
|
|
||||||
mov ecx, [bx+40h] ; frs_size
|
|
||||||
cmp cl, al
|
|
||||||
jg .1
|
|
||||||
neg cl
|
|
||||||
inc ax
|
|
||||||
shl eax, cl
|
|
||||||
jmp .2
|
|
||||||
.1:
|
|
||||||
mov eax, ecx
|
|
||||||
shl eax, 9
|
|
||||||
.2:
|
|
||||||
mov [bp + frs_size - dat], ax
|
|
||||||
; standard value for frs_size is 0x400 bytes = 1 Kb, and it cannot be set different
|
|
||||||
; (at least with standard tools)
|
|
||||||
; we allow extra size, but no more than 0x1000 bytes = 4 Kb
|
|
||||||
mov si, invalid_volume_msg
|
|
||||||
cmp eax, 0x1000
|
|
||||||
ja find_error_si
|
|
||||||
; must be multiple of sector size
|
|
||||||
test ax, 0x1FF
|
|
||||||
jnz find_error_si
|
|
||||||
shr ax, 9
|
|
||||||
xchg cx, ax
|
|
||||||
; initialize cache - no data loaded
|
|
||||||
lea si, [bp + cache1head - dat]
|
|
||||||
mov [si], si
|
|
||||||
mov [si+2], si
|
|
||||||
mov word [si+4], 3400h ; first free item = 3400h
|
|
||||||
mov word [si+6], 3400h + 8*8 ; 8 items in this cache
|
|
||||||
; read first MFT record - description of MFT itself
|
|
||||||
mov [bp + cur_obj - dat], mft_string
|
|
||||||
mov eax, [bx+30h] ; mft_cluster
|
|
||||||
mul [bp + sect_per_clust - dat]
|
|
||||||
push 0x8000
|
|
||||||
pop es
|
|
||||||
xor bx, bx
|
|
||||||
push es
|
|
||||||
call read
|
|
||||||
pop ds
|
|
||||||
call restore_usa
|
|
||||||
; scan for unnamed $DATA attribute
|
|
||||||
mov [bp + freeattr - dat], 4000h
|
|
||||||
mov ax, 80h
|
|
||||||
call load_attr
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov si, nodata_string
|
|
||||||
jc find_error_si
|
|
||||||
; load secondary loader
|
|
||||||
mov [bp + load_file_ptr - dat], load_file_ntfs
|
|
||||||
jmp load_secondary
|
|
||||||
|
|
||||||
find_error_si:
|
|
||||||
push si
|
|
||||||
find_error_sp:
|
|
||||||
cmp [bp + in_callback - dat], 0
|
|
||||||
jnz error_in_callback
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
mov si, error_msg
|
|
||||||
call out_string
|
|
||||||
mov si, [bp + cur_obj - dat]
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz @f
|
|
||||||
cmp al, '/'
|
|
||||||
jz @f
|
|
||||||
mov ah, 0Eh
|
|
||||||
mov bx, 7
|
|
||||||
int 10h
|
|
||||||
jmp @b
|
|
||||||
@@:
|
|
||||||
mov si, colon
|
|
||||||
call out_string
|
|
||||||
pop si
|
|
||||||
call out_string
|
|
||||||
mov si, newline
|
|
||||||
call out_string
|
|
||||||
mov sp, 0x3000
|
|
||||||
jmp next_partition
|
|
||||||
error_in_callback:
|
|
||||||
; return status: file not found, except for read errors
|
|
||||||
mov bx, 2
|
|
||||||
cmp si, disk_error_msg
|
|
||||||
jnz @f
|
|
||||||
inc bx
|
|
||||||
@@:
|
|
||||||
mov ax, 0xFFFF
|
|
||||||
mov dx, ax
|
|
||||||
mov sp, 3000h - 6
|
|
||||||
ret
|
|
||||||
|
|
||||||
callback:
|
|
||||||
; in: ax = function number; only functions 1 and 2 are defined for now
|
|
||||||
; save caller's stack
|
|
||||||
mov dx, ss
|
|
||||||
mov cx, sp
|
|
||||||
; set our stack (required because we need ss=0)
|
|
||||||
xor si, si
|
|
||||||
mov ss, si
|
|
||||||
mov sp, 3000h
|
|
||||||
mov bp, dat
|
|
||||||
mov [bp + in_callback - dat], 1
|
|
||||||
push dx
|
|
||||||
push cx
|
|
||||||
; set ds:si -> ASCIIZ name
|
|
||||||
lea si, [di+6]
|
|
||||||
; set cx = limit in sectors; 4Kb = 8 sectors
|
|
||||||
movzx ecx, word [di+4]
|
|
||||||
shl cx, 3
|
|
||||||
; set es:bx = pointer to buffer
|
|
||||||
les bx, [di]
|
|
||||||
; call our function
|
|
||||||
stc ; unsupported function
|
|
||||||
dec ax
|
|
||||||
jz callback_readfile
|
|
||||||
dec ax
|
|
||||||
jnz callback_ret
|
|
||||||
call continue_load_file
|
|
||||||
jmp callback_ret_succ
|
|
||||||
callback_readfile:
|
|
||||||
; function 1: read file
|
|
||||||
; in: ds:di -> information structure
|
|
||||||
; dw:dw address
|
|
||||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
|
||||||
; ASCIIZ name
|
|
||||||
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
|
|
||||||
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
|
|
||||||
call [bp + load_file_ptr - dat]
|
|
||||||
callback_ret_succ:
|
|
||||||
clc
|
|
||||||
callback_ret:
|
|
||||||
; restore caller's stack
|
|
||||||
pop cx
|
|
||||||
pop ss
|
|
||||||
mov sp, cx
|
|
||||||
; return to caller
|
|
||||||
retf
|
|
||||||
|
|
||||||
read_file_chunk.resident:
|
|
||||||
; auxiliary label for read_file_chunk procedure
|
|
||||||
mov di, bx
|
|
||||||
lodsw
|
|
||||||
read_file_chunk.resident.continue:
|
|
||||||
mov dx, ax
|
|
||||||
add dx, 0x1FF
|
|
||||||
shr dx, 9
|
|
||||||
cmp dx, cx
|
|
||||||
jbe @f
|
|
||||||
mov ax, cx
|
|
||||||
shl ax, 9
|
|
||||||
@@:
|
|
||||||
xchg ax, cx
|
|
||||||
rep movsb
|
|
||||||
xchg ax, cx
|
|
||||||
clc ; no disk error if no disk requests
|
|
||||||
mov word [bp + num_sectors - dat], ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
read_file_chunk:
|
|
||||||
; in: ds:si -> file chunk
|
|
||||||
; in: es:bx -> buffer for output
|
|
||||||
; in: ecx = maximum number of sectors to read (high word must be 0)
|
|
||||||
; out: CF=1 <=> disk read error
|
|
||||||
lodsb
|
|
||||||
mov [bp + cur_chunk_resident - dat], al
|
|
||||||
test al, al
|
|
||||||
jz .resident
|
|
||||||
; normal case: load (non-resident) attribute from disk
|
|
||||||
.read_block:
|
|
||||||
lodsd
|
|
||||||
xchg eax, edx
|
|
||||||
test edx, edx
|
|
||||||
jz .ret
|
|
||||||
lodsd
|
|
||||||
; eax = start cluster, edx = number of clusters, cx = limit in sectors
|
|
||||||
imul eax, [bp + sect_per_clust - dat]
|
|
||||||
add eax, [bp + data_start - dat]
|
|
||||||
mov [bp + cur_cluster - dat], eax
|
|
||||||
imul edx, [bp + sect_per_clust - dat]
|
|
||||||
mov [bp + num_sectors - dat], edx
|
|
||||||
and [bp + cur_delta - dat], 0
|
|
||||||
.nonresident.continue:
|
|
||||||
cmp edx, ecx
|
|
||||||
jb @f
|
|
||||||
mov edx, ecx
|
|
||||||
@@:
|
|
||||||
test dx, dx
|
|
||||||
jz .read_block
|
|
||||||
add [bp + cur_delta - dat], edx
|
|
||||||
sub [bp + num_sectors - dat], edx
|
|
||||||
sub ecx, edx
|
|
||||||
push cx
|
|
||||||
mov cx, dx
|
|
||||||
call read
|
|
||||||
pop cx
|
|
||||||
jc .ret
|
|
||||||
test cx, cx
|
|
||||||
jnz .read_block
|
|
||||||
.ret:
|
|
||||||
ret
|
|
||||||
|
|
||||||
cache_lookup:
|
|
||||||
; in: eax = value to look, si = pointer to cache structure
|
|
||||||
; out: di->cache entry; CF=1 <=> the value was not found
|
|
||||||
push ds bx
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov di, [si+2]
|
|
||||||
.look:
|
|
||||||
cmp di, si
|
|
||||||
jz .not_in_cache
|
|
||||||
cmp eax, [di+4]
|
|
||||||
jz .in_cache
|
|
||||||
mov di, [di+2]
|
|
||||||
jmp .look
|
|
||||||
.not_in_cache:
|
|
||||||
; cache miss
|
|
||||||
; cache is full?
|
|
||||||
mov di, [si+4]
|
|
||||||
cmp di, [si+6]
|
|
||||||
jnz .cache_not_full
|
|
||||||
; yes, delete the oldest entry
|
|
||||||
mov di, [si]
|
|
||||||
mov bx, [di]
|
|
||||||
mov [si], bx
|
|
||||||
push word [di+2]
|
|
||||||
pop word [bx+2]
|
|
||||||
jmp .cache_append
|
|
||||||
.cache_not_full:
|
|
||||||
; no, allocate new item
|
|
||||||
add word [si+4], 8
|
|
||||||
.cache_append:
|
|
||||||
mov [di+4], eax
|
|
||||||
stc
|
|
||||||
jmp @f
|
|
||||||
.in_cache:
|
|
||||||
; delete this sector from the list
|
|
||||||
push si
|
|
||||||
mov si, [di]
|
|
||||||
mov bx, [di+2]
|
|
||||||
mov [si+2], bx
|
|
||||||
mov [bx], si
|
|
||||||
pop si
|
|
||||||
@@:
|
|
||||||
; add new sector to the end of list
|
|
||||||
mov bx, di
|
|
||||||
xchg bx, [si+2]
|
|
||||||
push word [bx]
|
|
||||||
pop word [di]
|
|
||||||
mov [bx], di
|
|
||||||
mov [di+2], bx
|
|
||||||
pop bx ds
|
|
||||||
ret
|
|
||||||
|
|
||||||
include 'fat.inc'
|
|
||||||
include 'ntfs.inc'
|
|
||||||
|
|
||||||
total_kaput db 13,10,'Fatal error: cannot load the secondary loader',0
|
|
||||||
error_too_big db 'file is too big',0
|
|
||||||
nodata_string db '$DATA '
|
|
||||||
error_not_found db 'not found',0
|
|
||||||
noindex_string db '$INDEX_ROOT not found',0
|
|
||||||
badname_msg db 'bad name for FAT',0
|
|
||||||
invalid_volume_msg db 'invalid volume',0
|
|
||||||
mft_string db '$MFT',0
|
|
||||||
fragmented_string db 'too fragmented file',0
|
|
||||||
invalid_read_request_string db 'cannot read attribute',0
|
|
||||||
|
|
||||||
kernel_name db 'kord/loader',0
|
|
||||||
|
|
||||||
align 4
|
|
||||||
dat:
|
|
||||||
|
|
||||||
extended_part_start dd 0 ; start sector for main extended partition
|
|
||||||
extended_part_cur dd ? ; start sector for current extended child
|
|
||||||
extended_parent dd 0 ; start sector for current extended parent
|
|
||||||
partition_start dd 0 ; start sector for current logical disk
|
|
||||||
cur_partition_ofs dw ? ; offset in MBR data for current partition
|
|
||||||
sect_per_clust dd 0
|
|
||||||
; change this variable if you want to boot from other physical drive
|
|
||||||
boot_drive db 80h
|
|
||||||
in_callback db 0
|
|
||||||
|
|
||||||
; uninitialized data
|
|
||||||
use_lba db ?
|
|
||||||
cur_chunk_resident db ?
|
|
||||||
align 2
|
|
||||||
heads dw ?
|
|
||||||
sectors dw ?
|
|
||||||
cache1head rw 2
|
|
||||||
cache1end dw ?
|
|
||||||
cache1limit dw ?
|
|
||||||
data_start dd ?
|
|
||||||
cachelimit dw ?
|
|
||||||
load_file_ptr dw ?
|
|
||||||
cur_obj dw ?
|
|
||||||
missing_slash dw ?
|
|
||||||
root_clus dd ?
|
|
||||||
root_start dd ?
|
|
||||||
get_next_cluster_ptr dw ?
|
|
||||||
frs_size dw ?
|
|
||||||
freeattr dw ?
|
|
||||||
index_root dw ?
|
|
||||||
index_alloc dw ?
|
|
||||||
cur_index_seg dw ?
|
|
||||||
cur_index_cache dw ?
|
|
||||||
filesize dd ?
|
|
||||||
filesize_sectors dd ?
|
|
||||||
cur_cluster dd ?
|
|
||||||
cur_delta dd ?
|
|
||||||
num_sectors dd ?
|
|
||||||
sectors_read dd ?
|
|
||||||
cur_chunk_ptr dw ?
|
|
||||||
|
|
||||||
rootcache_size dw ? ; must be immediately before foldcache_clus
|
|
||||||
if $-dat >= 0x80
|
|
||||||
warning: unoptimal data displacement!
|
|
||||||
end if
|
|
||||||
foldcache_clus rd 7
|
|
||||||
foldcache_mark rw 7
|
|
||||||
foldcache_size rw 7
|
|
||||||
fat_filename rb 11
|
|
||||||
|
|
||||||
if $ > 2000h
|
|
||||||
error: file is too big
|
|
||||||
end if
|
|
||||||
|
|
||||||
; for NT/2k/XP, file must be 16 sectors = 0x2000 bytes long
|
|
||||||
repeat 0x2600 - $
|
|
||||||
db 2 ; any data can be here; 2 is another nice face in ASCII :)
|
|
||||||
end repeat
|
|
@ -1,391 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
Нет повести печальнее на свете,
|
|
||||||
Чем повесть о заклинившем Reset'е...
|
|
||||||
|
|
||||||
Загрузчик для FAT- и NTFS-томов для случаев, когда основной бутсектор загружает
|
|
||||||
Windows, для носителей с размером сектора 512 байт.
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Требования для работы:
|
|
||||||
1) Все используемые файлы должны быть читабельны.
|
|
||||||
2) Минимальный процессор - 80386.
|
|
||||||
3) В системе должно быть как минимум 592K свободной базовой памяти.
|
|
||||||
4) Пути к используемым файлам не должны содержать символических ссылок NTFS
|
|
||||||
(жёсткие ссылки допускаются).
|
|
||||||
5) Используемые файлы не должны быть сжатыми или разреженными файлами
|
|
||||||
(актуально для NTFS, для FAT выполнено автоматически).
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Документация в тему (ссылки проверялись на валидность 08.08.2008):
|
|
||||||
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
|
||||||
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
|
|
||||||
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip
|
|
||||||
спецификация NTFS: file://C:/windows/system32/drivers/ntfs.sys
|
|
||||||
и file://C:/ntldr либо file://C:/bootmgr
|
|
||||||
неофициальное описание NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543
|
|
||||||
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
|
|
||||||
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
|
|
||||||
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
|
|
||||||
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
|
|
||||||
официальное описание bcdedit для Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx
|
|
||||||
официальное описание работы с базой данных загрузчика Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx
|
|
||||||
формат таблицы разделов жёсткого диска: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Схема используемой памяти:
|
|
||||||
600-2000 код загрузчика (и данные)
|
|
||||||
2000-3000 стек
|
|
||||||
3000-3200 сектор MBR
|
|
||||||
3200-3400 бутсектор логического диска
|
|
||||||
3400-3C00 информация о кэше для таблиц FAT16/FAT32:
|
|
||||||
для FAT16 - массив на 0x100 байт, каждый байт равен
|
|
||||||
0 или 1 в зависимости от того, загружен ли
|
|
||||||
соответствующий сектор таблицы FAT16;
|
|
||||||
для FAT32 - 100h входов по 8 байт: 4 байта
|
|
||||||
(две ссылки - вперёд и назад) для организации L2-списка
|
|
||||||
всех прочитанных секторов в порядке возрастания
|
|
||||||
последнего времени использования + 4 байта для номера
|
|
||||||
сектора; при переполнении кэша выкидывается элемент из
|
|
||||||
головы списка, то есть тот, к которому дольше всех
|
|
||||||
не было обращений
|
|
||||||
3400-3440 информация о кэше для файловых записей NTFS в
|
|
||||||
таком же формате, как и кэш для FAT32, но на 8 входов
|
|
||||||
3480-34C0 заголовки для кэшей записей индекса NTFS
|
|
||||||
3500-3D00 информация о кэшах записей индекса NTFS: с каждой
|
|
||||||
файловой записью связан свой кэш для
|
|
||||||
соответствующего индекса
|
|
||||||
4000-8000 место для информации об атрибутах для NTFS
|
|
||||||
60000-80000 таблица FAT12 / место под таблицу FAT16 /
|
|
||||||
кэш для таблицы FAT32 / кэш для структур NTFS
|
|
||||||
80000-90000 текущий рассматриваемый кластер
|
|
||||||
90000-92000 FAT: кэш для корневой папки
|
|
||||||
92000-... FAT: кэш для некорневых папок (каждой папке отводится
|
|
||||||
2000h байт = 100h входов, одновременно в кэше
|
|
||||||
может находиться не более 7 папок;
|
|
||||||
точный размер определяется размером доступной
|
|
||||||
физической памяти - как правило, непосредственно
|
|
||||||
перед A0000 размещается EBDA, Extended BIOS Data Area)
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Основной процесс загрузки.
|
|
||||||
0a. Загрузка из-под DOS и Win9x: установка kordldr.win осуществляется
|
|
||||||
размещением команды install=c:\kordldr.win в первой строке config.sys;
|
|
||||||
при этом основной загрузчик системы загружает kordldr.win как обычный
|
|
||||||
com-файл, в какой-то сегмент по смещению 100h и передаёт управление
|
|
||||||
в начало кода (xxxx:0100).
|
|
||||||
0б. Загрузка из-под WinNT/2000/XP: установка kordldr.win осуществляется
|
|
||||||
добавлением строки наподобие c:\kordldr.win="KordOS" в секцию
|
|
||||||
[operating systems] файла boot.ini; если загружаемый файл имеет размер
|
|
||||||
не менее 8 Кб (0x2000 байт) и по смещению 3 содержит сигнатуру 'NTFS'
|
|
||||||
(в случае kordldr.win так и есть), то основной загрузчик каждой из
|
|
||||||
этих систем загружает kordldr.win по адресу 0D00:0000 и передаёт
|
|
||||||
управление на адрес 0D00:0256.
|
|
||||||
0в. Загрузка из-под Vista: установка kordldr.win осуществляется манипуляциями
|
|
||||||
с базой данных основного загрузчика через bcdedit и подробно описана в
|
|
||||||
инструкции к kordldr.win; основной загрузчик загружает целиком
|
|
||||||
kordldr.win по адресу 0000:7C00 и передаёт управление в начало кода.
|
|
||||||
1. При загрузке из-под DOS/9x основной загрузчик не ожидает, что загруженная
|
|
||||||
им программа окажется в свою очередь загрузчиком, и в этом случае
|
|
||||||
kordldr.win оказывается в условиях, когда основной загрузчик уже
|
|
||||||
установил какое-то окружение, в частности, перехватил некоторые
|
|
||||||
прерывания. Поэтому перед остальными действиями загрузчик должен
|
|
||||||
восстановить систему в начальное состояние. (При загрузке под
|
|
||||||
NT-линейкой такой проблемы не возникает, поскольку там основной
|
|
||||||
загрузчик ничего в системе не трогает.) Поэтому перед собственно
|
|
||||||
инициализацией KordOS при работе из-под DOS/9x производятся
|
|
||||||
дополнительные действия. Первым делом kordldr проверяет, какой из
|
|
||||||
случаев 0а и 0в имеет место (случай 0б отличается тем, что передаёт
|
|
||||||
управление не на начало кода): определяет значение ip (команда call
|
|
||||||
помещает в стек адрес следующей после call инструкции, команда pop si
|
|
||||||
выталкивает его в регистр si), и если оно равно 100h, то kordldr
|
|
||||||
загружен как com-файл из-под DOS/9x. Тогда он спрашивает подтверждения
|
|
||||||
у пользователя (поскольку в этой схеме kordldr загружается всегда,
|
|
||||||
он должен оставить возможность продолжить загрузку DOS/9x). Если
|
|
||||||
пользователь хочет продолжить обычную загрузку, kordldr завершается.
|
|
||||||
Иначе используется тот факт, что при выдаче прерывания перезагрузки
|
|
||||||
int 19h система предварительно снимает все свои перехваты BIOSовских
|
|
||||||
прерываний, а потом в свою очередь выдаёт int 19h уже BIOSу. Так что
|
|
||||||
kordldr устанавливает свой обработчик трассировочного прерывания,
|
|
||||||
устанавливает флаг трассировки и передаёт управление DOSовскому
|
|
||||||
обработчику. Обработчик трассировочного прерывания ничего не делает
|
|
||||||
до тех пор, пока следующей инструкцией не оказывается int 19h, а
|
|
||||||
в этот момент отбирает управление и продолжает загрузку KordOS.
|
|
||||||
При этом BIOSовские обработчики восстановлены за исключением,
|
|
||||||
быть может, прерывания таймера int 8, которое, возможно, восстановлено
|
|
||||||
до команды jmp far на оригинальный обработчик. В последнем случае его
|
|
||||||
нужно восстановить явно.
|
|
||||||
2. Загрузчик перемещает свой код на адрес 0000:0600.
|
|
||||||
3. (метка real_entry) Загрузчик устанавливает сегментные регистры ds = es = 0,
|
|
||||||
настраивает стек ss:sp = 0000:3000 и устанавливает bp так, чтобы
|
|
||||||
все данные можно было адресовать через [bp+N] с однобайтовым N
|
|
||||||
(в дальнейшем они так и будут адресоваться для освобождения ds и
|
|
||||||
экономии на размере кода). Разрешает прерывания на случай, если
|
|
||||||
они были запрещены. Выдаёт сообщение о начале загрузки, начинающееся
|
|
||||||
с весёлой рожицы (символ с ASCII-кодом 2).
|
|
||||||
4. Определяет характеристики жёсткого диска, указанного в качестве
|
|
||||||
загрузочного: проверяет поддержку LBA (функция 41h прерывания 13h),
|
|
||||||
если LBA не поддерживается, то определяет геометрию - число дорожек
|
|
||||||
и число секторов на дорожке (функция 8 прерывания 13h), эти параметры
|
|
||||||
нужны функции чтения с диска.
|
|
||||||
5. (метка new_partition_ex) Устраивает цикл по разделам жёсткого диска.
|
|
||||||
Цель цикла - для каждого логического диска попытаться загрузиться с
|
|
||||||
него (действия по загрузке с конкретного логического диска начинаются
|
|
||||||
с метки not_extended), при ошибке загрузки управление передаётся
|
|
||||||
назад этому циклу (метка next_partition), и поиск подходящего раздела
|
|
||||||
продолжается. На выходе заполняется одна переменная partition_start,
|
|
||||||
имеющая смысл начала текущего рассматриваемого логического диска,
|
|
||||||
но по ходу дела из-за приколов таблиц разделов используются ещё четыре
|
|
||||||
переменных. cur_partition_ofs - фактически счётчик цикла, формально
|
|
||||||
указатель на текущий вход в текущей загрузочной записи. Сама
|
|
||||||
загрузочная запись считывается в память начиная с адреса 3000h.
|
|
||||||
Три оставшихся нужны для правильной работы с расширенными разделами.
|
|
||||||
В каждой загрузочной записи помещается не более 4 записей о разделах.
|
|
||||||
Поэтому главной загрузочной записи, размещающейся в первом физическом
|
|
||||||
секторе диска, может не хватить, и обычно создаётся так называемый
|
|
||||||
расширенный раздел с расширенными загрузочными записями, формат
|
|
||||||
которых почти идентичен главной. Расширенный раздел может быть только
|
|
||||||
один, но в нём может быть много логических дисков и расширенных
|
|
||||||
загрузочных записей. Расширенные загрузочные записи организованы
|
|
||||||
в односвязный список, в каждой такой записи первый вход указывает
|
|
||||||
на соответствующий логический диск, а второй - на следующую расширенную
|
|
||||||
загрузочную запись.
|
|
||||||
При этом в главной загрузочной записи все адреса разделов являются
|
|
||||||
абсолютными номерами секторов. В расширенных же записях адреса разделов
|
|
||||||
относительны, причём с разными базами: адрес логического диска
|
|
||||||
указывается относительно расширенной записи, а адрес следующей
|
|
||||||
расширенной записи указывается относительно начала расширенного
|
|
||||||
раздела. Такой разнобой выглядит несколько странно, но имеет место
|
|
||||||
быть. Три оставшихся переменных содержат: extended_part_start -
|
|
||||||
начало расширенного раздела; extended_parent - текущая рассматриваемая
|
|
||||||
расширенная загрузочная запись; extended_part_cur - следующая
|
|
||||||
загрузочная запись для рассмотрения.
|
|
||||||
Цикл выглядит так: просматриваются все разделы, указанные в текущей
|
|
||||||
(главной или расширенной) загрузочной записи; для нормальных разделов
|
|
||||||
(они же логические диски) происходит переход на not_extended, где
|
|
||||||
устанавливается partition_start и начинается собственно загрузка
|
|
||||||
(последующие шаги); при встрече с разделом, тип которого указывает
|
|
||||||
на расширенность (5 или 0xF), код запоминает начало этого раздела
|
|
||||||
(в главной загрузочной записи такой тип означает расширенный раздел,
|
|
||||||
в расширенной - только указатель на следующую расширенную запись,
|
|
||||||
в обоих случаях он может встретиться только один раз в данной записи);
|
|
||||||
когда код доходит до конца списка, все нормальные разделы, описываемые
|
|
||||||
в этой записи, уже просмотрены, так что код с чистой совестью переходит
|
|
||||||
к следующей расширенной записи. Если он её не встретил, значит, уже
|
|
||||||
все логические разделы были подвергнуты попыткам загрузиться, и все
|
|
||||||
безрезультатно, так что выводится ругательство и работа останавливается
|
|
||||||
(jmp $).
|
|
||||||
Может возникнуть вопрос, зачем нужна такая сложная схема и почему
|
|
||||||
нельзя узнать нужный логический диск заранее или хотя бы ограничиться
|
|
||||||
первым попавшимся логическим диском, не крутя цикл. Так вот, вариант
|
|
||||||
с предварительным определением нужного раздела в данном случае не
|
|
||||||
используется, поскольку повлёк бы за собой нетривиальные лишние
|
|
||||||
действия по установке (в текущем виде установку можно провести вручную,
|
|
||||||
и она сводится к указанию системному загрузчику на существование
|
|
||||||
kordldr); кстати, в альтернативной версии загрузки после
|
|
||||||
Windows-загрузчика, когда установка осуществляется не вручную, а
|
|
||||||
специальной программой под Windows, используется модифицированная
|
|
||||||
версия, в которой как раз начальный физический сектор нужного раздела
|
|
||||||
прописывается установщиком. Сам kordldr не может установить, с какого
|
|
||||||
раздела его загрузил Windows-загрузчик (и вообще под NT/2000/XP обязан
|
|
||||||
быть файлом на диске C:\). Вариант с первым попавшимся логическим
|
|
||||||
диском был реализован в первой версии загрузчика, но по ходу дела
|
|
||||||
обнаружилось, что таки нужно крутить цикл: во-вторых, может быть
|
|
||||||
приятным, что сама система может стоять вовсе не на системном C:\, а и
|
|
||||||
на других дисках; во-первых, диск C: может и не быть первым логическим
|
|
||||||
разделом - Vista любит создавать скрытый первичный раздел перед
|
|
||||||
системным, и тогда диск C: становится вторым логическим.
|
|
||||||
6. Извещает пользователя о том, что происходит попытка загрузки с очередного
|
|
||||||
логического диска.
|
|
||||||
7. Читает первый сектор логического диска и определяет файловую систему.
|
|
||||||
И в FAT, и в NTFS поле со смещением +11 содержит число байт в секторе
|
|
||||||
и должно совпадать с характеристикой физического носителя, то есть
|
|
||||||
200h байт. И в FAT, и в NTFS поле со смещением +13 содержит число
|
|
||||||
секторов в кластере и должно быть степенью двойки.
|
|
||||||
Критерий NTFS: поле со смещением +3 содержит строку NTFS и поле со
|
|
||||||
смещением +16 нулевое (в FAT оно содержит число таблиц FAT и обязано
|
|
||||||
быть ненулевым).
|
|
||||||
Критерий FAT: загрузчик вычисляет число кластеров, определяет
|
|
||||||
предположительный тип (FAT12/FAT16/FAT32) и проверяет байт по смещению
|
|
||||||
+38 для FAT12/16, +66 для FAT32 (он должен быть равен 0x29).
|
|
||||||
После определения типа файловой системы извещает пользователя об
|
|
||||||
определённом типе. Если файловая система не распознана, выдаёт
|
|
||||||
соответствующее сообщение и переходит к следующему логическому диску.
|
|
||||||
8a. Для FAT12-томов: засовывает в стек идентификатор файловой системы -
|
|
||||||
константу '12'; устанавливает указатель на функцию получения следующего
|
|
||||||
в цепочке FAT кластера на FAT12-обработчик; считывает в память всю
|
|
||||||
таблицу FAT12 (она не превосходит 0x1800 байт = 6 Кб), при ошибке
|
|
||||||
чтения пытается использовать другие копии FAT.
|
|
||||||
8б. Для FAT16-томов: засовывает в стек идентификатор файловой системы -
|
|
||||||
константу '16'; устанавливает указатель на функцию получения следующего
|
|
||||||
в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию
|
|
||||||
о кэше секторов FAT (массив байт с возможными значениями 0 и 1,
|
|
||||||
означающими, был ли уже загружен соответствующий сектор - всего в
|
|
||||||
таблице FAT16 не более 0x100 секторов) - ни один сектор ещё не
|
|
||||||
загружен, все байты нулевые.
|
|
||||||
8в. Для FAT32-томов: засовывает в стек идентификатор файловой системы -
|
|
||||||
константу '32'; устанавливает указатель на функцию получения следующего
|
|
||||||
в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию
|
|
||||||
о кэше секторов FAT (формат информации описан выше, в распределении
|
|
||||||
используемой загрузчиком памяти) - ни один сектор ещё не загружен.
|
|
||||||
8г. Общее для FAT-томов: определяет значения служебных переменных
|
|
||||||
root_start (первый сектор корневого каталога в FAT12/16, игнорируется
|
|
||||||
при обработке FAT32-томов), data_start (начало данных с поправкой,
|
|
||||||
вводимой для того, чтобы кластер N начинался с сектора
|
|
||||||
N*sectors_per_cluster+data_start), root_clus (первый кластер корневого
|
|
||||||
каталога в FAT32, 0 в FAT12/16); устанавливает указатель на функцию
|
|
||||||
загрузки файла на FAT-обработчик.
|
|
||||||
8д. Для NTFS-томов: засовывает в стек идентификатор файловой системы -
|
|
||||||
константу 'nt'; определяет значение служебной переменной frs_size
|
|
||||||
(размер в байтах файловой записи, File Record Segment), для полной
|
|
||||||
корректности проверяет, что это значение (равное 0x400 байт на всех
|
|
||||||
реальных NTFS-томах - единственный способ изменить его заключается
|
|
||||||
в пересоздании всех системных структур вручную) не превосходит 0x1000
|
|
||||||
и кратно размеру сектора 0x200 байт; инициализирует кэш файловых
|
|
||||||
записей - ничего ещё не загружено; считывает первый кластер $MFT
|
|
||||||
и загружает информацию о расположении на диске всей таблицы $MFT
|
|
||||||
(атрибут 0x80, $Data); устанавливает указатель на функцию загрузки
|
|
||||||
файла на NTFS-обработчик.
|
|
||||||
9. (метка load_secondary) Вызывает функцию загрузки файла для файла вторичного
|
|
||||||
загрузчика. При обнаружении ошибки переходит на обработчик ошибок с
|
|
||||||
соответствующим сообщением.
|
|
||||||
10. Устанавливает регистры для вторичного загрузчика: al='h' (жёсткий диск),
|
|
||||||
ah=номер диска (для готового бинарника - 0 (BIOS-идентификатор 80h),
|
|
||||||
может быть изменён путём модификации константы в исходнике или
|
|
||||||
специальным установщиком), bx=идентификатор файловой системы (берётся
|
|
||||||
из стека, куда ранее был засунут на шаге 8), ds:si=указатель на
|
|
||||||
callback-функцию.
|
|
||||||
11. Передаёт управление вторичному загрузчику дальним переходом на 1000:0000.
|
|
||||||
|
|
||||||
Функция обратного вызова для вторичного загрузчика:
|
|
||||||
предоставляет возможность чтения файла.
|
|
||||||
Вход и выход описаны в спецификации на загрузчик.
|
|
||||||
Чтение файла:
|
|
||||||
1. Сохраняет стек вызывающего кода и устанавливает свой стек:
|
|
||||||
ss:sp = 0:3000, bp=dat: пара ss:bp при работе с остальным
|
|
||||||
кодом должна указывать на 0:dat.
|
|
||||||
2. Разбирает переданные параметры и вызывает процедуру загрузки файла.
|
|
||||||
3. Восстанавливает стек вызывающего кода и возвращает управление.
|
|
||||||
|
|
||||||
Вспомогательные процедуры.
|
|
||||||
Процедура чтения секторов (read):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
ss:bp = 0:dat
|
|
||||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
|
||||||
eax = стартовый сектор (относительно начала логического диска)
|
|
||||||
cx = число секторов (должно быть больше нуля)
|
|
||||||
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные,
|
|
||||||
флаг CF установлен, если возникла ошибка чтения
|
|
||||||
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на
|
|
||||||
устройстве, прибавляя номер первого сектора логического диска,
|
|
||||||
найденный при переборе дисков.
|
|
||||||
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации
|
|
||||||
CHS-версия: все читаемые секторы были на одной дорожке.
|
|
||||||
LBA-версия: число читаемых секторов не превосходило 7Fh (требование
|
|
||||||
спецификации EDD BIOS).
|
|
||||||
CHS-версия:
|
|
||||||
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как
|
|
||||||
единица плюс остаток от деления абсолютного номера на число секторов
|
|
||||||
на дорожке; дорожка рассчитывается как остаток от деления частного,
|
|
||||||
полученного на предыдущем шаге, на число дорожек, а цилиндр - как
|
|
||||||
частное от этого же деления. Если число секторов для чтения больше,
|
|
||||||
чем число секторов до конца дорожки, уменьшает число секторов для
|
|
||||||
чтения.
|
|
||||||
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов,
|
|
||||||
dh=головка, (младшие 6 бит cl)=сектор,
|
|
||||||
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер).
|
|
||||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска
|
|
||||||
и повторяет попытку чтения, всего делается не более трёх попыток
|
|
||||||
(несколько попыток нужно в случае дискеты для гарантии того, что
|
|
||||||
мотор раскрутился). Если все три раза происходит ошибка чтения,
|
|
||||||
переходит на код обработки ошибок с сообщением "Read error".
|
|
||||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
|
||||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
|
||||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
|
||||||
работу, иначе возвращается на шаг 3.
|
|
||||||
LBA-версия:
|
|
||||||
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
|
|
||||||
итерации) до 7Fh.
|
|
||||||
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
|
|
||||||
push, причём в обратном порядке: стек - структура LIFO, и данные в
|
|
||||||
стеке хранятся в обратном порядке по отношению к тому, как их туда
|
|
||||||
клали).
|
|
||||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки
|
|
||||||
ошибок с сообщением "Read error". Очищает стек от пакета,
|
|
||||||
сформированного на предыдущем шаге.
|
|
||||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
|
||||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
|
||||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
|
||||||
работу, иначе возвращается на шаг 3.
|
|
||||||
|
|
||||||
Процедура обработки ошибок (find_error_si и find_error_sp):
|
|
||||||
на входе: указатель на сообщение об ошибке в si либо на верхушке стека
|
|
||||||
0. Если вызывается find_error_si, она помещает переданный указатель в стек.
|
|
||||||
1. Если ошибка произошла в процессе работы callback-функции, то
|
|
||||||
(метка error_in_callback) обработчик просто возвращает управление
|
|
||||||
вызвавшему коду, рапортуя о ненайденном файле.
|
|
||||||
2. Если же ошибка произошла до передачи управления вторичному загрузчику,
|
|
||||||
обработчик выводит сообщение типа "Error: <текущий объект>: <ошибка>"
|
|
||||||
и (восстановив стек) переходит к следующему логическому диску.
|
|
||||||
|
|
||||||
Процедура чтения файла/атрибута по известному размещению на диске
|
|
||||||
(read_file_chunk):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
ds:si = указатель на информацию о размещении
|
|
||||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
|
||||||
ecx = лимит числа секторов для чтения, старшее слово должно быть 0
|
|
||||||
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные,
|
|
||||||
флаг CF установлен, если возникла ошибка чтения
|
|
||||||
1. Определяет, является ли атрибут резидентным (возможно только в NTFS
|
|
||||||
и означает, что данные файла/атрибута уже были целиком прочитаны при
|
|
||||||
обработке информации о файле) или нерезидентным (означает, что данные
|
|
||||||
хранятся где-то на диске, и имеется информация о том, где именно).
|
|
||||||
2. Для резидентных атрибутов (метка read_file_chunk.resident) просто копирует
|
|
||||||
данные по месту назначения (с учётом указанного лимита).
|
|
||||||
3. Для нерезидентных атрибутов информация состоит из пар <размер очередного
|
|
||||||
фрагмента файла в кластерах, стартовый кластер фрагмента>; процедура
|
|
||||||
читает фрагменты, пока файл не закончится или пока не будет достигнут
|
|
||||||
указанный лимит.
|
|
||||||
|
|
||||||
Процедура просмотра кэша (cache_lookup):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
eax = искомое значение
|
|
||||||
ss:si = указатель на структуру-заголовок кэша
|
|
||||||
на выходе: ss:di = указатель на вход в кэше; флаг CF установлен, если значение
|
|
||||||
было только что добавлено, и сброшен, если оно уже было в кэше.
|
|
||||||
1. Просматривает кэш в поисках указанного значения. Если значение найдено
|
|
||||||
(при этом флаг CF оказывается сброшенным), переходит к шагу 4.
|
|
||||||
2. Если кэш уже заполнен, удаляет из кэша самый старый вход (он находится в
|
|
||||||
голове двусвязного списка), иначе добавляет к кэшу ещё один вход.
|
|
||||||
3. Устанавливает в полученном входе указанное значение. Устанавливает флаг
|
|
||||||
CF, последующие шаги не меняют состояния флагов. Переходит к шагу 5.
|
|
||||||
4. Удаляет вход из списка.
|
|
||||||
5. Добавляет сектор в конец списка (самый новый вход).
|
|
@ -1,587 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
restore_usa:
|
|
||||||
; Update Sequence Array restore
|
|
||||||
; in: ds:bx -> USA-protected structure
|
|
||||||
push bx
|
|
||||||
lea di, [bx+1feh]
|
|
||||||
mov cx, [bx+6]
|
|
||||||
add bx, [bx+4]
|
|
||||||
dec cx
|
|
||||||
@@:
|
|
||||||
mov ax, [bx+2]
|
|
||||||
mov [di], ax
|
|
||||||
inc bx
|
|
||||||
inc bx
|
|
||||||
add di, 200h
|
|
||||||
loop @b
|
|
||||||
pop bx
|
|
||||||
ret
|
|
||||||
|
|
||||||
find_attr:
|
|
||||||
; in: ds:di->file record, ax=attribute
|
|
||||||
; out: ds:di->attribute or di=0 if not found
|
|
||||||
add di, [di+14h]
|
|
||||||
.1:
|
|
||||||
; attributes' codes are formally dwords, but all of them fit in word
|
|
||||||
cmp word [di], -1
|
|
||||||
jz .notfound
|
|
||||||
cmp word [di], ax
|
|
||||||
jnz .continue
|
|
||||||
; for $DATA attribute, scan only unnamed
|
|
||||||
cmp ax, 80h
|
|
||||||
jnz .found
|
|
||||||
cmp byte [di+9], 0
|
|
||||||
jz .found
|
|
||||||
.continue:
|
|
||||||
add di, [di+4]
|
|
||||||
jmp .1
|
|
||||||
.notfound:
|
|
||||||
xor di, di
|
|
||||||
.found:
|
|
||||||
ret
|
|
||||||
|
|
||||||
process_mcb_nonres:
|
|
||||||
; in: ds:si->attribute, es:di->buffer
|
|
||||||
; out: es:di->buffer end
|
|
||||||
pushad
|
|
||||||
pop di
|
|
||||||
add si, [si+20h]
|
|
||||||
xor ebx, ebx
|
|
||||||
.loop:
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz .done
|
|
||||||
push invalid_read_request_string
|
|
||||||
movzx cx, al
|
|
||||||
shr cx, 4
|
|
||||||
jz find_error_sp
|
|
||||||
xchg ax, dx
|
|
||||||
and dx, 0Fh
|
|
||||||
jz find_error_sp
|
|
||||||
add si, cx
|
|
||||||
add si, dx
|
|
||||||
pop ax
|
|
||||||
push si
|
|
||||||
dec si
|
|
||||||
movsx eax, byte [si]
|
|
||||||
dec cx
|
|
||||||
jz .l1e
|
|
||||||
.l1:
|
|
||||||
dec si
|
|
||||||
shl eax, 8
|
|
||||||
mov al, [si]
|
|
||||||
loop .l1
|
|
||||||
.l1e:
|
|
||||||
xchg ebp, eax
|
|
||||||
dec si
|
|
||||||
movsx eax, byte [si]
|
|
||||||
mov cx, dx
|
|
||||||
dec cx
|
|
||||||
jz .l2e
|
|
||||||
.l2:
|
|
||||||
dec si
|
|
||||||
shl eax, 8
|
|
||||||
mov al, byte [si]
|
|
||||||
loop .l2
|
|
||||||
.l2e:
|
|
||||||
pop si
|
|
||||||
add ebx, ebp
|
|
||||||
; eax=length, ebx=disk block
|
|
||||||
stosd
|
|
||||||
mov eax, ebx
|
|
||||||
stosd
|
|
||||||
cmp di, 0x8000 - 12
|
|
||||||
jbe .loop
|
|
||||||
..attr_overflow:
|
|
||||||
mov si, fragmented_string
|
|
||||||
jmp find_error_si
|
|
||||||
.done:
|
|
||||||
xor ax, ax
|
|
||||||
stosw
|
|
||||||
stosw
|
|
||||||
push di
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
load_attr:
|
|
||||||
; in: ax=attribute, ds:bx->base record
|
|
||||||
; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated,
|
|
||||||
; edx=size of attribute in bytes
|
|
||||||
; out: if not found: CF=1
|
|
||||||
mov di, [bp + freeattr - dat]
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
mov byte [es:di], 1
|
|
||||||
inc di
|
|
||||||
cmp di, 0x8000 - 12
|
|
||||||
ja ..attr_overflow
|
|
||||||
or edx, -1 ; file size is not known yet
|
|
||||||
; scan for attribute
|
|
||||||
push di
|
|
||||||
mov di, bx
|
|
||||||
add di, [di+14h]
|
|
||||||
@@:
|
|
||||||
call find_attr.1
|
|
||||||
test di, di
|
|
||||||
jz .notfound1
|
|
||||||
cmp byte [di+8], 0
|
|
||||||
jnz .nonresident
|
|
||||||
mov si, di
|
|
||||||
pop di
|
|
||||||
push ds
|
|
||||||
jmp .resident
|
|
||||||
.aux_resident:
|
|
||||||
mov ax, ds
|
|
||||||
mov si, di
|
|
||||||
pop di ds bx ds edx
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
push ds
|
|
||||||
mov ds, ax
|
|
||||||
; resident attribute
|
|
||||||
.resident:
|
|
||||||
dec di
|
|
||||||
mov al, 0
|
|
||||||
stosb
|
|
||||||
mov ax, [si+10h]
|
|
||||||
stosw
|
|
||||||
push di
|
|
||||||
add di, ax
|
|
||||||
cmp di, 0x8000 - 12
|
|
||||||
pop di
|
|
||||||
ja ..attr_overflow
|
|
||||||
movzx edx, ax ; length of attribute
|
|
||||||
xchg ax, cx
|
|
||||||
add si, [si+14h]
|
|
||||||
rep movsb
|
|
||||||
mov [bp + freeattr - dat], di
|
|
||||||
pop ds
|
|
||||||
ret
|
|
||||||
.nonresident:
|
|
||||||
; nonresident attribute
|
|
||||||
cmp dword [di+10h], 0
|
|
||||||
jnz @b
|
|
||||||
; read start of data
|
|
||||||
mov si, di
|
|
||||||
mov edx, [di+30h] ; size of attribute
|
|
||||||
pop di
|
|
||||||
call process_mcb_nonres
|
|
||||||
sub di, 4
|
|
||||||
push di
|
|
||||||
.notfound1:
|
|
||||||
pop di
|
|
||||||
push edx
|
|
||||||
; $ATTRIBUTE_LIST is always in base file record
|
|
||||||
cmp ax, 20h
|
|
||||||
jz .nofragmented
|
|
||||||
; try to load $ATTRIBUTE_LIST = 20h
|
|
||||||
push ax
|
|
||||||
mov ax, 20h
|
|
||||||
push [bp + freeattr - dat]
|
|
||||||
mov [bp + freeattr - dat], di
|
|
||||||
push di
|
|
||||||
call load_attr
|
|
||||||
pop di
|
|
||||||
pop [bp + freeattr - dat]
|
|
||||||
pop ax
|
|
||||||
jc .nofragmented
|
|
||||||
push ds bx
|
|
||||||
pusha
|
|
||||||
mov si, di
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
push 0x8100
|
|
||||||
pop es
|
|
||||||
xor ecx, ecx
|
|
||||||
mov cl, 0x78
|
|
||||||
xor bx, bx
|
|
||||||
push es
|
|
||||||
call read_file_chunk
|
|
||||||
pop ds
|
|
||||||
jc ..found_disk_error
|
|
||||||
test cx, cx
|
|
||||||
jz ..attr_overflow
|
|
||||||
popa
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
xor bx, bx
|
|
||||||
.1:
|
|
||||||
cmp [bx], ax
|
|
||||||
jnz .continue1
|
|
||||||
; only unnamed $DATA attributes!
|
|
||||||
cmp ax, 80h
|
|
||||||
jnz @f
|
|
||||||
cmp byte [bx+6], 0
|
|
||||||
jnz .continue1
|
|
||||||
@@:
|
|
||||||
cmp dword [bx+10h], 0
|
|
||||||
jz .continue1
|
|
||||||
cmp dword [bx+8], 0
|
|
||||||
jnz @f
|
|
||||||
dec di
|
|
||||||
cmp di, [bp + freeattr - dat]
|
|
||||||
lea di, [di+1]
|
|
||||||
jnz .continue1
|
|
||||||
@@:
|
|
||||||
push ds di
|
|
||||||
push ax
|
|
||||||
mov eax, [bx+10h]
|
|
||||||
mov ecx, [bx+8]
|
|
||||||
call read_file_record
|
|
||||||
pop ax
|
|
||||||
mov di, [14h]
|
|
||||||
.2:
|
|
||||||
call find_attr.1
|
|
||||||
cmp byte [di+8], 0
|
|
||||||
jz .aux_resident
|
|
||||||
cmp dword [di+10h], ecx
|
|
||||||
jnz .2
|
|
||||||
mov si, di
|
|
||||||
mov di, sp
|
|
||||||
cmp dword [ss:di+8], -1
|
|
||||||
jnz @f
|
|
||||||
push dword [si+30h] ; size of attribute
|
|
||||||
pop dword [ss:di+8]
|
|
||||||
@@:
|
|
||||||
pop di
|
|
||||||
call process_mcb_nonres
|
|
||||||
sub di, 4
|
|
||||||
pop ds
|
|
||||||
.continue1:
|
|
||||||
add bx, [bx+4]
|
|
||||||
cmp bx, dx
|
|
||||||
jb .1
|
|
||||||
pop bx ds
|
|
||||||
.nofragmented:
|
|
||||||
pop edx
|
|
||||||
dec di
|
|
||||||
cmp di, [bp + freeattr - dat]
|
|
||||||
jnz @f
|
|
||||||
stc
|
|
||||||
ret
|
|
||||||
@@:
|
|
||||||
inc di
|
|
||||||
xor ax, ax
|
|
||||||
stosw
|
|
||||||
stosw
|
|
||||||
mov [bp + freeattr - dat], di
|
|
||||||
ret
|
|
||||||
|
|
||||||
read_file_record:
|
|
||||||
; in: eax = index of record
|
|
||||||
; out: ds:0 -> record
|
|
||||||
; find place in cache
|
|
||||||
push di
|
|
||||||
push si
|
|
||||||
mov si, cache1head
|
|
||||||
call cache_lookup
|
|
||||||
pop si
|
|
||||||
pushf
|
|
||||||
sub di, 3400h
|
|
||||||
shl di, 10-3
|
|
||||||
add di, 0x6000
|
|
||||||
mov ds, di
|
|
||||||
popf
|
|
||||||
pop di
|
|
||||||
jnc .noread
|
|
||||||
; read file record <eax> to ds:0
|
|
||||||
pushad
|
|
||||||
push ds
|
|
||||||
push es
|
|
||||||
movzx ecx, [bp + frs_size - dat]
|
|
||||||
shr cx, 9
|
|
||||||
mul ecx
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov si, 0x4000
|
|
||||||
xor bx, bx
|
|
||||||
push [bp + cur_obj - dat]
|
|
||||||
mov [bp + cur_obj - dat], mft_string
|
|
||||||
push es
|
|
||||||
call read_attr
|
|
||||||
; initialize cache for $INDEX_ALLOCATION for this record
|
|
||||||
pop si
|
|
||||||
push si
|
|
||||||
sub si, 0x6000
|
|
||||||
mov ax, si
|
|
||||||
shr si, 10-3
|
|
||||||
shr ax, 2
|
|
||||||
add si, 3480h
|
|
||||||
add ax, 3500h
|
|
||||||
mov [si], si
|
|
||||||
mov [si+2], si
|
|
||||||
mov [si+4], ax
|
|
||||||
pop ds
|
|
||||||
call restore_usa
|
|
||||||
pop [bp + cur_obj - dat]
|
|
||||||
pop es
|
|
||||||
pop ds
|
|
||||||
popad
|
|
||||||
.noread:
|
|
||||||
ret
|
|
||||||
|
|
||||||
read_attr:
|
|
||||||
; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute
|
|
||||||
push invalid_read_request_string
|
|
||||||
cmp byte [si], 0
|
|
||||||
jnz .nonresident
|
|
||||||
cmp eax, 10000h shr 9
|
|
||||||
jae find_error_sp
|
|
||||||
shl ax, 9
|
|
||||||
shl cx, 9
|
|
||||||
cmp ax, [si+2]
|
|
||||||
jae find_error_sp
|
|
||||||
cmp cx, [si+2]
|
|
||||||
ja find_error_sp
|
|
||||||
add si, 3
|
|
||||||
add si, ax
|
|
||||||
mov di, bx
|
|
||||||
rep movsb
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
.nonresident:
|
|
||||||
inc si
|
|
||||||
.loop:
|
|
||||||
mov edx, dword [si]
|
|
||||||
add si, 8
|
|
||||||
test edx, edx
|
|
||||||
jz find_error_sp
|
|
||||||
imul edx, [bp + sect_per_clust - dat]
|
|
||||||
sub eax, edx
|
|
||||||
jnc .loop
|
|
||||||
add eax, edx
|
|
||||||
sub edx, eax
|
|
||||||
push cx
|
|
||||||
cmp ecx, edx
|
|
||||||
jb @f
|
|
||||||
mov cx, dx
|
|
||||||
@@:
|
|
||||||
push bx
|
|
||||||
mov ebx, [si-4]
|
|
||||||
imul ebx, [bp + sect_per_clust - dat]
|
|
||||||
add eax, ebx
|
|
||||||
pop bx
|
|
||||||
call read
|
|
||||||
jc ..found_disk_error
|
|
||||||
mov dx, cx
|
|
||||||
pop cx
|
|
||||||
xor eax, eax
|
|
||||||
sub cx, dx
|
|
||||||
jnz .loop
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
load_file_ntfs:
|
|
||||||
; in: ss:bp = 0:dat
|
|
||||||
; in: es:bx = address to load file
|
|
||||||
; in: ds:si -> ASCIIZ name
|
|
||||||
; in: cx = limit in sectors
|
|
||||||
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found
|
|
||||||
; out: dx:ax = file size (0xFFFFFFFF if file not found)
|
|
||||||
push es bx cx
|
|
||||||
mov eax, 5 ; root cluster
|
|
||||||
mov [bp + cur_obj - dat], root_string
|
|
||||||
.parse_dir_loop:
|
|
||||||
push ds si
|
|
||||||
call read_file_record
|
|
||||||
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
|
|
||||||
mov ax, [bp + freeattr - dat]
|
|
||||||
mov [bp + index_root - dat], ax
|
|
||||||
mov ax, 90h ; $INDEX_ROOT
|
|
||||||
xor bx, bx
|
|
||||||
call load_attr
|
|
||||||
mov si, noindex_string
|
|
||||||
jc find_error_si
|
|
||||||
mov ax, [bp + freeattr - dat]
|
|
||||||
mov [bp + index_alloc - dat], ax
|
|
||||||
mov ax, 0A0h ; $INDEX_ALLOCATION
|
|
||||||
call load_attr
|
|
||||||
jnc @f
|
|
||||||
mov [bp + index_alloc - dat], bx
|
|
||||||
@@:
|
|
||||||
push ds
|
|
||||||
; search for entry
|
|
||||||
mov si, [bp + index_root - dat]
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
push 0x8100
|
|
||||||
pop es
|
|
||||||
xor ecx, ecx
|
|
||||||
mov cl, 0x78
|
|
||||||
xor bx, bx
|
|
||||||
push es
|
|
||||||
call read_file_chunk
|
|
||||||
pop ds
|
|
||||||
jc ..found_disk_error
|
|
||||||
test cx, cx
|
|
||||||
jz ..attr_overflow
|
|
||||||
mov si, invalid_read_request_string
|
|
||||||
cmp word [bx+10], 0
|
|
||||||
jnz find_error_si
|
|
||||||
; calculate number of items in cache
|
|
||||||
mov di, [bx+8] ; subnode_size
|
|
||||||
mov ax, 0x4000
|
|
||||||
sub ax, word [bp + frs_size - dat]
|
|
||||||
cwd
|
|
||||||
div di
|
|
||||||
test ax, ax
|
|
||||||
jz find_error_si
|
|
||||||
mov si, invalid_volume_msg
|
|
||||||
test di, 0x1FF
|
|
||||||
jnz find_error_si
|
|
||||||
pop cx
|
|
||||||
mov [bp + cur_index_seg - dat], cx
|
|
||||||
shl ax, 3
|
|
||||||
sub cx, 6000h
|
|
||||||
mov si, cx
|
|
||||||
shr cx, 2
|
|
||||||
shr si, 10-3
|
|
||||||
add cx, ax
|
|
||||||
add si, 3480h
|
|
||||||
mov [bp + cur_index_cache - dat], si
|
|
||||||
add cx, 3500h
|
|
||||||
mov [ss:si+6], cx
|
|
||||||
mov dx, di
|
|
||||||
add bx, 10h
|
|
||||||
.scan_record:
|
|
||||||
add bx, [bx]
|
|
||||||
.scan:
|
|
||||||
test byte [bx+0Ch], 2
|
|
||||||
jnz .look_child
|
|
||||||
movzx cx, byte [bx+50h] ; namelen
|
|
||||||
lea di, [bx+52h] ; name
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
pop si ds
|
|
||||||
push ds si
|
|
||||||
xor ax, ax
|
|
||||||
.1:
|
|
||||||
lodsb
|
|
||||||
cmp al, '/'
|
|
||||||
jnz @f
|
|
||||||
mov al, 0
|
|
||||||
@@:
|
|
||||||
cmp al, 'A'
|
|
||||||
jb .nocapital
|
|
||||||
cmp al, 'Z'
|
|
||||||
ja .nocapital
|
|
||||||
or al, 20h
|
|
||||||
.nocapital:
|
|
||||||
cmp al, 'a'
|
|
||||||
jb .notletter
|
|
||||||
cmp al, 'z'
|
|
||||||
ja .notletter
|
|
||||||
or byte [es:di], 20h
|
|
||||||
.notletter:
|
|
||||||
scasw
|
|
||||||
loopz .1
|
|
||||||
jb .look_child
|
|
||||||
ja @f
|
|
||||||
cmp byte [si], 0
|
|
||||||
jz .file_found
|
|
||||||
cmp byte [si], '/'
|
|
||||||
jz .file_found
|
|
||||||
@@:
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
add bx, [bx+8]
|
|
||||||
jmp .scan
|
|
||||||
.look_child:
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
test byte [bx+0Ch], 1
|
|
||||||
jz .not_found
|
|
||||||
mov si, [bp + index_alloc - dat]
|
|
||||||
test si, si
|
|
||||||
jz .not_found
|
|
||||||
add bx, [bx+8]
|
|
||||||
mov eax, [bx-8]
|
|
||||||
mov es, [bp + cur_index_seg - dat]
|
|
||||||
push si
|
|
||||||
mov si, [bp + cur_index_cache - dat]
|
|
||||||
call cache_lookup
|
|
||||||
pop si
|
|
||||||
pushf
|
|
||||||
mov bx, di
|
|
||||||
mov bh, 0
|
|
||||||
shr bx, 3
|
|
||||||
imul bx, dx
|
|
||||||
add bx, [bp + frs_size - dat]
|
|
||||||
popf
|
|
||||||
jnc .noread
|
|
||||||
push es
|
|
||||||
push dx
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
movzx ecx, dx
|
|
||||||
shr cx, 9
|
|
||||||
mul [bp + sect_per_clust - dat]
|
|
||||||
call read_attr
|
|
||||||
pop dx
|
|
||||||
pop es
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
call restore_usa
|
|
||||||
.noread:
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
add bx, 18h
|
|
||||||
jmp .scan_record
|
|
||||||
.not_found:
|
|
||||||
pop [bp + cur_obj - dat]
|
|
||||||
mov si, error_not_found
|
|
||||||
jmp find_error_si
|
|
||||||
.file_found:
|
|
||||||
pop [bp + cur_obj - dat]
|
|
||||||
pop cx
|
|
||||||
mov ax, [bp + index_root - dat]
|
|
||||||
mov [bp + freeattr - dat], ax
|
|
||||||
mov eax, [es:bx]
|
|
||||||
test byte [es:bx+48h+3], 10h
|
|
||||||
jz .regular_file
|
|
||||||
cmp byte [si], 0
|
|
||||||
jz ..directory_error
|
|
||||||
inc si
|
|
||||||
jmp .parse_dir_loop
|
|
||||||
.regular_file:
|
|
||||||
cmp byte [si], 0
|
|
||||||
jnz ..notdir_error
|
|
||||||
; read entry
|
|
||||||
call read_file_record
|
|
||||||
xor bx, bx
|
|
||||||
mov ax, 80h
|
|
||||||
call load_attr
|
|
||||||
mov si, nodata_string
|
|
||||||
jc find_error_si
|
|
||||||
mov si, [bp + index_root - dat]
|
|
||||||
mov [bp + freeattr - dat], si
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
jmp load_file_common_end
|
|
@ -1,20 +0,0 @@
|
|||||||
echo off
|
|
||||||
cls
|
|
||||||
echo ** bulding after win loader **
|
|
||||||
@fasm -m 65535 after_win/kordldr.win.asm after_win/kordldr.win
|
|
||||||
echo ==============================
|
|
||||||
echo ** building first loader for cd/dvd **
|
|
||||||
@fasm -m 65535 cdfs/bootsect.asm cdfs/bootsect.bin
|
|
||||||
echo ==============================
|
|
||||||
echo ** building first loader for fat12/fat16 **
|
|
||||||
@fasm -m 65535 fat1x/bootsect.asm fat1x/bootsect.bin
|
|
||||||
@fasm -m 65535 fat1x/kordldr.f1x.asm fat1x/kordldr.f1x
|
|
||||||
echo ==============================
|
|
||||||
echo ** building firs loader for fat32 **
|
|
||||||
@fasm -m 65535 fat32/bootsect.asm fat32/bootsect.bin
|
|
||||||
@fasm -m 65535 fat32/kordldr.f1x.asm fat32/kordldr.f1x
|
|
||||||
echo ==============================
|
|
||||||
echo ** make a image of fdd **
|
|
||||||
@fasm -m 65535 floppy.asc kord.img
|
|
||||||
|
|
||||||
@pause
|
|
File diff suppressed because it is too large
Load Diff
@ -1,418 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.?
|
|
||||||
|
|
||||||
Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660.
|
|
||||||
(ISO-9660 и её расширения - стандарт для CD; DVD может использовать
|
|
||||||
либо ISO-9660, либо UDF.)
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Требования для работы:
|
|
||||||
1) Сам бутсектор и все используемые файлы должны быть читабельны.
|
|
||||||
2) Минимальный процессор - 80386.
|
|
||||||
3) В системе должно быть как минимум 452K свободной базовой памяти.
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Документация в тему (ссылки проверялись на валидность 14.09.2008):
|
|
||||||
стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
|
|
||||||
стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf
|
|
||||||
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
|
|
||||||
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
|
|
||||||
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
|
|
||||||
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Схема используемой памяти:
|
|
||||||
1000-1800 временный буфер для чтения одиночных секторов
|
|
||||||
...-7C00 стек
|
|
||||||
7C00-8400 код бутсектора
|
|
||||||
8400-8A00 информация о кэше для папок: массив входов следующего
|
|
||||||
формата:
|
|
||||||
dw следующий элемент в L2-списке закэшированных папок,
|
|
||||||
упорядоченном по времени использования
|
|
||||||
(голова списка - самый старый);
|
|
||||||
dw предыдущий элемент в том же списке;
|
|
||||||
dd первый сектор папки;
|
|
||||||
dw размер папки в байтах;
|
|
||||||
dw сегмент кэша
|
|
||||||
60000-... содержимое Path Table, если она используется
|
|
||||||
+ кэш для папок;
|
|
||||||
точный размер определяется размером доступной
|
|
||||||
физической памяти - как правило, непосредственно
|
|
||||||
перед A0000 размещается EBDA, Extended BIOS Data Area
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Основной процесс загрузки.
|
|
||||||
Точка входа (start): получает управление от BIOS при загрузке, при этом
|
|
||||||
dl содержит идентификатор диска, с которого идёт загрузка
|
|
||||||
1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip
|
|
||||||
равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает
|
|
||||||
дальний прыжок на самого себя с целью получить cs=0 (в некоторых
|
|
||||||
местах используется адресация переменных загрузчика через cs, поскольку
|
|
||||||
и ds, и es могут быть заняты под другие сегменты).
|
|
||||||
2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом)
|
|
||||||
и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления
|
|
||||||
и разрешённые прерывания. Сохраняет идентификатор загрузочного диска
|
|
||||||
в специальную переменную.
|
|
||||||
3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять
|
|
||||||
LBA-функции.
|
|
||||||
4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту
|
|
||||||
ISO9660 со смещения 10h начинается цепочка описателей тома,
|
|
||||||
завершающаяся специальным описателем (Volume Descriptor Set
|
|
||||||
Terminator). Код по очереди считывает все сектора, пока не наткнётся
|
|
||||||
либо на искомый описатель, либо на терминатор. Во втором случае
|
|
||||||
выдаётся соответствующее сообщение, и загрузка прекращается.
|
|
||||||
Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD
|
|
||||||
располагается в последней сессии. И спецификация ElTorito загрузочного
|
|
||||||
CD оперирует также с последней сессией. Однако на практике оказывается,
|
|
||||||
что: во-первых, реальные BIOSы не понимают мультисессионных CD и
|
|
||||||
всегда используют первую сессию; во-вторых, BIOSовский int 13h просто
|
|
||||||
не позволяет получить информацию о последней сессии. В связи с этим
|
|
||||||
загрузчик также использует первую сессию. (В-третьих, в одной из BIOS
|
|
||||||
обнаружилась заготовка, которая в случае запроса сектора 10h, в котором
|
|
||||||
во всех нормальных случаях и располагается PVD, перенаправляет его
|
|
||||||
на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с
|
|
||||||
последней сессии, то благодаря заготовке загрузчик без всяких
|
|
||||||
модификаций также читал бы последнюю сессию.)
|
|
||||||
5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во
|
|
||||||
внутренние переменные: размер логического блока (согласно спецификации,
|
|
||||||
должен быть степенью двойки от 512 до размера логического сектора,
|
|
||||||
равного 2048 для CD и DVD); положение на диске корневой папки;
|
|
||||||
вычисляет число блоков в секторе (из предыдущего примечания следует,
|
|
||||||
что оно всегда целое и само является степенью двойки).
|
|
||||||
6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет
|
|
||||||
размер пространства, которое может использовать загрузчик (от
|
|
||||||
адреса 6000:0000 до конца доступной памяти).
|
|
||||||
7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит
|
|
||||||
базовую информацию обо всех папках на диске. Если таблица слишком
|
|
||||||
велика (больше 62K или больше половины доступной памяти), то она
|
|
||||||
игнорируется. Если таблица путей недоступна, то запрос типа
|
|
||||||
dir1/dir2/dir3/file приведёт к последовательному разбору корневой
|
|
||||||
папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать
|
|
||||||
саму таблицу путей (где записано положение папки dir1/dir2/dir3)
|
|
||||||
и папку dir3. Если таблица загружена, то соответственно уменьшается
|
|
||||||
объём оставшейся доступной памяти и увеличивается указатель на
|
|
||||||
свободную область.
|
|
||||||
8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7
|
|
||||||
доступная память отводится под этот кэш).
|
|
||||||
9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке
|
|
||||||
печатает соответствующее сообщение и прекращает загрузку с CD.
|
|
||||||
10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует
|
|
||||||
тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is'
|
|
||||||
идентифицирует файловую систему ISO-9660; ds:si указывает на
|
|
||||||
callback-функцию, которую может вызывать вторичный загрузчик.
|
|
||||||
11. Передаёт управление вторичному загрузчику, совершая дальний прыжок
|
|
||||||
на адрес, куда kord/loader был загружен.
|
|
||||||
|
|
||||||
Функция обратного вызова для вторичного загрузчика (callback):
|
|
||||||
предоставляет возможность чтения файла.
|
|
||||||
Вход и выход описаны в спецификации на загрузчик.
|
|
||||||
Перенаправляет запрос соответствующей локальной процедуре (load_file при
|
|
||||||
первом запросе на загрузку файла, loadloop.loadnew при последующих
|
|
||||||
запросах на продолжение загрузки файла).
|
|
||||||
|
|
||||||
Вспомогательные процедуры.
|
|
||||||
Код обработки ошибок (err):
|
|
||||||
1. Выводит строку с сообщением об ошибке.
|
|
||||||
2. Выводит строку "Press any key...".
|
|
||||||
3. Ждёт нажатия any key.
|
|
||||||
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
|
|
||||||
5. Для подстраховки зацикливается.
|
|
||||||
|
|
||||||
Процедура чтения секторов (read_sectors):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
|
||||||
eax = стартовый сектор
|
|
||||||
cx = число секторов
|
|
||||||
на выходе:
|
|
||||||
es:bx указывает на конец буфера, в который были прочитаны данные
|
|
||||||
если произошла ошибка чтения, флаг CF установлен
|
|
||||||
1. В цикле (шаги 2-4) читает секторы, следит за тем, чтобы на каждой итерации
|
|
||||||
число читаемых секторов не превосходило 7Fh (требование спецификации
|
|
||||||
EDD BIOS).
|
|
||||||
2. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
|
|
||||||
итерации) до 7Fh.
|
|
||||||
3. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
|
|
||||||
push, причём в обратном порядке: стек - структура LIFO, и данные в
|
|
||||||
стеке хранятся в обратном порядке по отношению к тому, как их туда
|
|
||||||
клали).
|
|
||||||
4. Вызывает BIOS. Если BIOS рапортует об ошибке, очищает стек,
|
|
||||||
устанавливает CF=1 и выходит из процедуры.
|
|
||||||
Очищает стек от пакета, сформированного на предыдущем шаге.
|
|
||||||
5. В соответствии с числом прочитанных на текущей итерации секторов
|
|
||||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
|
||||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
|
||||||
работу, иначе возвращается на шаг 2.
|
|
||||||
|
|
||||||
Процедура вывода на экран ASCIIZ-строки (out_string):
|
|
||||||
на входе: ds:si -> строка
|
|
||||||
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh.
|
|
||||||
|
|
||||||
Процедура загрузки файла (load_file):
|
|
||||||
на входе:
|
|
||||||
ds:di = указатель на информационную структуру, описанную в спецификации
|
|
||||||
на загрузчик, а также в комментариях к коду
|
|
||||||
на выходе:
|
|
||||||
bx = статус: 0=успех, 1=файл слишком большой, прочитана только часть,
|
|
||||||
2=файл не найден, 3=ошибка чтения
|
|
||||||
dx:ax = размер файла, 0xFFFFFFFF, если файл не найден
|
|
||||||
1. Если подготовительный код загрузил таблицу путей, то ищет папку в таблице,
|
|
||||||
иначе переходит сразу к шагу 4, установив eax = начальный блок
|
|
||||||
корневой папки.
|
|
||||||
2. Устанавливает es:di на начало таблицы путей. Ограничение на размер
|
|
||||||
гарантирует, что вся таблица помещается в сегменте 6000h.
|
|
||||||
Инициализирует dx (в котором будет хранится номер текущего входа в
|
|
||||||
таблице, считая с 1), cx (размер оставшегося участка таблицы),
|
|
||||||
bx (номер входа, соответствующего родительской папке для текущего
|
|
||||||
рассматриваемого участка пути).
|
|
||||||
3. В цикле ищет вход с нужным родительским элементом и нужным именем. Элементы
|
|
||||||
таблицы путей упорядочены (подробно о порядке написано в спецификации),
|
|
||||||
так что если родительский элемент для очередного входа больше нужного,
|
|
||||||
то нужного входа в таблице нет совсем, и в этом случае происходит
|
|
||||||
выход из процедуры с bx=2, ax=dx=0xFFFF. Если обнаружился элемент,
|
|
||||||
соответствующий очередной папке в запрошенном пути, то на рассмотрение
|
|
||||||
выносится следующая компонента пути. Если эта компонента последняя,
|
|
||||||
то осталось найти файл в папке, и код переходит к пункту 4,
|
|
||||||
установив eax = начальный блок этой папки. Если же нет, то эта
|
|
||||||
компонента должна задавать имя папки, и код возвращается к пункту 3,
|
|
||||||
скорректировав указатель на имя ds:si и номер родительского входа bx.
|
|
||||||
4. (parse_dir) На этом шаге заданы начальный логический блок папки в eax
|
|
||||||
и указатель на имя файла относительно этой папки в ds:si. Если
|
|
||||||
папку искали по таблице путей, то имя файла уже не содержит подпапок;
|
|
||||||
если же нет, то подпапки вполне возможны.
|
|
||||||
5. Файлы в ISO-9660 могут состоять из нескольких кусков (File Section), каждый
|
|
||||||
из которых задаётся отдельным входом в папке. Информация обо всех
|
|
||||||
таких кусках при просмотре папки запоминается в области, начинающейся
|
|
||||||
с адреса 0000:2000. Переменная cur_desc_end содержит указатель на
|
|
||||||
конец этой области, он же указатель, куда будет помещена информация
|
|
||||||
при обнаружении следующего входа. (Папки, согласно спецификации,
|
|
||||||
должны задаваться одним куском.)
|
|
||||||
6. Код сначала ищет запрошенную папку в кэше папок.
|
|
||||||
7. (parse_dir.found) Если папка уже есть в кэше, то она удаляется из списка,
|
|
||||||
отсортированного по давности последнего обращения и код переходит к
|
|
||||||
п.15. (Следующим действием станет добавление папки в конец списка.)
|
|
||||||
8. (parse_dir.notfound) Если же папки нет в кэше, то её придётся загружать
|
|
||||||
с диска. Сначала загружается первый сектор (физический сектор,
|
|
||||||
содержащий первый логический блок). При ошибке ввода/вывода
|
|
||||||
происходит немедленный выход из процедуры с bx=3, dx=ax=0xFFFF.
|
|
||||||
Первый элемент папки содержит информацию о самой этой папке, конкретно
|
|
||||||
загрузчик интересуется её размером.
|
|
||||||
9. Если размер папки слишком большой (больше или равен 64K либо больше половины
|
|
||||||
общего размера кэша), то кэшироваться она не будет. В этом случае код
|
|
||||||
считывает папку посекторно во временный буфер (0000:1000) и посекторно
|
|
||||||
сканирует на наличие запрошенного имени, пока не найдёт такого имени
|
|
||||||
или пока не кончатся данные. (Цикл начинается со сканирования,
|
|
||||||
поскольку первая часть данных уже прочитана.) В конце код переходит
|
|
||||||
к п.17.
|
|
||||||
10. (parse_dir.yescache) Если принято решение о кэшировании папки, то нужно
|
|
||||||
обеспечить достаточное количество свободного места. Для этого может
|
|
||||||
понадобиться выкинуть какое-то количество старых данных (цикл
|
|
||||||
parse_dir.freeloop). Но если просто выкидывать, то, вообще говоря,
|
|
||||||
свободное пространство окажется разорванным на несколько фрагментов.
|
|
||||||
Поэтому при выкидывании какой-то папки из кэша загрузчик перемещает
|
|
||||||
все следующие за ней данные назад по памяти и соответственно
|
|
||||||
корректирует информацию о местонахождении данных в информации о кэше.
|
|
||||||
При этом новое пространство всегда добавляется в конец доступной
|
|
||||||
памяти. Цикл выкидывания продолжается, пока не освободится место,
|
|
||||||
достаточное для хранения папки. Из-за ограничений на размер кэшируемых
|
|
||||||
папок в конце концов место найдётся.
|
|
||||||
11. Выделяется новый элемент кэша. Все удалённые на шаге 10 элементы
|
|
||||||
организуются в единый список свободных элементов; если он непуст,
|
|
||||||
то очередной элемент берётся из этого списка; если же пуст, то
|
|
||||||
берётся совсем новый элемент из области памяти, предназначенной для
|
|
||||||
элементов кэша.
|
|
||||||
12. В новом элементе заполняются поля начального блока, сегмента с данными,
|
|
||||||
размера в байтах.
|
|
||||||
13. Уже прочитанные данные первого физического сектора пересылаются на
|
|
||||||
законное место в кэше.
|
|
||||||
14. Если все данные не исчерпываются первым сектором, то догружаются оставшиеся
|
|
||||||
данные с диска. При ошибке чтения, как и раньше, происходит выход из
|
|
||||||
процедуры с bx=3, ax=dx=0xFFFF.
|
|
||||||
15. (parse_dir.scan) Новый элемент добавляется в конец списка всех элементов
|
|
||||||
кэша.
|
|
||||||
16. Загрузчик ищет запрошенное имя в загруженных данных папки.
|
|
||||||
(Из-за ограничений на размер кэшируемой папки все данные располагаются
|
|
||||||
в одном сегменте.)
|
|
||||||
17. (parse_dir.scandone) Если в процессе сканирования папки не было найдено
|
|
||||||
никаких кусков файла, то cur_desc_end такой же, каким был вначале.
|
|
||||||
В этом случае процедура рапортует о ненайденном файле и выходит.
|
|
||||||
18. (filefound) Пропускает текущую компоненту имени. Если она была не последней
|
|
||||||
(то есть подпапкой, в которой нужно производить дальнейший поиск),
|
|
||||||
то код проверяет, что найденный вход - действительно подпапка,
|
|
||||||
устанавливает новый стартовый блок и возвращается к п.4.
|
|
||||||
Если же последней, то код проверяет, что найденный вход - регулярный
|
|
||||||
файл и начинает загрузку файла.
|
|
||||||
19. Нормализует указатель, по которому требуется прочитать файл. Под
|
|
||||||
нормализацией понимается преобразование типа
|
|
||||||
1234:FC08 -> (1234+0FC0):0008, которое не меняет суммарного адреса,
|
|
||||||
но гарантирует отсутствие переполнений: в приведённом примере попытка
|
|
||||||
переслать 400h байт по rep movsb приведёт к тому, что последние 8
|
|
||||||
байт запишутся не в нужное место, а на 64K раньше. Далее нормализация
|
|
||||||
будет производиться после каждой пересылки. В cur_limit помещает
|
|
||||||
предельный размер для чтения в байтах.
|
|
||||||
20. (loadloop) В цикле по найденным фрагментам файла загружает эти фрагменты
|
|
||||||
(пункты 21-27).
|
|
||||||
21. Обнуляет переменную [cur_start], имеющую смысл числа байт, которое
|
|
||||||
нужно пропустить с начала фрагмента.
|
|
||||||
22. (loadloop.loadnew) На эту метку управление может попасть либо с предыдущего
|
|
||||||
шага, либо напрямую из callback-процедуры при запросе на продолжение
|
|
||||||
чтения. Для этого и нужна вышеупомянутая переменная [cur_start] -
|
|
||||||
при продолжении чтения, прервавшегося из-за конца буфера посередине
|
|
||||||
фрагмента, там будет записано соответствующее значение.
|
|
||||||
23. Определяет текущую длину (хранится в esi) как минимум из длины фрагмента
|
|
||||||
и максимальной длины остатка. Если второе строго меньше, то
|
|
||||||
запоминает, что файл слишком большой и прочитан только частично.
|
|
||||||
Определяет новое значение числа прочитанных байт во фрагменте
|
|
||||||
для возможных будущих вызовов [cur_start].
|
|
||||||
24. Переводит пропускаемое число байт в число логических блоков и байт
|
|
||||||
в первом блоке, последнее число записывает в переменную [first_byte],
|
|
||||||
откуда её позднее достанет read_many_bytes.with_first.
|
|
||||||
25. Если фрагмент записан в обычном режиме (non-interleaved mode), то код
|
|
||||||
определяет начальный блок фрагмента и вызывает вспомогательную функцию
|
|
||||||
чтения блоков. При ошибке чтения устанавливает bx=3 (код ошибки чтения)
|
|
||||||
и выходит из цикла к п.28.
|
|
||||||
26. Если фрагмент записан в чередуемом режиме (interleaved mode), то сначала
|
|
||||||
код пропускает нужное количество непрерывных частей, а потом
|
|
||||||
в цикле загружает непрерывные части с помощью той же функции,
|
|
||||||
в промежутках между частями увеличивая номер начального блока.
|
|
||||||
Пока не кончится фрагмент или пока не наберётся запрошенное число байт.
|
|
||||||
При ошибке чтения делает то же самое, что и в предыдущем случае.
|
|
||||||
27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер
|
|
||||||
ещё не достигнут, переходит к следующему фрагменту и п.20. В противном
|
|
||||||
случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли
|
|
||||||
переполнение в п.23.
|
|
||||||
28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех
|
|
||||||
фрагментов.
|
|
||||||
|
|
||||||
Процедура проверки, является ли текущая компонента имени файла последней
|
|
||||||
(is_last_component):
|
|
||||||
на входе: ds:si = указатель на имя
|
|
||||||
на выходе: флаг CF установлен, если есть последующие компоненты
|
|
||||||
В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый,
|
|
||||||
то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF
|
|
||||||
и выходит.
|
|
||||||
|
|
||||||
Процедуры проверки на совпадение текущей компоненты имени файла с именем
|
|
||||||
текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки):
|
|
||||||
на входе: ds:si = указатель на имя, es:di = указатель на элемент
|
|
||||||
таблицы путей для test_filename1, папки для test_filename2
|
|
||||||
на выходе: CF установлен, если имена не совпадают
|
|
||||||
В цикле проверяет совпадение приведённых к верхнему регистру очередных символов
|
|
||||||
имён файла и элемента. Условия выхода из цикла: закончилось имя файла
|
|
||||||
в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение
|
|
||||||
возможно только в ситуации типа имени "filename.ext" и элемента
|
|
||||||
"filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми
|
|
||||||
именами в папке отсортированы по убыванию версий);
|
|
||||||
несовпадение символов - означает, что имена не совпадают;
|
|
||||||
закончилось имя элемента - нужно проверить, закончилось ли при этом имя
|
|
||||||
файла, и в зависимости от этого принимать решение о совпадении.
|
|
||||||
|
|
||||||
Процедура приведения символа в верхний регистр (toupper):
|
|
||||||
на входе: ASCII-символ
|
|
||||||
на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к
|
|
||||||
нему неприменимо)
|
|
||||||
Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A',
|
|
||||||
остальные символы не трогает.
|
|
||||||
|
|
||||||
Процедура поиска файла в данных папки (scan_for_filename_in_sector):
|
|
||||||
на входе:
|
|
||||||
ds:si = указатель на имя файла
|
|
||||||
es:bx = указатель на начало данных папки
|
|
||||||
es:dx = указатель на конец данных папки
|
|
||||||
на выходе:
|
|
||||||
CF сброшен, если найден финальный фрагмент файла
|
|
||||||
(и дальше сканировать папку не нужно)
|
|
||||||
в область для информации о фрагментах файла записывается найденное
|
|
||||||
В цикле просматривает все входы папки, пропуская те, у которых установлен
|
|
||||||
бит Associated (это специальные входы, дополняющие основные). Если
|
|
||||||
имя очередного входа совпадает с именем файла, то запоминает новый
|
|
||||||
фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent),
|
|
||||||
то код выходит с CF=0. Если достигнут конец данных, то код выходит
|
|
||||||
с CF=1. Если очередной вход нулевой (первый байт настоящего входа
|
|
||||||
содержит длину и не может быть нулём), то процедура переходит к
|
|
||||||
рассмотрению следующего логического блока. При этом потенциально
|
|
||||||
возможно переполнение при добавлении размера блока; поскольку такой
|
|
||||||
сценарий означает, что процедура вызвана для кэшированной папки
|
|
||||||
с размером почти 64K и началом данных bx=0 (это свойство вызывающего
|
|
||||||
кода), а размер блока - степень двойки, то после переполнения всегда
|
|
||||||
bx=0, так что это можно обнаружить по взведённому ZF после сложения;
|
|
||||||
в этом случае также происходит выход (а после переполнения CF=1).
|
|
||||||
|
|
||||||
Процедура перевода логического блока в номер сектора:
|
|
||||||
на входе: eax = логический блок
|
|
||||||
на выходе: eax = физический сектор, dx = номер логического блока в секторе
|
|
||||||
Осуществляет обычное деление 32-битного числа на 32-битное (число логических
|
|
||||||
блоков в секторе, хранящееся во внутренней переменной).
|
|
||||||
|
|
||||||
Процедура загрузки физического сектора, содержащего указанный логический блок
|
|
||||||
(load_phys_sector_for_lb_force):
|
|
||||||
на входе: eax = логический блок;
|
|
||||||
si - индикатор, задающий, следует ли читать данные в случае,
|
|
||||||
если логический блок начинается с начала физического:
|
|
||||||
si = 0 - не нужно, si ненулевой - нужно
|
|
||||||
на выходе:
|
|
||||||
физический сектор загружен по адресу 0000:1000
|
|
||||||
si указывает на данные логического блока
|
|
||||||
CF установлен при ошибке чтения
|
|
||||||
Преобразует предыдущей процедурой номер логического блока в номер физического
|
|
||||||
сектора и номер логического блока внутри сектора; если последняя
|
|
||||||
величина нулевая и никаких действий в этом случае не запрошено (si=0),
|
|
||||||
то ничего и не делает; иначе устанавливает si в соответствии с ней
|
|
||||||
и читает сектор.
|
|
||||||
|
|
||||||
Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков
|
|
||||||
(read_many_bytes и read_many_bytes.with_first):
|
|
||||||
на входе:
|
|
||||||
eax = логический блок
|
|
||||||
esi = число байт для чтения
|
|
||||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
|
||||||
cur_limit = размер буфера (не меньше esi)
|
|
||||||
на выходе:
|
|
||||||
es:bx указывает на конец буфера, в который были прочитаны данные
|
|
||||||
если произошла ошибка чтения, флаг CF установлен
|
|
||||||
cur_limit соответствующим образом уменьшен
|
|
||||||
Отличие двух процедур: вторая дополнительно принимает во внимание переменную
|
|
||||||
[first_byte], начиная чтение первого блока со смещения [first_byte];
|
|
||||||
соответственно, первая читает блок с начала, обнуляя [first_byte]
|
|
||||||
при входе.
|
|
||||||
1. Отдельно считывает первый физический сектор во временную область 0000:1000,
|
|
||||||
если первый логический блок начинается не с начала сектора. При
|
|
||||||
ошибке чтения выходит из процедуры.
|
|
||||||
2. Пересылает нужную часть данных (возможно, 0 байт), прочитанных в п.1,
|
|
||||||
в буфер. Нормализует указатель на буфер.
|
|
||||||
3. Если все необходимые данные уже прочитаны, выходит из процедуры.
|
|
||||||
4. Дальнейшие данные находятся в нескольких физических секторах, при этом,
|
|
||||||
возможно, последний сектор считывать нужно не целиком.
|
|
||||||
5. Если в буфере есть место для считывания всех секторов, то сразу читаются
|
|
||||||
все сектора, после чего указатель на буфер нужным образом уменьшается.
|
|
||||||
6. Если же нет, то считываются все сектора, кроме последнего, после чего
|
|
||||||
последний сектор считывается отдельно во временную область, и уже
|
|
||||||
оттуда нужная часть данных копируется в буфер.
|
|
@ -1,2 +0,0 @@
|
|||||||
@fasm -m 65535 bootsect.asm bootsect.bin
|
|
||||||
@pause
|
|
@ -1,392 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
use_lba = 0
|
|
||||||
org 0x7C00
|
|
||||||
jmp start
|
|
||||||
nop
|
|
||||||
; FAT parameters, BPB
|
|
||||||
; note: they can be changed at install, replaced with real values
|
|
||||||
; these settings are for most typical 1.44M floppies
|
|
||||||
db 'KOLIBRI ' ; BS_OEMName, ignored
|
|
||||||
dw 200h ; BPB_BytsPerSec
|
|
||||||
BPB_SecsPerClus db 1
|
|
||||||
BPB_RsvdSecCnt dw 1
|
|
||||||
BPB_NumFATs db 2
|
|
||||||
BPB_RootEntCnt dw 0xE0
|
|
||||||
dw 2880 ; BPB_TotSec16
|
|
||||||
db 0xF0 ; BPB_Media
|
|
||||||
BPB_FATSz16 dw 9
|
|
||||||
BPB_SecPerTrk dw 18
|
|
||||||
BPB_NumHeads dw 2
|
|
||||||
BPB_HiddSec dd 0
|
|
||||||
dd 0 ; BPB_TotSec32
|
|
||||||
BS_DrvNum db 0
|
|
||||||
db 0 ; BS_Reserved1
|
|
||||||
db ')' ; BS_BootSig
|
|
||||||
dd 12344321h ; BS_VolID
|
|
||||||
filename:
|
|
||||||
db 'KORD.OS ' ; BS_VolLab
|
|
||||||
db 'FAT12 ' ; BS_FilSysType
|
|
||||||
; Used memory map:
|
|
||||||
; 8000:0000 - current directory
|
|
||||||
; 9000:0000 - root directory data [cached]
|
|
||||||
start:
|
|
||||||
xor ax, ax
|
|
||||||
mov ss, ax
|
|
||||||
mov sp, 0x7C00
|
|
||||||
mov ds, ax
|
|
||||||
mov bp, sp
|
|
||||||
cld
|
|
||||||
sti
|
|
||||||
mov [bp+BS_DrvNum-0x7C00], dl
|
|
||||||
if use_lba
|
|
||||||
mov ah, 41h
|
|
||||||
mov bx, 55AAh
|
|
||||||
int 13h
|
|
||||||
mov si, aNoLBA
|
|
||||||
jc err_
|
|
||||||
cmp bx, 0AA55h
|
|
||||||
jnz err_
|
|
||||||
test cx, 1
|
|
||||||
jz err_
|
|
||||||
else
|
|
||||||
mov ah, 8
|
|
||||||
int 13h
|
|
||||||
jc @f ; on error, assume that BPB geometry is valid
|
|
||||||
mov al, dh
|
|
||||||
mov ah, 0
|
|
||||||
inc ax
|
|
||||||
mov [bp+BPB_NumHeads-0x7C00], ax
|
|
||||||
and cx, 3Fh
|
|
||||||
mov [bp+BPB_SecPerTrk-0x7C00], cx
|
|
||||||
@@:
|
|
||||||
end if
|
|
||||||
; get FAT parameters
|
|
||||||
xor bx, bx
|
|
||||||
mov al, [bp+BPB_NumFATs-0x7C00]
|
|
||||||
mov ah, 0
|
|
||||||
mul [bp+BPB_FATSz16-0x7C00]
|
|
||||||
add ax, [bp+BPB_RsvdSecCnt-0x7C00]
|
|
||||||
adc dx, bx
|
|
||||||
push dx
|
|
||||||
push ax ; root directory start = dword [bp-4]
|
|
||||||
mov cx, [bp+BPB_RootEntCnt-0x7C00]
|
|
||||||
add cx, 0xF
|
|
||||||
rcr cx, 1
|
|
||||||
shr cx, 3 ; cx = size of root directory in sectors
|
|
||||||
add ax, cx
|
|
||||||
adc dx, bx
|
|
||||||
push dx
|
|
||||||
push ax ; data start = dword [bp-8]
|
|
||||||
; load start of root directory (no more than 0x2000 bytes = 0x10 sectors)
|
|
||||||
cmp cx, 0x10
|
|
||||||
jb @f
|
|
||||||
mov cx, 0x10
|
|
||||||
@@:
|
|
||||||
mov ax, [bp-4]
|
|
||||||
mov dx, [bp-2]
|
|
||||||
push 0x9000
|
|
||||||
pop es
|
|
||||||
call read_sectors
|
|
||||||
add word [bp-4], cx ; dword [bp-4] = start of non-cached root data
|
|
||||||
adc word [bp-2], bx
|
|
||||||
; load kordldr.f12
|
|
||||||
mov si, main_loader
|
|
||||||
call lookup_in_root_dir
|
|
||||||
jc noloader
|
|
||||||
test byte [es:di+11], 10h ; directory?
|
|
||||||
jz kordldr_ok
|
|
||||||
noloader:
|
|
||||||
mov si, aLoaderNotFound
|
|
||||||
err_:
|
|
||||||
call out_string
|
|
||||||
mov si, aPressAnyKey
|
|
||||||
call out_string
|
|
||||||
xor ax, ax
|
|
||||||
int 16h
|
|
||||||
int 18h
|
|
||||||
jmp $
|
|
||||||
kordldr_ok:
|
|
||||||
mov ax, [es:di+26] ; get file cluster
|
|
||||||
mov bx, 0x7E00
|
|
||||||
xor cx, cx
|
|
||||||
mov es, cx
|
|
||||||
sub ax, 2
|
|
||||||
jc noloader
|
|
||||||
push bx ; save return address: bx = 7E00
|
|
||||||
mov cl, [bp+BPB_SecsPerClus-0x7C00]
|
|
||||||
mul cx
|
|
||||||
; fall through - 'ret' in read_sectors will return to 7E00
|
|
||||||
|
|
||||||
read_sectors2:
|
|
||||||
; same as read_sectors, but dx:ax is relative to start of data
|
|
||||||
add ax, [bp-8]
|
|
||||||
adc dx, [bp-6]
|
|
||||||
read_sectors:
|
|
||||||
; ss:bp = 0:7C00
|
|
||||||
; es:bx = pointer to data
|
|
||||||
; dx:ax = first sector
|
|
||||||
; cx = number of sectors
|
|
||||||
pusha
|
|
||||||
add ax, word [bp+BPB_HiddSec-0x7C00]
|
|
||||||
adc dx, word [bp+BPB_HiddSec+2-0x7C00]
|
|
||||||
if use_lba
|
|
||||||
push ds
|
|
||||||
do_read_sectors:
|
|
||||||
push ax
|
|
||||||
push cx
|
|
||||||
push dx
|
|
||||||
cmp cx, 0x7F
|
|
||||||
jbe @f
|
|
||||||
mov cx, 0x7F
|
|
||||||
@@:
|
|
||||||
; create disk address packet on the stack
|
|
||||||
; dq starting LBA
|
|
||||||
push 0
|
|
||||||
push 0
|
|
||||||
push dx
|
|
||||||
push ax
|
|
||||||
; dd buffer
|
|
||||||
push es
|
|
||||||
push bx
|
|
||||||
; dw number of blocks to transfer (no more than 0x7F)
|
|
||||||
push cx
|
|
||||||
; dw packet size in bytes
|
|
||||||
push 10h
|
|
||||||
; issue BIOS call
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov si, sp
|
|
||||||
mov dl, [bp+BS_DrvNum-0x7C00]
|
|
||||||
mov ah, 42h
|
|
||||||
int 13h
|
|
||||||
mov si, aReadError
|
|
||||||
jc err_
|
|
||||||
; restore stack
|
|
||||||
add sp, 10h
|
|
||||||
; increase current sector & buffer; decrease number of sectors
|
|
||||||
mov si, cx
|
|
||||||
mov ax, es
|
|
||||||
shl cx, 5
|
|
||||||
add ax, cx
|
|
||||||
mov es, ax
|
|
||||||
pop dx
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
add ax, si
|
|
||||||
adc dx, 0
|
|
||||||
sub cx, si
|
|
||||||
jnz do_read_sectors
|
|
||||||
pop ds
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
else
|
|
||||||
do_read_sectors:
|
|
||||||
pusha
|
|
||||||
pop di
|
|
||||||
push bx
|
|
||||||
|
|
||||||
; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx
|
|
||||||
mov si, ax
|
|
||||||
xchg ax, dx
|
|
||||||
xor dx, dx
|
|
||||||
div [bp+BPB_SecPerTrk-0x7C00]
|
|
||||||
push ax
|
|
||||||
mov ax, si
|
|
||||||
div [bp+BPB_SecPerTrk-0x7C00]
|
|
||||||
mov bx, dx ; bx=sector-1
|
|
||||||
pop dx
|
|
||||||
|
|
||||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
|
||||||
div [bp+BPB_NumHeads-0x7C00]
|
|
||||||
|
|
||||||
; number of sectors: read no more than to end of track
|
|
||||||
push bx
|
|
||||||
sub bx, [bp+BPB_SecPerTrk-0x7C00]
|
|
||||||
neg bx
|
|
||||||
cmp cx, bx
|
|
||||||
jbe @f
|
|
||||||
mov cx, bx
|
|
||||||
@@:
|
|
||||||
pop bx
|
|
||||||
|
|
||||||
inc bx
|
|
||||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
|
|
||||||
mov di, cx
|
|
||||||
mov dh, dl
|
|
||||||
mov dl, [bp+BS_DrvNum-0x7C00]
|
|
||||||
shl ah, 6
|
|
||||||
mov ch, al
|
|
||||||
mov al, cl
|
|
||||||
mov cl, bl
|
|
||||||
or cl, ah
|
|
||||||
pop bx
|
|
||||||
mov si, 3
|
|
||||||
mov ah, 2
|
|
||||||
@@:
|
|
||||||
push ax
|
|
||||||
int 13h
|
|
||||||
jnc @f
|
|
||||||
xor ax, ax
|
|
||||||
int 13h ; reset drive
|
|
||||||
pop ax
|
|
||||||
dec si
|
|
||||||
jnz @b
|
|
||||||
mov si, aReadError
|
|
||||||
jmp err_
|
|
||||||
@@:
|
|
||||||
pop ax
|
|
||||||
mov ax, es
|
|
||||||
mov cx, di
|
|
||||||
shl cx, 5
|
|
||||||
add ax, cx
|
|
||||||
mov es, ax
|
|
||||||
push di
|
|
||||||
popa
|
|
||||||
add ax, di
|
|
||||||
adc dx, 0
|
|
||||||
sub cx, di
|
|
||||||
jnz do_read_sectors
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
end if
|
|
||||||
|
|
||||||
scan_for_filename:
|
|
||||||
; in: ds:si -> 11-bytes FAT name
|
|
||||||
; in: es:0 -> part of directory data
|
|
||||||
; in: cx = number of entries
|
|
||||||
; out: if found: CF=0, ZF=1, es:di -> directory entry
|
|
||||||
; out: if not found, but continue required: CF=1 and ZF=0
|
|
||||||
; out: if not found and zero item reached: CF=1 and ZF=1
|
|
||||||
xor di, di
|
|
||||||
push cx
|
|
||||||
sloop:
|
|
||||||
cmp byte [es:di], 0
|
|
||||||
jz snotfound
|
|
||||||
test byte [es:di+11], 8 ; volume label?
|
|
||||||
jnz scont ; ignore volume labels
|
|
||||||
pusha
|
|
||||||
mov cx, 11
|
|
||||||
repz cmpsb
|
|
||||||
popa
|
|
||||||
jz sdone
|
|
||||||
scont:
|
|
||||||
add di, 0x20
|
|
||||||
loop sloop
|
|
||||||
inc cx ; clear ZF flag
|
|
||||||
snotfound:
|
|
||||||
stc
|
|
||||||
sdone:
|
|
||||||
pop cx
|
|
||||||
lrdret:
|
|
||||||
ret
|
|
||||||
|
|
||||||
lookup_in_root_dir:
|
|
||||||
; ss:bp = 0:7C00
|
|
||||||
; in: ds:si -> 11-bytes FAT name
|
|
||||||
; out: if found: CF=0, es:di -> directory entry
|
|
||||||
; out: if not found: CF=1
|
|
||||||
mov cx, [bp+BPB_RootEntCnt-0x7C00]
|
|
||||||
push cx
|
|
||||||
; first, look in root directory cache
|
|
||||||
push 0x9000
|
|
||||||
pop es
|
|
||||||
test ch, ch
|
|
||||||
jz @f
|
|
||||||
mov cx, 0x100
|
|
||||||
@@:
|
|
||||||
mov ax, [bp-4]
|
|
||||||
mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory
|
|
||||||
lrdloop:
|
|
||||||
call scan_for_filename
|
|
||||||
pop bx
|
|
||||||
jz lrdret
|
|
||||||
sub bx, cx
|
|
||||||
mov cx, bx
|
|
||||||
stc
|
|
||||||
jz lrdret
|
|
||||||
; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries
|
|
||||||
push cx
|
|
||||||
cmp ch, 0x8
|
|
||||||
jb @f
|
|
||||||
mov cx, 0x800
|
|
||||||
@@:
|
|
||||||
push 0x8000
|
|
||||||
pop es
|
|
||||||
push cx
|
|
||||||
push es
|
|
||||||
xor bx, bx
|
|
||||||
add cx, 0xF
|
|
||||||
shr cx, 4
|
|
||||||
call read_sectors
|
|
||||||
pop es
|
|
||||||
add ax, cx
|
|
||||||
adc dx, bx
|
|
||||||
pop cx
|
|
||||||
jmp lrdloop
|
|
||||||
|
|
||||||
out_string:
|
|
||||||
; in: ds:si -> ASCIIZ string
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz lrdret
|
|
||||||
mov ah, 0Eh
|
|
||||||
mov bx, 7
|
|
||||||
int 10h
|
|
||||||
jmp out_string
|
|
||||||
|
|
||||||
aReadError db 'Read error',0
|
|
||||||
if use_lba
|
|
||||||
aNoLBA db 'The drive does not support LBA!',0
|
|
||||||
end if
|
|
||||||
aLoaderNotFound db 'Loader not found',0
|
|
||||||
aPressAnyKey db 13,10,'Press any key...',13,10,0
|
|
||||||
main_loader db 'KORDLDR F1X'
|
|
||||||
|
|
||||||
if use_lba
|
|
||||||
db 0 ; make bootsector 512 bytes in length
|
|
||||||
end if
|
|
||||||
|
|
||||||
; bootsector signature
|
|
||||||
dw 0xAA55
|
|
||||||
|
|
||||||
; display offsets of all procedures used by kordldr.f12.asm
|
|
||||||
macro show [procedure]
|
|
||||||
{
|
|
||||||
bits = 16
|
|
||||||
display `procedure,' = '
|
|
||||||
repeat bits/4
|
|
||||||
d = '0' + procedure shr (bits - %*4) and 0Fh
|
|
||||||
if d > '9'
|
|
||||||
d = d + 'A'-'9'-1
|
|
||||||
end if
|
|
||||||
display d
|
|
||||||
end repeat
|
|
||||||
display 13,10
|
|
||||||
}
|
|
||||||
|
|
||||||
show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader
|
|
@ -1,360 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
Встречаются вирус и FAT.
|
|
||||||
- Привет, ты кто?
|
|
||||||
- Я? Вирус.
|
|
||||||
- A я AFT, то есть TAF, то есть FTA, черт, совсем запутался...
|
|
||||||
|
|
||||||
Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт.
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Есть две версии в зависимости от того, поддерживает ли носитель LBA,
|
|
||||||
выбор осуществляется установкой константы use_lba в первой строке исходника.
|
|
||||||
Требования для работы:
|
|
||||||
1) Сам бутсектор, первая копия FAT и все используемые файлы
|
|
||||||
должны быть читабельны.
|
|
||||||
2) Минимальный процессор - 80186.
|
|
||||||
3) В системе должно быть как минимум 592K свободной базовой памяти.
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Документация в тему (ссылки валидны на момент написания этого файла, 15.05.2008):
|
|
||||||
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
|
||||||
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
|
|
||||||
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip
|
|
||||||
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
|
|
||||||
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
|
|
||||||
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
|
|
||||||
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер
|
|
||||||
занимает 12 бит в таблице FAT, так что общий размер не превосходит
|
|
||||||
0x17EE = 6126 байт. Вся таблица помещается в памяти.
|
|
||||||
Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый
|
|
||||||
кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит
|
|
||||||
0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в
|
|
||||||
этом случае несколько нецелесообразно считывать всю таблицу, поскольку
|
|
||||||
на практике нужна только небольшая её часть. Поэтому место в памяти
|
|
||||||
резервируется, но данные считываются только в момент, когда к ним
|
|
||||||
действительно идёт обращение.
|
|
||||||
|
|
||||||
Схема используемой памяти:
|
|
||||||
...-7C00 стек
|
|
||||||
7C00-7E00 код бутсектора
|
|
||||||
7E00-8200 вспомогательный файл загрузчика (kordldr.f1x)
|
|
||||||
8200-8300 список загруженных секторов таблицы FAT16
|
|
||||||
(1 = соответствующий сектор загружен)
|
|
||||||
60000-80000 загруженная таблица FAT12 / место для таблицы FAT16
|
|
||||||
80000-90000 текущий кластер текущей рассматриваемой папки
|
|
||||||
90000-92000 кэш для корневой папки
|
|
||||||
92000-... кэш для некорневых папок (каждой папке отводится
|
|
||||||
2000h байт = 100h входов, одновременно в кэше
|
|
||||||
может находиться не более 7 папок;
|
|
||||||
точный размер определяется размером доступной
|
|
||||||
физической памяти - как правило, непосредственно
|
|
||||||
перед A0000 размещается EBDA, Extended BIOS Data Area)
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Основной процесс загрузки.
|
|
||||||
Точка входа (start): получает управление от BIOS при загрузке, при этом
|
|
||||||
dl содержит идентификатор диска, с которого идёт загрузка
|
|
||||||
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед
|
|
||||||
кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало
|
|
||||||
бутсектора (в дальнейшем данные будут адресоваться через [bp+N] -
|
|
||||||
это освобождает ds и экономит на размере кода).
|
|
||||||
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h
|
|
||||||
прерывания 13h. Если нет, переходит на код обработки ошибок с
|
|
||||||
сообщением об отсутствии LBA.
|
|
||||||
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и
|
|
||||||
записывает полученные данные поверх BPB. Если вызов завершился ошибкой,
|
|
||||||
предполагает уже существующие данные корректными.
|
|
||||||
3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки
|
|
||||||
и начальный сектор данных. Кладёт их в стек; впоследствии они
|
|
||||||
всегда будут лежать в стеке и адресоваться через bp.
|
|
||||||
4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых
|
|
||||||
секторов - минимум из размера корневой папки, указанного в BPB, и 16
|
|
||||||
(размер кэша для корневой папки - 2000h байт = 16 секторов).
|
|
||||||
5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если
|
|
||||||
он оказывается папкой, или если файл имеет нулевую длину -
|
|
||||||
переходит на код обработки ошибок с сообщением о
|
|
||||||
ненайденном загрузчике.
|
|
||||||
Замечание: на этом этапе загрузки искать можно только в корневой
|
|
||||||
папке и только имена, заданные в формате файловой системе FAT
|
|
||||||
(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны
|
|
||||||
быть заглавными, при необходимости имя и расширение дополняются
|
|
||||||
пробелами, разделяющей точки нет, завершающего нуля нет).
|
|
||||||
6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт
|
|
||||||
ему управление. При этом в регистрах dx:ax оказывается абсолютный
|
|
||||||
номер первого сектора kordldr.f1x, а в cx - число считанных секторов
|
|
||||||
(равное размеру кластера).
|
|
||||||
|
|
||||||
Вспомогательные процедуры бутсектора.
|
|
||||||
Код обработки ошибок (err):
|
|
||||||
1. Выводит строку с сообщением об ошибке.
|
|
||||||
2. Выводит строку "Press any key...".
|
|
||||||
3. Ждёт нажатия any key.
|
|
||||||
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
|
|
||||||
5. Для подстраховки зацикливается.
|
|
||||||
|
|
||||||
Процедура чтения секторов (read_sectors и read_sectors2):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
ss:bp = 0:7C00
|
|
||||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
|
||||||
dx:ax = стартовый сектор (относительно начала логического диска
|
|
||||||
для read_sectors, относительно начала данных для read_sectors2)
|
|
||||||
cx = число секторов (должно быть больше нуля)
|
|
||||||
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные
|
|
||||||
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора
|
|
||||||
в номер относительно начала логического диска, прибавляя номер сектора
|
|
||||||
начала данных, хранящийся в стеке как [bp-8].
|
|
||||||
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на
|
|
||||||
устройстве, прибавляя значение соответствующего поля из BPB.
|
|
||||||
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации
|
|
||||||
CHS-версия: все читаемые секторы были на одной дорожке.
|
|
||||||
LBA-версия: число читаемых секторов не превосходило 7Fh (требование
|
|
||||||
спецификации EDD BIOS).
|
|
||||||
CHS-версия:
|
|
||||||
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как
|
|
||||||
единица плюс остаток от деления абсолютного номера на число секторов
|
|
||||||
на дорожке; дорожка рассчитывается как остаток от деления частного,
|
|
||||||
полученного на предыдущем шаге, на число дорожек, а цилиндр - как
|
|
||||||
частное от этого же деления. Если число секторов для чтения больше,
|
|
||||||
чем число секторов до конца дорожки, уменьшает число секторов для
|
|
||||||
чтения.
|
|
||||||
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов,
|
|
||||||
dh=головка, (младшие 6 бит cl)=сектор,
|
|
||||||
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер).
|
|
||||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска
|
|
||||||
и повторяет попытку чтения, всего делается не более трёх попыток
|
|
||||||
(несколько попыток нужно в случае дискеты для гарантии того, что
|
|
||||||
мотор раскрутился). Если все три раза происходит ошибка чтения,
|
|
||||||
переходит на код обработки ошибок с сообщением "Read error".
|
|
||||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
|
||||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
|
||||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
|
||||||
работу, иначе возвращается на шаг 3.
|
|
||||||
LBA-версия:
|
|
||||||
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
|
|
||||||
итерации) до 7Fh.
|
|
||||||
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
|
|
||||||
push, причём в обратном порядке: стек - структура LIFO, и данные в
|
|
||||||
стеке хранятся в обратном порядке по отношению к тому, как их туда
|
|
||||||
клали).
|
|
||||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки
|
|
||||||
ошибок с сообщением "Read error". Очищает стек от пакета,
|
|
||||||
сформированного на предыдущем шаге.
|
|
||||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
|
||||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
|
||||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
|
||||||
работу, иначе возвращается на шаг 3.
|
|
||||||
|
|
||||||
Процедура поиска элемента по имени в уже прочитанных данных папки
|
|
||||||
(scan_for_filename):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя,
|
|
||||||
3 на расширение, все буквы заглавные, если имя/расширение
|
|
||||||
короче, оно дополняется до максимума пробелами)
|
|
||||||
es = сегмент данных папки
|
|
||||||
cx = число элементов в прочитанных данных
|
|
||||||
на выходе: ZF определяет, нужно ли продолжать разбор данных папки
|
|
||||||
(ZF=1, если либо найден запрошенный элемент, либо достигнут
|
|
||||||
конец папки); CF определяет, удалось ли найти элемент с искомым именем
|
|
||||||
(CF=1, если не удалось); если удалось, то es:di указывает на него.
|
|
||||||
scan_for_filename считает, что данные папки размещаются начиная с es:0.
|
|
||||||
Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки
|
|
||||||
проверяет имена.
|
|
||||||
|
|
||||||
Процедура поиска элемента в корневой папке (lookup_in_root_dir):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
ss:bp = 0:7C00
|
|
||||||
ds:si = указатель на имя файла в формате FAT (см. выше)
|
|
||||||
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то
|
|
||||||
CF сброшен и es:di указывает на элемент папки
|
|
||||||
Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле
|
|
||||||
сканирует элементы; если по результатам сканирования обнаруживает,
|
|
||||||
что нужно читать папку дальше, то считывает не более 0x10000 = 64K
|
|
||||||
байт (ограничение введено по двум причинам: во-первых, чтобы заведомо
|
|
||||||
не вылезти за пределы используемой памяти, во-вторых, сканирование
|
|
||||||
предполагает, что все обрабатываемые элементы располагаются в одном
|
|
||||||
сегменте) и продолжает цикл.
|
|
||||||
Сканирование прекращается в трёх случаях: обнаружен искомый элемент;
|
|
||||||
кончились элементы в папке (судя по числу элементов, указанному в BPB);
|
|
||||||
очередной элемент папки сигнализирует о конце (первый байт нулевой).
|
|
||||||
|
|
||||||
Процедура вывода на экран ASCIIZ-строки (out_string):
|
|
||||||
на входе: ds:si -> строка
|
|
||||||
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh.
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Работа вспомогательного загрузчика kordldr.f1x:
|
|
||||||
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора.
|
|
||||||
В зависимости от этого устанавливает смещения используемых процедур
|
|
||||||
бутсектора. Критерий проверки: scan_for_filename должна начинаться
|
|
||||||
с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может
|
|
||||||
с равным успехом ассемблироваться и как 33 FF, но fasm генерирует
|
|
||||||
именно такую форму).
|
|
||||||
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска
|
|
||||||
адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с
|
|
||||||
ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента
|
|
||||||
место должно быть, отсюда ограничение в 592 Kb (94000h байт).
|
|
||||||
Замечание: этот размер не может превосходить 0A0000h байт и
|
|
||||||
на практике оказывается немного (на 1-2 килобайта) меньшим из-за
|
|
||||||
наличия дополнительной области данных BIOS "вверху" базовой памяти.
|
|
||||||
3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной
|
|
||||||
спецификации от Microsoft (версия 1.03 спецификации датирована,
|
|
||||||
к слову, 06 декабря 2000 года), разрядность FAT определяется
|
|
||||||
исключительно числом кластеров: максимальное число кластеров на
|
|
||||||
FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12
|
|
||||||
может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2,
|
|
||||||
а число 0xFF7 не может быть корректным номером кластера.
|
|
||||||
Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается
|
|
||||||
по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает
|
|
||||||
явно неверно, считая, что 0xFF6 (или меньше) кластеров означает
|
|
||||||
FAT12-том, в результате получается, что последний кластер
|
|
||||||
(в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe
|
|
||||||
[встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик
|
|
||||||
[бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы
|
|
||||||
лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили
|
|
||||||
в соответствии со спецификацией. Linux при определении FAT12/FAT16
|
|
||||||
честно следует спецификации.
|
|
||||||
Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT
|
|
||||||
Microsoft если и будет исправлять ошибки, то согласно собственному
|
|
||||||
описанию.
|
|
||||||
4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000.
|
|
||||||
Если размер, указанный в BPB, превосходит 12 секторов,
|
|
||||||
это означает, что заявленный размер слишком большой (это не считается
|
|
||||||
ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12
|
|
||||||
заведомо влезает в такой объём данных).
|
|
||||||
Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор
|
|
||||||
FAT не загружен (они будут подгружаться позднее, когда понадобятся
|
|
||||||
и только те, которые понадобятся).
|
|
||||||
5. Если кластер равен сектору, то бутсектор загрузил только часть файла
|
|
||||||
kordldr.f1x, и загрузчик подгружает вторую свою часть, используя
|
|
||||||
значения регистров на входе в kordldr.f1x.
|
|
||||||
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не
|
|
||||||
найден, или оказался папкой, или оказался слишком большим, то переходит
|
|
||||||
на код обработки ошибок из бутсектора с сообщением
|
|
||||||
"Fatal error: cannot load the secondary loader".
|
|
||||||
Замечание: на этом этапе имя файла уже можно указывать вместе с путём
|
|
||||||
и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов
|
|
||||||
по-прежнему нет.
|
|
||||||
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err.
|
|
||||||
Это нужно, чтобы последующие обращения к коду бутсектора в случае
|
|
||||||
ошибок чтения не выводил соответствующее сообщение с последующей
|
|
||||||
перезагрузкой, а рапортовал об ошибке чтения, которую мог бы
|
|
||||||
как-нибудь обработать вторичный загрузчик.
|
|
||||||
8. Если загрузочный диск имеет идентификатор меньше 0x80,
|
|
||||||
то устанавливает al='f' ("floppy"), ah=идентификатор диска,
|
|
||||||
иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска).
|
|
||||||
Устанавливает bx='12', если тип файловой системы - FAT12, и
|
|
||||||
bx='16' в случае FAT16. Устанавливает si=смещение функции обратного
|
|
||||||
вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес.
|
|
||||||
9. Передаёт управление по адресу 1000:0000.
|
|
||||||
|
|
||||||
Функция обратного вызова для вторичного загрузчика:
|
|
||||||
предоставляет возможность чтения файла.
|
|
||||||
Вход и выход описаны в спецификации на загрузчик.
|
|
||||||
1. Сохраняет стек вызывающего кода и устанавливает свой стек:
|
|
||||||
ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным
|
|
||||||
кодом должна указывать на 0:7C00, а -8 берётся от того, что
|
|
||||||
инициализирующий код бутсектора уже поместил в стек 2 двойных слова,
|
|
||||||
и они должны сохраняться в неизменности.
|
|
||||||
2. Разбирает переданные параметры, выясняет, какое действие запрошено,
|
|
||||||
и вызывает нужную вспомогательную процедуру.
|
|
||||||
3. Восстанавливает стек вызывающего кода и возвращает управление.
|
|
||||||
|
|
||||||
Вспомогательные процедуры kordldr.f1x.
|
|
||||||
Процедура получения следующего кластера в FAT (get_next_cluster):
|
|
||||||
1. Вспоминает разрядность FAT, вычисленную ранее.
|
|
||||||
Для FAT12:
|
|
||||||
2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана
|
|
||||||
вся таблица FAT.
|
|
||||||
3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте
|
|
||||||
слова, задающего следующий кластер. Загружает слово по этому адресу.
|
|
||||||
4. Если кластер имеет нечётный номер, то соответствующий ему элемент
|
|
||||||
располагается в старших 12 битах слова, и слово нужно сдвинуть вправо
|
|
||||||
на 4 бита; в противном случае - в младших 12 битах, и делать ничего не
|
|
||||||
надо.
|
|
||||||
5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7:
|
|
||||||
номера нормальных кластеров меньше, и флаг CF устанавливается;
|
|
||||||
специальные значения EOF и BadClus сбрасывают флаг CF.
|
|
||||||
Для FAT16:
|
|
||||||
2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных
|
|
||||||
в таблице FAT.
|
|
||||||
3. Если сектор ещё не загружен, то загружает его.
|
|
||||||
4. Вычисляет смещение данных для конкретного кластера относительно начала
|
|
||||||
сектора.
|
|
||||||
5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3.
|
|
||||||
6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг
|
|
||||||
CF устанавливается; специальные значения EOF и BadClus сбрасывают CF.
|
|
||||||
|
|
||||||
Процедура загрузки файла (load_file):
|
|
||||||
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4.
|
|
||||||
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты
|
|
||||||
разделяются символом '/') в FAT-формат 8+3. Если это невозможно
|
|
||||||
(больше 8 символов в имени, больше 3 символов в расширении или
|
|
||||||
больше одной точки), возвращается с ошибкой.
|
|
||||||
3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой
|
|
||||||
папки используется процедура из бутсектора. Для остальных папок:
|
|
||||||
a) Проверяет, есть ли такая папка в кэше некорневых папок.
|
|
||||||
(Идентификация папок осуществляется по номеру начального кластера.)
|
|
||||||
Если такой папки ещё нет, добавляет её в кэш; если тот переполняется,
|
|
||||||
выкидывает папку, к которой дольше всего не было обращений. (Для
|
|
||||||
каждого элемента кэша хранится метка от 0 до (размер кэша)-1,
|
|
||||||
определяющая его номер при сортировке по давности последнего обращения.
|
|
||||||
При обращении к какому-то элементу его метка становится нулевой,
|
|
||||||
а те метки, которые меньше старого значения, увеличиваются на единицу.)
|
|
||||||
б) Просматривает в поисках запрошенного имени все элементы из кэша,
|
|
||||||
используя процедуру из бутсектора. Если обнаруживает искомый элемент,
|
|
||||||
переходит к шагу 4. Если обнаруживает конец папки, возвращается из
|
|
||||||
процедуры с ошибкой.
|
|
||||||
в) В цикле считывает папку посекторно. При этом пропускает начальные
|
|
||||||
секторы, которые уже находятся в кэше и уже были просмотрены. Каждый
|
|
||||||
прочитанный сектор копирует в кэш, если там ещё остаётся место,
|
|
||||||
и просматривает в нём все элементы. Работает, пока не случится одно из
|
|
||||||
трёх событий: найден искомый элемент; кончились кластеры (судя по
|
|
||||||
цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце
|
|
||||||
(первый байт нулевой). В двух последних случаях возвращается с ошибкой.
|
|
||||||
4. Проверяет тип найденного элемента (файл/папка): последний элемент в
|
|
||||||
запрошенном имени должен быть файлом, все промежуточные - папками.
|
|
||||||
Если текущий компонент имени - промежуточный, продвигает текущую
|
|
||||||
рассматриваемую папку и возвращается к пункту 2.
|
|
||||||
5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный
|
|
||||||
при вызове буфер последовательными вызовами функции бутсектора;
|
|
||||||
при этом если несколько кластеров файла расположены на диске
|
|
||||||
последовательно, то их чтение объединяется в одну операцию.
|
|
||||||
Следит за тем, чтобы не превысить указанный при вызове процедуры
|
|
||||||
лимит числа секторов для чтения.
|
|
||||||
|
|
||||||
Процедура продолжения загрузки файла (continue_load_file): встроена
|
|
||||||
внутрь шага 5 load_file; загружает в регистры нужные значения (ранее
|
|
||||||
сохранённые из load_file) и продолжает шаг 5.
|
|
@ -1,3 +0,0 @@
|
|||||||
@fasm -m 65535 bootsect.asm bootsect.bin
|
|
||||||
@fasm -m 65535 kordldr.f1x.asm kordldr.f1x
|
|
||||||
@pause
|
|
@ -1,667 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
org 0x7E00
|
|
||||||
; the KordOS FAT12/FAT16 bootsector loads first cluster of this file to 0:7E00 and transfers control to here
|
|
||||||
; ss:bp = 0:7C00
|
|
||||||
virtual at bp
|
|
||||||
rb 3 ; BS_jmpBoot
|
|
||||||
rb 8 ; BS_OEMName, ignored
|
|
||||||
dw ? ; BPB_BytsPerSec
|
|
||||||
BPB_SecsPerClus db ?
|
|
||||||
BPB_RsvdSecCnt dw ?
|
|
||||||
BPB_NumFATs db ?
|
|
||||||
BPB_RootEntCnt dw ?
|
|
||||||
BPB_TotSec16 dw ?
|
|
||||||
db ? ; BPB_Media
|
|
||||||
BPB_FATSz16 dw ?
|
|
||||||
BPB_SecPerTrk dw ?
|
|
||||||
BPB_NumHeads dw ?
|
|
||||||
BPB_HiddSec dd ?
|
|
||||||
BPB_TotSec32 dd ?
|
|
||||||
BS_DrvNum db ?
|
|
||||||
fat_type db ? ; this is BS_Reserved1,
|
|
||||||
; we use it to save FS type: 0=FAT12, 1=FAT16
|
|
||||||
db ? ; BS_BootSig
|
|
||||||
num_sectors dd ? ; BS_VolID
|
|
||||||
; rb 11 ; BS_VolLab
|
|
||||||
; rb 3 ; BS_FilSysType, first 3 bytes
|
|
||||||
read_sectors dw ?
|
|
||||||
read_sectors2 dw ?
|
|
||||||
lookup_in_root_dir dw ?
|
|
||||||
scan_for_filename dw ?
|
|
||||||
err_ dw ?
|
|
||||||
noloader dw ?
|
|
||||||
cachelimit dw ?
|
|
||||||
filesize: ; will be used to save file size
|
|
||||||
rb 5 ; BS_FilSysType, last 5 bytes
|
|
||||||
; following variables are located in the place of starting code;
|
|
||||||
; starting code is no more used at this point
|
|
||||||
sect_per_clus dw ?
|
|
||||||
cur_cluster dw ?
|
|
||||||
next_cluster dw ?
|
|
||||||
flags dw ?
|
|
||||||
cur_delta dd ?
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
; procedures from boot sector
|
|
||||||
; LBA version
|
|
||||||
lba_read_sectors = 7CE2h
|
|
||||||
lba_read_sectors2 = 7CDCh
|
|
||||||
lba_lookup_in_root_dir = 7D4Fh
|
|
||||||
lba_scan_for_filename = 7D2Dh
|
|
||||||
lba_err = 7CB5h
|
|
||||||
lba_noloader = 7CB2h
|
|
||||||
; CHS version
|
|
||||||
chs_read_sectors = 7CDEh
|
|
||||||
chs_read_sectors2 = 7CD8h
|
|
||||||
chs_lookup_in_root_dir = 7D70h
|
|
||||||
chs_scan_for_filename = 7D4Eh
|
|
||||||
chs_err = 7CB1h
|
|
||||||
chs_noloader = 7CAEh
|
|
||||||
|
|
||||||
push ax cx ; save our position on disk
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
; determine version of bootsector (LBA vs CHS)
|
|
||||||
; mov [read_sectors], chs_read_sectors
|
|
||||||
; mov [read_sectors2], chs_read_sectors2
|
|
||||||
; mov [lookup_in_root_dir], chs_lookup_in_root_dir
|
|
||||||
; mov [scan_for_filename], chs_scan_for_filename
|
|
||||||
; mov [err], chs_err
|
|
||||||
; mov [noloader], chs_noloader
|
|
||||||
lea di, [read_sectors]
|
|
||||||
mov si, chs_proc_addresses
|
|
||||||
mov cx, 6*2
|
|
||||||
cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di'
|
|
||||||
jz @f
|
|
||||||
add si, cx
|
|
||||||
; mov [read_sectors], lba_read_sectors
|
|
||||||
; mov [read_sectors2], lba_read_sectors2
|
|
||||||
; mov [lookup_in_root_dir], lba_lookup_in_root_dir
|
|
||||||
; mov [scan_for_filename], lba_scan_for_filename
|
|
||||||
; mov [err], lba_err
|
|
||||||
; mov [noloader], lba_noloader
|
|
||||||
@@:
|
|
||||||
rep movsb
|
|
||||||
mov cl, [BPB_SecsPerClus]
|
|
||||||
mov [sect_per_clus], cx
|
|
||||||
xor bx, bx
|
|
||||||
; determine size of cache for folders
|
|
||||||
int 12h ; ax = size of available base memory in Kb
|
|
||||||
sub ax, 94000h / 1024
|
|
||||||
jae @f
|
|
||||||
nomem:
|
|
||||||
mov si, nomem_str
|
|
||||||
jmp [err_]
|
|
||||||
@@:
|
|
||||||
shr ax, 3
|
|
||||||
mov [cachelimit], ax ; size of cache - 1
|
|
||||||
; get type of file system - FAT12 or FAT16?
|
|
||||||
; calculate number of clusters
|
|
||||||
mov ax, [BPB_TotSec16]
|
|
||||||
xor dx, dx
|
|
||||||
test ax, ax
|
|
||||||
jnz @f
|
|
||||||
mov ax, word [BPB_TotSec32]
|
|
||||||
mov dx, word [BPB_TotSec32+2]
|
|
||||||
@@:
|
|
||||||
sub ax, [bp-8] ; dword [bp-8] = first data sector
|
|
||||||
sbb dx, [bp-6]
|
|
||||||
jb j_noloader
|
|
||||||
div [sect_per_clus]
|
|
||||||
; ax = number of clusters
|
|
||||||
; note: this is loader for FAT12/FAT16, so 'div' does not overflow on correct volumes
|
|
||||||
mov [fat_type], ch
|
|
||||||
cmp ax, 0xFF5
|
|
||||||
jb init_fat12
|
|
||||||
inc [fat_type]
|
|
||||||
init_fat16:
|
|
||||||
; no sectors loaded
|
|
||||||
mov di, 0x8200
|
|
||||||
xor ax, ax
|
|
||||||
mov cx, 0x100/2
|
|
||||||
rep stosw
|
|
||||||
jmp init_fat_done
|
|
||||||
init_fat12:
|
|
||||||
; read FAT
|
|
||||||
push 0x6000
|
|
||||||
pop es
|
|
||||||
mov ax, [BPB_RsvdSecCnt]
|
|
||||||
mov cx, [BPB_FATSz16]
|
|
||||||
cmp cx, 12
|
|
||||||
jb @f
|
|
||||||
mov cx, 12
|
|
||||||
@@:
|
|
||||||
xor dx, dx
|
|
||||||
call [read_sectors]
|
|
||||||
init_fat_done:
|
|
||||||
; if cluster = sector, we need to read second part of our file
|
|
||||||
; (bootsector loads only first cluster of kordldr.f1x)
|
|
||||||
pop cx ax ; restore our position on disk
|
|
||||||
cmp cx, 1
|
|
||||||
ja kordldr_full
|
|
||||||
sub ax, [bp-8]
|
|
||||||
inc ax
|
|
||||||
inc ax ; ax = first cluster of kordldr.f12
|
|
||||||
call get_next_cluster
|
|
||||||
jc @f
|
|
||||||
j_noloader:
|
|
||||||
jmp [noloader]
|
|
||||||
@@:
|
|
||||||
dec ax
|
|
||||||
dec ax
|
|
||||||
push 0x800
|
|
||||||
pop es
|
|
||||||
call [read_sectors2]
|
|
||||||
kordldr_full:
|
|
||||||
; ...continue loading...
|
|
||||||
mov di, secondary_loader_info
|
|
||||||
call load_file
|
|
||||||
test bx, bx
|
|
||||||
mov bx, [err_]
|
|
||||||
jz @f
|
|
||||||
mov si, aKernelNotFound
|
|
||||||
jmp bx
|
|
||||||
@@:
|
|
||||||
; for subsequent calls to callback function, hook error handler
|
|
||||||
; mov byte [bx], 0xE9 ; 'jmp' opcode
|
|
||||||
; mov ax, hooked_err - 3
|
|
||||||
; sub ax, bx
|
|
||||||
; mov word [bx+1], ax
|
|
||||||
; push hooked_err / ret
|
|
||||||
mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8)
|
|
||||||
mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8)
|
|
||||||
; set registers for secondary loader
|
|
||||||
mov ah, [BS_DrvNum]
|
|
||||||
mov al, 'f'
|
|
||||||
test ah, ah
|
|
||||||
jns @f
|
|
||||||
sub ah, 80h
|
|
||||||
mov al, 'h'
|
|
||||||
@@:
|
|
||||||
mov bx, '12'
|
|
||||||
cmp [fat_type], 0
|
|
||||||
jz @f
|
|
||||||
mov bh, '6'
|
|
||||||
@@:
|
|
||||||
mov si, callback ; ds:si = far pointer to callback procedure
|
|
||||||
jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000
|
|
||||||
|
|
||||||
nomem_str db 'No memory',0
|
|
||||||
|
|
||||||
chs_proc_addresses:
|
|
||||||
dw chs_read_sectors
|
|
||||||
dw chs_read_sectors2
|
|
||||||
dw chs_lookup_in_root_dir
|
|
||||||
dw chs_scan_for_filename
|
|
||||||
dw chs_err
|
|
||||||
dw chs_noloader
|
|
||||||
lba_proc_addresses:
|
|
||||||
dw lba_read_sectors
|
|
||||||
dw lba_read_sectors2
|
|
||||||
dw lba_lookup_in_root_dir
|
|
||||||
dw lba_scan_for_filename
|
|
||||||
dw lba_err
|
|
||||||
dw lba_noloader
|
|
||||||
|
|
||||||
get_next_cluster:
|
|
||||||
; in: ax = cluster
|
|
||||||
; out: if there is next cluster: CF=1, ax = next cluster
|
|
||||||
; out: if there is no next cluster: CF=0
|
|
||||||
push si
|
|
||||||
cmp [fat_type], 0
|
|
||||||
jnz gnc16
|
|
||||||
; for FAT12
|
|
||||||
push ds
|
|
||||||
push 0x6000
|
|
||||||
pop ds
|
|
||||||
mov si, ax
|
|
||||||
shr si, 1
|
|
||||||
add si, ax
|
|
||||||
test al, 1
|
|
||||||
lodsw
|
|
||||||
jz @f
|
|
||||||
shr ax, 4
|
|
||||||
@@:
|
|
||||||
and ax, 0xFFF
|
|
||||||
cmp ax, 0xFF7
|
|
||||||
pop ds si
|
|
||||||
ret
|
|
||||||
; for FAT16
|
|
||||||
gnc16:
|
|
||||||
; each sector contains 200h bytes = 100h FAT entries
|
|
||||||
; so ah = # of sector, al = offset in sector
|
|
||||||
mov si, ax
|
|
||||||
mov ah, 0
|
|
||||||
shr si, 8
|
|
||||||
; calculate segment for this sector of FAT table
|
|
||||||
; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si)
|
|
||||||
; segment = 6000 + 20*si, offset = 0
|
|
||||||
push es
|
|
||||||
push si
|
|
||||||
shl si, 5
|
|
||||||
add si, 0x6000
|
|
||||||
mov es, si
|
|
||||||
pop si
|
|
||||||
cmp byte [ss:0x8200+si], ah ; sector already loaded?
|
|
||||||
jnz @f
|
|
||||||
; load corresponding sector
|
|
||||||
pusha
|
|
||||||
push es
|
|
||||||
xor bx, bx
|
|
||||||
mov ax, [BPB_RsvdSecCnt]
|
|
||||||
xor dx, dx
|
|
||||||
add ax, si
|
|
||||||
adc dx, bx
|
|
||||||
mov cx, 1 ; read 1 sector
|
|
||||||
call [read_sectors]
|
|
||||||
pop es
|
|
||||||
popa
|
|
||||||
@@:
|
|
||||||
mov si, ax
|
|
||||||
add si, si
|
|
||||||
; mov ax, [es:si]
|
|
||||||
lods word [es:si]
|
|
||||||
pop es
|
|
||||||
cmp ax, 0xFFF7
|
|
||||||
pop si
|
|
||||||
ret
|
|
||||||
|
|
||||||
if $ > 0x8000
|
|
||||||
error 'get_next_cluster must fit in first sector of kordldr.f1x!'
|
|
||||||
end if
|
|
||||||
|
|
||||||
load_file:
|
|
||||||
; in: ss:bp = 0:7C00
|
|
||||||
; in: ds:di -> information structure
|
|
||||||
; dw:dw address
|
|
||||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
|
||||||
; ASCIIZ name
|
|
||||||
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found
|
|
||||||
; out: dx:ax = file size (0xFFFFFFFF if file not found)
|
|
||||||
xor ax, ax ; start from root directory
|
|
||||||
mov dx, -1
|
|
||||||
mov word [filesize], dx
|
|
||||||
mov word [filesize+2], dx ; initialize file size with invalid value
|
|
||||||
lea si, [di+6]
|
|
||||||
parse_dir_loop:
|
|
||||||
; convert name to FAT name
|
|
||||||
push di
|
|
||||||
push ax
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
; convert ASCIIZ filename to FAT name
|
|
||||||
mov di, filename
|
|
||||||
push di
|
|
||||||
mov cx, 8+3
|
|
||||||
mov al, ' '
|
|
||||||
rep stosb
|
|
||||||
pop di
|
|
||||||
mov cl, 8 ; 8 symbols per name
|
|
||||||
mov bl, 1
|
|
||||||
nameloop:
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz namedone
|
|
||||||
cmp al, '/'
|
|
||||||
jz namedone
|
|
||||||
cmp al, '.'
|
|
||||||
jz namedot
|
|
||||||
dec cx
|
|
||||||
js badname
|
|
||||||
cmp al, 'a'
|
|
||||||
jb @f
|
|
||||||
cmp al, 'z'
|
|
||||||
ja @f
|
|
||||||
sub al, 'a'-'A'
|
|
||||||
@@:
|
|
||||||
stosb
|
|
||||||
jmp nameloop
|
|
||||||
namedot:
|
|
||||||
inc bx
|
|
||||||
jp badname
|
|
||||||
add di, cx
|
|
||||||
mov cl, 3
|
|
||||||
jmp nameloop
|
|
||||||
badname: ; do not make direct js/jp to notfound_pop:
|
|
||||||
; this generates long forms of conditional jumps and results in longer code
|
|
||||||
jmp notfound_pop
|
|
||||||
namedone:
|
|
||||||
; scan directory
|
|
||||||
pop ax ; ax = cluster of directory or 0 for root
|
|
||||||
push ds
|
|
||||||
push si
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
mov si, filename ; ds:si -> filename in FAT style
|
|
||||||
test ax, ax
|
|
||||||
jnz lookup_in_notroot_dir
|
|
||||||
; for root directory, use the subroutine from bootsector
|
|
||||||
call [lookup_in_root_dir]
|
|
||||||
jmp lookup_done
|
|
||||||
lookup_in_notroot_dir:
|
|
||||||
; for other directories, read a folder sector-by-sector and scan
|
|
||||||
; first, try to use the cache
|
|
||||||
push ds
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
mov bx, [cachelimit]
|
|
||||||
add bx, bx
|
|
||||||
mov di, foldcache_mark
|
|
||||||
@@:
|
|
||||||
mov dx, [foldcache_clus+di-foldcache_mark+bx]
|
|
||||||
cmp dx, ax
|
|
||||||
jz cacheok
|
|
||||||
test dx, dx
|
|
||||||
jz cacheadd ; the cache has place for new entry
|
|
||||||
dec bx
|
|
||||||
dec bx
|
|
||||||
jns @b
|
|
||||||
; the folder is not present in the cache, so add it
|
|
||||||
; the cache is full; find the oldest entry and replace it with the new one
|
|
||||||
mov dx, [cachelimit]
|
|
||||||
@@:
|
|
||||||
inc bx
|
|
||||||
inc bx
|
|
||||||
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
|
|
||||||
jnz @b
|
|
||||||
cacheadd:
|
|
||||||
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
|
|
||||||
mov [foldcache_clus+di-foldcache_mark+bx], ax
|
|
||||||
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
|
|
||||||
cacheok:
|
|
||||||
; update cache marks
|
|
||||||
mov dx, [di+bx]
|
|
||||||
mov cx, [foldcache_size+di-foldcache_mark+bx]
|
|
||||||
mov di, [cachelimit]
|
|
||||||
add di, di
|
|
||||||
cacheupdate:
|
|
||||||
cmp [foldcache_mark+di], dx
|
|
||||||
adc [foldcache_mark+di], 0
|
|
||||||
dec di
|
|
||||||
dec di
|
|
||||||
jns cacheupdate
|
|
||||||
and [foldcache_mark+bx], 0
|
|
||||||
; done, bx contains (position in cache)*2
|
|
||||||
pop ds
|
|
||||||
; mov dx, bx
|
|
||||||
; shl dx, 8 ; dx = (position in cache)*0x2000/0x10
|
|
||||||
; add dx, 0x9200
|
|
||||||
lea dx, [bx+0x92]
|
|
||||||
xchg dl, dh
|
|
||||||
mov es, dx
|
|
||||||
jcxz not_in_cache
|
|
||||||
call [scan_for_filename]
|
|
||||||
jz lookup_done
|
|
||||||
not_in_cache:
|
|
||||||
; cache miss, read folder data from disk
|
|
||||||
mov bx, cx
|
|
||||||
shr bx, 4
|
|
||||||
shl cx, 5
|
|
||||||
mov di, cx ; es:di -> free space in cache entry
|
|
||||||
; external loop: scan clusters
|
|
||||||
folder_next_cluster:
|
|
||||||
; internal loop: scan sectors in cluster
|
|
||||||
mov cx, [sect_per_clus]
|
|
||||||
push ax
|
|
||||||
dec ax
|
|
||||||
dec ax
|
|
||||||
mul cx
|
|
||||||
add ax, [bp-8]
|
|
||||||
adc dx, [bp-6] ; dx:ax = absolute sector
|
|
||||||
folder_next_sector:
|
|
||||||
; skip first bx sectors
|
|
||||||
dec bx
|
|
||||||
jns folder_skip_sector
|
|
||||||
push cx
|
|
||||||
push es di
|
|
||||||
push 0x8000
|
|
||||||
pop es
|
|
||||||
xor bx, bx
|
|
||||||
mov cx, 1
|
|
||||||
push es
|
|
||||||
call [read_sectors]
|
|
||||||
; copy data to the cache...
|
|
||||||
pop ds
|
|
||||||
pop di es
|
|
||||||
cmp di, 0x2000 ; ...if there is free space, of course
|
|
||||||
jae @f
|
|
||||||
push si di
|
|
||||||
mov cx, 0x100
|
|
||||||
xor si, si
|
|
||||||
rep movsw
|
|
||||||
mov di, es
|
|
||||||
shr di, 8
|
|
||||||
add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache
|
|
||||||
pop di si
|
|
||||||
@@:
|
|
||||||
push es
|
|
||||||
push 0x8000
|
|
||||||
pop es
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
mov cx, 0x10
|
|
||||||
call [scan_for_filename]
|
|
||||||
pop es
|
|
||||||
pop cx
|
|
||||||
jz lookup_done_pop
|
|
||||||
folder_skip_sector:
|
|
||||||
inc ax
|
|
||||||
jnz @f
|
|
||||||
inc dx
|
|
||||||
@@:
|
|
||||||
loop folder_next_sector
|
|
||||||
pop ax ; ax = current cluster
|
|
||||||
call get_next_cluster
|
|
||||||
jc folder_next_cluster
|
|
||||||
stc
|
|
||||||
push ax
|
|
||||||
lookup_done_pop:
|
|
||||||
pop ax
|
|
||||||
lookup_done:
|
|
||||||
pop si
|
|
||||||
pop ds
|
|
||||||
; CF=1 <=> failed
|
|
||||||
jnc found
|
|
||||||
notfound:
|
|
||||||
pop di
|
|
||||||
mov bx, 2 ; file not found
|
|
||||||
mov ax, 0xFFFF
|
|
||||||
mov dx, ax ; invalid file size
|
|
||||||
ret
|
|
||||||
notfound_pop:
|
|
||||||
pop ax
|
|
||||||
jmp notfound
|
|
||||||
found:
|
|
||||||
mov ax, [es:di+26] ; get cluster
|
|
||||||
test byte [es:di+11], 10h ; directory?
|
|
||||||
jz regular_file
|
|
||||||
cmp byte [si-1], 0
|
|
||||||
jz notfound ; don't read directories as a regular files
|
|
||||||
; ok, we have found a directory and the caller requested a file into it
|
|
||||||
pop di
|
|
||||||
jmp parse_dir_loop ; restart with new cluster in ax
|
|
||||||
regular_file:
|
|
||||||
cmp byte [si-1], 0
|
|
||||||
jnz notfound ; file does not contain another files
|
|
||||||
; ok, we have found a regular file and the caller requested it
|
|
||||||
; save file size
|
|
||||||
mov dx, [es:di+28]
|
|
||||||
mov [filesize], dx
|
|
||||||
mov dx, [es:di+30]
|
|
||||||
mov [filesize+2], dx
|
|
||||||
pop di
|
|
||||||
mov si, [di+4]
|
|
||||||
shl si, 3
|
|
||||||
push si ; [ds:di+4] = limit in 4K blocks
|
|
||||||
les bx, [di] ; es:bx -> buffer
|
|
||||||
clusloop:
|
|
||||||
; ax = first cluster, top of stack contains limit in sectors
|
|
||||||
mov si, ax ; remember current cluster
|
|
||||||
xor cx, cx ; cx will contain number of consecutive clusters
|
|
||||||
mov word [cur_delta], cx
|
|
||||||
mov word [cur_delta+2], cx
|
|
||||||
mov di, ax
|
|
||||||
clusfind:
|
|
||||||
inc di
|
|
||||||
inc cx
|
|
||||||
call get_next_cluster
|
|
||||||
jnc clusread
|
|
||||||
cmp ax, di
|
|
||||||
jz clusfind
|
|
||||||
stc
|
|
||||||
clusread:
|
|
||||||
pop di ; limit in sectors
|
|
||||||
push ax ; save next cluster
|
|
||||||
pushf ; save flags
|
|
||||||
; read cx clusters, starting from si
|
|
||||||
; calculate number of sectors
|
|
||||||
xchg ax, cx
|
|
||||||
mul [sect_per_clus]
|
|
||||||
; dx:ax = number of sectors; compare with limit
|
|
||||||
mov word [num_sectors], ax
|
|
||||||
mov word [num_sectors+2], dx
|
|
||||||
jmp @f
|
|
||||||
continue_load_file:
|
|
||||||
les bx, [di] ; es:bx -> buffer
|
|
||||||
mov di, [di+4] ; ds:di = limit in 4K blocks
|
|
||||||
shl di, 3 ; now di = limit in sectors
|
|
||||||
mov ax, word [num_sectors]
|
|
||||||
mov dx, word [num_sectors+2]
|
|
||||||
mov si, [cur_cluster]
|
|
||||||
push [next_cluster]
|
|
||||||
push [flags]
|
|
||||||
or ax, dx
|
|
||||||
jz nextclus
|
|
||||||
@@:
|
|
||||||
test dx, dx
|
|
||||||
jnz clusdecrease
|
|
||||||
push dx ; limit was not exceeded
|
|
||||||
cmp ax, di
|
|
||||||
jbe @f
|
|
||||||
pop ax
|
|
||||||
clusdecrease:
|
|
||||||
push 1 ; limit was exceeded
|
|
||||||
mov ax, di
|
|
||||||
@@:
|
|
||||||
sub di, ax ; calculate new limit
|
|
||||||
sub word [num_sectors], ax
|
|
||||||
sbb word [num_sectors+2], 0
|
|
||||||
; calculate starting sector
|
|
||||||
xchg ax, cx
|
|
||||||
lea ax, [si-2]
|
|
||||||
mul [sect_per_clus]
|
|
||||||
add ax, word [cur_delta]
|
|
||||||
adc dx, word [cur_delta+2]
|
|
||||||
add word [cur_delta], cx
|
|
||||||
adc word [cur_delta+2], 0
|
|
||||||
; read
|
|
||||||
call [read_sectors2]
|
|
||||||
pop dx
|
|
||||||
; next cluster?
|
|
||||||
nextclus:
|
|
||||||
popf
|
|
||||||
pop ax
|
|
||||||
mov [cur_cluster], si
|
|
||||||
mov [next_cluster], ax
|
|
||||||
pushf
|
|
||||||
pop [flags]
|
|
||||||
jnc @f ; no next cluster => return
|
|
||||||
mov dl, 1 ; dh=0 in any case
|
|
||||||
test di, di
|
|
||||||
jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded
|
|
||||||
push di
|
|
||||||
jmp clusloop ; all is ok, continue
|
|
||||||
hooked_err:
|
|
||||||
mov sp, 7C00h-12-2 ; restore stack
|
|
||||||
mov dx, 3 ; return: read error
|
|
||||||
@@:
|
|
||||||
mov bx, dx
|
|
||||||
mov ax, [filesize]
|
|
||||||
mov dx, [filesize+2]
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Callback function for secondary loader
|
|
||||||
callback:
|
|
||||||
; in: ax = function number; only functions 1 and 2 are defined for now
|
|
||||||
; save caller's stack
|
|
||||||
mov dx, ss
|
|
||||||
mov cx, sp
|
|
||||||
; set our stack (required because we need ss=0)
|
|
||||||
xor si, si
|
|
||||||
mov ss, si
|
|
||||||
mov sp, 7C00h-8
|
|
||||||
mov bp, 7C00h
|
|
||||||
push dx
|
|
||||||
push cx
|
|
||||||
; call our function
|
|
||||||
stc ; unsupported function
|
|
||||||
dec ax
|
|
||||||
jz callback_readfile
|
|
||||||
dec ax
|
|
||||||
jnz callback_ret
|
|
||||||
; function 2: continue loading file
|
|
||||||
; can be called only after function 1 returned value bx=1 (only part of file was loaded)
|
|
||||||
; in: ds:di -> information structure
|
|
||||||
; dw:dw address
|
|
||||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
|
||||||
; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error
|
|
||||||
; out: dx:ax = file size
|
|
||||||
call continue_load_file
|
|
||||||
jmp callback_ret_succ
|
|
||||||
callback_readfile:
|
|
||||||
; function 1: read file
|
|
||||||
; in: ds:di -> information structure
|
|
||||||
; dw:dw address
|
|
||||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
|
||||||
; ASCIIZ name
|
|
||||||
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
|
|
||||||
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
|
|
||||||
call load_file
|
|
||||||
callback_ret_succ:
|
|
||||||
clc ; function is supported
|
|
||||||
callback_ret:
|
|
||||||
; restore caller's stack
|
|
||||||
pop cx
|
|
||||||
pop ss
|
|
||||||
mov sp, cx
|
|
||||||
; return to caller
|
|
||||||
retf
|
|
||||||
|
|
||||||
secondary_loader_info:
|
|
||||||
dw 0, 0x1000
|
|
||||||
dw 0x30000 / 0x1000
|
|
||||||
db 'kord/loader',0
|
|
||||||
aKernelNotFound db 'Fatal error: cannot load the secondary loader',0
|
|
||||||
|
|
||||||
foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache
|
|
||||||
foldcache_mark rw 7
|
|
||||||
foldcache_size rw 7
|
|
||||||
filename rb 11
|
|
||||||
if $ > 0x8200
|
|
||||||
error: table overwritten
|
|
||||||
end if
|
|
@ -1,358 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
use_lba = 0
|
|
||||||
org 0x7C00
|
|
||||||
jmp start
|
|
||||||
nop
|
|
||||||
; FAT parameters, BPB
|
|
||||||
; they must be changed at install, replaced with real values
|
|
||||||
rb 8 ; BS_OEMName, ignored
|
|
||||||
dw 200h ; BPB_BytsPerSec
|
|
||||||
BPB_SecsPerClus db ?
|
|
||||||
BPB_RsvdSecCnt dw ?
|
|
||||||
BPB_NumFATs db ?
|
|
||||||
BPB_RootEntCnt dw ?
|
|
||||||
dw ? ; BPB_TotSec16
|
|
||||||
db ? ; BPB_Media
|
|
||||||
dw ? ; BPB_FATSz16 = 0 for FAT32
|
|
||||||
BPB_SecPerTrk dw ?
|
|
||||||
BPB_NumHeads dw ?
|
|
||||||
BPB_HiddSec dd ?
|
|
||||||
dd ? ; BPB_TotSec32
|
|
||||||
BPB_FATSz32 dd ?
|
|
||||||
BPB_ExtFlags dw ?
|
|
||||||
dw ? ; BPB_FSVer
|
|
||||||
BPB_RootClus dd ?
|
|
||||||
dw ? ; BPB_FSInfo
|
|
||||||
BPB_BkBootSec dw ?
|
|
||||||
rb 12 ; BPB_Reserved
|
|
||||||
BS_DrvNum db ?
|
|
||||||
db ? ; BS_Reserved1
|
|
||||||
db ? ; BS_BootSig
|
|
||||||
dd ? ; BS_VolID
|
|
||||||
rb 11 ; BS_VolLab
|
|
||||||
rb 8 ;
|
|
||||||
|
|
||||||
curseg dw 0x8000
|
|
||||||
|
|
||||||
start:
|
|
||||||
xor ax, ax
|
|
||||||
mov ss, ax
|
|
||||||
mov sp, 0x7C00
|
|
||||||
mov ds, ax
|
|
||||||
mov bp, sp
|
|
||||||
cld
|
|
||||||
sti
|
|
||||||
push dx ; byte [bp-2] = boot drive
|
|
||||||
if use_lba
|
|
||||||
mov ah, 41h
|
|
||||||
mov bx, 55AAh
|
|
||||||
int 13h
|
|
||||||
mov si, aNoLBA
|
|
||||||
jc err_
|
|
||||||
cmp bx, 0AA55h
|
|
||||||
jnz err_
|
|
||||||
test cl, 1
|
|
||||||
jz err_
|
|
||||||
else
|
|
||||||
mov ah, 8
|
|
||||||
int 13h
|
|
||||||
jc @f
|
|
||||||
movzx ax, dh
|
|
||||||
inc ax
|
|
||||||
mov [bp+BPB_NumHeads-0x7C00], ax
|
|
||||||
and cx, 3Fh
|
|
||||||
mov [bp+BPB_SecPerTrk-0x7C00], cx
|
|
||||||
@@:
|
|
||||||
end if
|
|
||||||
; get FAT parameters
|
|
||||||
xor bx, bx
|
|
||||||
movzx eax, [bp+BPB_NumFATs-0x7C00]
|
|
||||||
mul [bp+BPB_FATSz32-0x7C00]
|
|
||||||
movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00]
|
|
||||||
push ecx ; FAT start = dword [bp-6]
|
|
||||||
add eax, ecx
|
|
||||||
push eax ; data start = dword [bp-10]
|
|
||||||
;push dword -1 ; dword [bp-14] = current sector for FAT cache
|
|
||||||
db 66h
|
|
||||||
push -1 ; dword [bp-14] = current sector for FAT cache
|
|
||||||
mov eax, [bp+BPB_RootClus-0x7C00]
|
|
||||||
mov si, main_loader
|
|
||||||
call lookup_in_dir
|
|
||||||
jnc kordldr_ok
|
|
||||||
noloader:
|
|
||||||
mov si, aLoaderNotFound
|
|
||||||
err_:
|
|
||||||
call out_string
|
|
||||||
mov si, aPressAnyKey
|
|
||||||
call out_string
|
|
||||||
xor ax, ax
|
|
||||||
int 16h
|
|
||||||
int 18h
|
|
||||||
jmp $
|
|
||||||
kordldr_ok:
|
|
||||||
mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster)
|
|
||||||
mov ax, [es:di+26] ; loword(eax) = loword(cluster)
|
|
||||||
mov es, bx ; es = 0
|
|
||||||
mov bx, 0x7E00
|
|
||||||
push bx ; save return address: bx = 7E00
|
|
||||||
; fall through - 'ret' in read_cluster will return to 7E00
|
|
||||||
|
|
||||||
read_cluster:
|
|
||||||
; ss:bp = 0:7C00
|
|
||||||
; es:bx = pointer to data
|
|
||||||
; eax = cluster
|
|
||||||
sub eax, 2
|
|
||||||
movzx ecx, [bp+BPB_SecsPerClus-0x7C00]
|
|
||||||
mul ecx
|
|
||||||
|
|
||||||
read_sectors2:
|
|
||||||
; same as read_sectors32, but eax is relative to start of data
|
|
||||||
add eax, [bp-10]
|
|
||||||
read_sectors32:
|
|
||||||
; ss:bp = 0:7C00
|
|
||||||
; es:bx = pointer to data
|
|
||||||
; eax = first sector
|
|
||||||
; cx = number of sectors
|
|
||||||
; some high words of 32-bit registers are destroyed!
|
|
||||||
pusha
|
|
||||||
add eax, [bp+BPB_HiddSec-0x7C00]
|
|
||||||
if use_lba
|
|
||||||
push ds
|
|
||||||
do_read_sectors:
|
|
||||||
push ax
|
|
||||||
push cx
|
|
||||||
cmp cx, 0x7F
|
|
||||||
jbe @f
|
|
||||||
mov cx, 0x7F
|
|
||||||
@@:
|
|
||||||
; create disk address packet on the stack
|
|
||||||
; dq starting LBA
|
|
||||||
push 0
|
|
||||||
push 0
|
|
||||||
push eax
|
|
||||||
; dd buffer
|
|
||||||
push es
|
|
||||||
push bx
|
|
||||||
; dw number of blocks to transfer (no more than 0x7F)
|
|
||||||
push cx
|
|
||||||
; dw packet size in bytes
|
|
||||||
push 10h
|
|
||||||
; issue BIOS call
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov si, sp
|
|
||||||
mov dl, [bp-2]
|
|
||||||
mov ah, 42h
|
|
||||||
int 13h
|
|
||||||
mov si, aReadError
|
|
||||||
jc err_
|
|
||||||
; restore stack
|
|
||||||
add sp, 10h
|
|
||||||
; increase current sector & buffer; decrease number of sectors
|
|
||||||
movzx esi, cx
|
|
||||||
mov ax, es
|
|
||||||
shl cx, 5
|
|
||||||
add ax, cx
|
|
||||||
mov es, ax
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
add eax, esi
|
|
||||||
sub cx, si
|
|
||||||
jnz do_read_sectors
|
|
||||||
pop ds
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
else
|
|
||||||
do_read_sectors:
|
|
||||||
pusha
|
|
||||||
pop edi ; loword(edi) = di, hiword(edi) = si
|
|
||||||
push bx
|
|
||||||
|
|
||||||
; eax / (SectorsPerTrack) -> eax, remainder bx
|
|
||||||
movzx esi, [bp+BPB_SecPerTrk-0x7C00]
|
|
||||||
xor edx, edx
|
|
||||||
div esi
|
|
||||||
mov bx, dx ; bx=sector-1
|
|
||||||
|
|
||||||
; eax -> dx:ax
|
|
||||||
push eax
|
|
||||||
pop ax
|
|
||||||
pop dx
|
|
||||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
|
||||||
div [bp+BPB_NumHeads-0x7C00]
|
|
||||||
|
|
||||||
; number of sectors: read no more than to end of track
|
|
||||||
sub si, bx
|
|
||||||
cmp cx, si
|
|
||||||
jbe @f
|
|
||||||
mov cx, si
|
|
||||||
@@:
|
|
||||||
|
|
||||||
inc bx
|
|
||||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
|
|
||||||
movzx edi, cx
|
|
||||||
mov dh, dl
|
|
||||||
mov dl, [bp-2]
|
|
||||||
shl ah, 6
|
|
||||||
mov ch, al
|
|
||||||
mov al, cl
|
|
||||||
mov cl, bl
|
|
||||||
or cl, ah
|
|
||||||
pop bx
|
|
||||||
mov si, 3
|
|
||||||
mov ah, 2
|
|
||||||
@@:
|
|
||||||
push ax
|
|
||||||
int 13h
|
|
||||||
jnc @f
|
|
||||||
xor ax, ax
|
|
||||||
int 13h ; reset drive
|
|
||||||
pop ax
|
|
||||||
dec si
|
|
||||||
jnz @b
|
|
||||||
mov si, aReadError
|
|
||||||
jmp err_
|
|
||||||
@@:
|
|
||||||
pop ax
|
|
||||||
mov ax, es
|
|
||||||
mov cx, di
|
|
||||||
shl cx, 5
|
|
||||||
add ax, cx
|
|
||||||
mov es, ax
|
|
||||||
push edi
|
|
||||||
popa
|
|
||||||
add eax, edi
|
|
||||||
sub cx, di
|
|
||||||
jnz do_read_sectors
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
end if
|
|
||||||
|
|
||||||
lookup_in_dir:
|
|
||||||
; in: ds:si -> 11-bytes FAT name
|
|
||||||
; in: eax = cluster
|
|
||||||
; in: bx = 0
|
|
||||||
; out: if found: CF=0, es:di -> directory entry
|
|
||||||
; out: if not found: CF=1
|
|
||||||
; push 0x8000
|
|
||||||
; pop es
|
|
||||||
; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000
|
|
||||||
mov es, [bp-7C00h + curseg]
|
|
||||||
push es
|
|
||||||
push eax
|
|
||||||
call read_cluster
|
|
||||||
mov ax, es
|
|
||||||
cmp ah, 82h
|
|
||||||
jb @f
|
|
||||||
mov ax, 8200h
|
|
||||||
@@:
|
|
||||||
mov [bp-7C00h + curseg], ax
|
|
||||||
pop eax
|
|
||||||
pop es
|
|
||||||
; scan for filename
|
|
||||||
shl cx, 4
|
|
||||||
xor di, di
|
|
||||||
sloop:
|
|
||||||
cmp byte [es:di], bl
|
|
||||||
jz snotfound
|
|
||||||
test byte [es:di+11], 8 ; volume label?
|
|
||||||
jnz scont ; ignore volume labels
|
|
||||||
pusha
|
|
||||||
mov cx, 11
|
|
||||||
repz cmpsb
|
|
||||||
popa
|
|
||||||
jz sdone
|
|
||||||
scont:
|
|
||||||
add di, 0x20
|
|
||||||
loop sloop
|
|
||||||
; next cluster
|
|
||||||
push 0x6000
|
|
||||||
pop es
|
|
||||||
push es ax
|
|
||||||
shr eax, 7
|
|
||||||
cmp eax, [bp-14]
|
|
||||||
mov [bp-14], eax
|
|
||||||
jz @f
|
|
||||||
add eax, [bp-6]
|
|
||||||
mov cx, 1
|
|
||||||
call read_sectors32
|
|
||||||
@@:
|
|
||||||
pop di es
|
|
||||||
and di, 0x7F
|
|
||||||
shl di, 2
|
|
||||||
and byte [es:di+3], 0x0F
|
|
||||||
mov eax, [es:di]
|
|
||||||
;and eax, 0x0FFFFFFF
|
|
||||||
cmp eax, 0x0FFFFFF7
|
|
||||||
jb lookup_in_dir
|
|
||||||
snotfound:
|
|
||||||
stc
|
|
||||||
sdone:
|
|
||||||
ret
|
|
||||||
|
|
||||||
out_string:
|
|
||||||
; in: ds:si -> ASCIIZ string
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz sdone
|
|
||||||
mov ah, 0Eh
|
|
||||||
mov bx, 7
|
|
||||||
int 10h
|
|
||||||
jmp out_string
|
|
||||||
|
|
||||||
aReadError db 'Read error',0
|
|
||||||
if use_lba
|
|
||||||
aNoLBA db 'The drive does not support LBA!',0
|
|
||||||
end if
|
|
||||||
aLoaderNotFound db 'Loader not found',0
|
|
||||||
aPressAnyKey db 13,10,'Press any key...',13,10,0
|
|
||||||
main_loader db 'KORDLDR F32'
|
|
||||||
|
|
||||||
db 56h
|
|
||||||
; just to make file 512 bytes long :)
|
|
||||||
db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
|
|
||||||
|
|
||||||
; bootsector signature
|
|
||||||
dw 0xAA55
|
|
||||||
|
|
||||||
; display offsets of all procedures used by kordldr.f12.asm
|
|
||||||
macro show [procedure]
|
|
||||||
{
|
|
||||||
bits = 16
|
|
||||||
display `procedure,' = '
|
|
||||||
repeat bits/4
|
|
||||||
d = '0' + procedure shr (bits - %*4) and 0Fh
|
|
||||||
if d > '9'
|
|
||||||
d = d + 'A'-'9'-1
|
|
||||||
end if
|
|
||||||
display d
|
|
||||||
end repeat
|
|
||||||
display 13,10
|
|
||||||
}
|
|
||||||
|
|
||||||
show read_sectors32, read_sectors2, err_, noloader
|
|
@ -1,333 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
Читай между строк - там никогда не бывает опечаток.
|
|
||||||
|
|
||||||
Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт.
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Есть две версии в зависимости от того, поддерживает ли носитель LBA,
|
|
||||||
выбор осуществляется установкой константы use_lba в первой строке исходника.
|
|
||||||
Требования для работы:
|
|
||||||
1) Сам бутсектор, первая копия FAT и все используемые файлы
|
|
||||||
должны быть читабельны. (Если дело происходит на носителе с разбиением на
|
|
||||||
разделы и загрузочный код в MBR достаточно умный, то читабельности резервной
|
|
||||||
копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности
|
|
||||||
самого бутсектора).
|
|
||||||
2) Минимальный процессор - 80386.
|
|
||||||
3) В системе должно быть как минимум 584K свободной базовой памяти.
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Документация в тему (ссылки проверялись на валидность 15.05.2008):
|
|
||||||
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
|
||||||
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
|
|
||||||
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip
|
|
||||||
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
|
|
||||||
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
|
|
||||||
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
|
|
||||||
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Схема используемой памяти:
|
|
||||||
...-7C00 стек
|
|
||||||
7C00-7E00 код бутсектора
|
|
||||||
7E00-8200 вспомогательный файл загрузчика (kordldr.f32)
|
|
||||||
8400-8C00 информация о кэше для таблицы FAT: 100h входов по 8
|
|
||||||
байт: 4 байта (две ссылки - вперёд и назад) для
|
|
||||||
организации L2-списка всех прочитанных секторов в
|
|
||||||
порядке возрастания последнего времени использования
|
|
||||||
+ 4 байта для номера сектора; при переполнении кэша
|
|
||||||
выкидывается элемент из головы списка, то есть тот,
|
|
||||||
к которому дольше всех не было обращений
|
|
||||||
60000-80000 кэш для таблицы FAT (100h секторов)
|
|
||||||
80000-90000 текущий кластер текущей рассматриваемой папки
|
|
||||||
90000-... кэш для содержимого папок (каждой папке отводится
|
|
||||||
2000h байт = 100h входов, одновременно в кэше
|
|
||||||
может находиться не более 8 папок;
|
|
||||||
точный размер определяется размером доступной
|
|
||||||
физической памяти - как правило, непосредственно
|
|
||||||
перед A0000 размещается EBDA, Extended BIOS Data Area)
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Основной процесс загрузки.
|
|
||||||
Точка входа (start): получает управление от BIOS при загрузке, при этом
|
|
||||||
dl содержит идентификатор диска, с которого идёт загрузка
|
|
||||||
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед
|
|
||||||
кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало
|
|
||||||
бутсектора (в дальнейшем данные будут адресоваться через [bp+N] -
|
|
||||||
это освобождает ds и экономит на размере кода). Сохраняет в стеке
|
|
||||||
идентификатор загрузочного диска для последующего обращения
|
|
||||||
через byte [bp-2].
|
|
||||||
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h
|
|
||||||
прерывания 13h. Если нет, переходит на код обработки ошибок с
|
|
||||||
сообщением об отсутствии LBA.
|
|
||||||
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и
|
|
||||||
записывает полученные данные поверх BPB. Если вызов завершился ошибкой,
|
|
||||||
предполагает уже существующие данные корректными.
|
|
||||||
3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего
|
|
||||||
обращения через dword [bp-10]. В процессе вычисления узнаёт начало
|
|
||||||
первой FAT, сохраняет и его в стек для последующего обращения через
|
|
||||||
dword [bp-6].
|
|
||||||
4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1
|
|
||||||
для последующего обращения через dword [bp-14] - инициализация
|
|
||||||
переменной, содержащей текущий сектор, находящийся в кэше FAT
|
|
||||||
(-1 не является валидным значением для номера сектора FAT).
|
|
||||||
5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на
|
|
||||||
код обработки ошибок с сообщением о ненайденном загрузчике.
|
|
||||||
Замечание: на этом этапе загрузки искать можно только в корневой
|
|
||||||
папке и только имена, заданные в формате файловой системе FAT
|
|
||||||
(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны
|
|
||||||
быть заглавными, при необходимости имя и расширение дополняются
|
|
||||||
пробелами, разделяющей точки нет, завершающего нуля нет).
|
|
||||||
6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт
|
|
||||||
ему управление. При этом в регистре eax оказывается абсолютный
|
|
||||||
номер первого сектора kordldr.f32, а в cx - число считанных секторов
|
|
||||||
(равное размеру кластера).
|
|
||||||
|
|
||||||
Вспомогательные процедуры бутсектора.
|
|
||||||
Код обработки ошибок (err):
|
|
||||||
1. Выводит строку с сообщением об ошибке.
|
|
||||||
2. Выводит строку "Press any key...".
|
|
||||||
3. Ждёт нажатия any key.
|
|
||||||
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
|
|
||||||
5. Для подстраховки зацикливается.
|
|
||||||
|
|
||||||
Процедура чтения кластера (read_cluster):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
ss:bp = 0:7C00
|
|
||||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
|
||||||
eax = номер кластера
|
|
||||||
на выходе: ecx = число прочитанных секторов (размер кластера),
|
|
||||||
es:bx указывает на конец буфера, в который были прочитаны данные,
|
|
||||||
eax и старшие слова других 32-битных регистров разрушаются
|
|
||||||
Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора
|
|
||||||
и переходит к следующей процедуре.
|
|
||||||
|
|
||||||
Процедура чтения секторов (read_sectors32 и read_sectors2):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
ss:bp = 0:7C00
|
|
||||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
|
||||||
eax = стартовый сектор (относительно начала логического диска
|
|
||||||
для read_sectors32, относительно начала данных
|
|
||||||
для read_sectors2)
|
|
||||||
cx = число секторов (должно быть больше нуля)
|
|
||||||
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные
|
|
||||||
старшие слова 32-битных регистров могут разрушиться
|
|
||||||
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора
|
|
||||||
в номер относительно начала логического диска, прибавляя номер сектора
|
|
||||||
начала данных, хранящийся в стеке как [bp-10].
|
|
||||||
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на
|
|
||||||
устройстве, прибавляя значение соответствующего поля из BPB.
|
|
||||||
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации
|
|
||||||
CHS-версия: все читаемые секторы были на одной дорожке.
|
|
||||||
LBA-версия: число читаемых секторов не превосходило 7Fh (требование
|
|
||||||
спецификации EDD BIOS).
|
|
||||||
CHS-версия:
|
|
||||||
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как
|
|
||||||
единица плюс остаток от деления абсолютного номера на число секторов
|
|
||||||
на дорожке; дорожка рассчитывается как остаток от деления частного,
|
|
||||||
полученного на предыдущем шаге, на число дорожек, а цилиндр - как
|
|
||||||
частное от этого же деления. Если число секторов для чтения больше,
|
|
||||||
чем число секторов до конца дорожки, уменьшает число секторов для
|
|
||||||
чтения.
|
|
||||||
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов,
|
|
||||||
dh=головка, (младшие 6 бит cl)=сектор,
|
|
||||||
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер).
|
|
||||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска
|
|
||||||
и повторяет попытку чтения, всего делается не более трёх попыток
|
|
||||||
(несколько попыток нужно в случае дискеты для гарантии того, что
|
|
||||||
мотор раскрутился). Если все три раза происходит ошибка чтения,
|
|
||||||
переходит на код обработки ошибок с сообщением "Read error".
|
|
||||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
|
||||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
|
||||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
|
||||||
работу, иначе возвращается на шаг 3.
|
|
||||||
LBA-версия:
|
|
||||||
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
|
|
||||||
итерации) до 7Fh.
|
|
||||||
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
|
|
||||||
push, причём в обратном порядке: стек - структура LIFO, и данные в
|
|
||||||
стеке хранятся в обратном порядке по отношению к тому, как их туда
|
|
||||||
клали).
|
|
||||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки
|
|
||||||
ошибок с сообщением "Read error". Очищает стек от пакета,
|
|
||||||
сформированного на предыдущем шаге.
|
|
||||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
|
||||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
|
||||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
|
||||||
работу, иначе возвращается на шаг 3.
|
|
||||||
|
|
||||||
Процедура поиска элемента в папке (lookup_in_dir):
|
|
||||||
на входе должно быть установлено:
|
|
||||||
ss:bp = 0:7C00
|
|
||||||
ds:si = указатель на имя файла в формате FAT (см. выше)
|
|
||||||
eax = начальный кластер папки
|
|
||||||
bx = 0
|
|
||||||
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то
|
|
||||||
CF сброшен и es:di указывает на элемент папки
|
|
||||||
В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных
|
|
||||||
данных. Для чтения кластера использует уже описанную процедуру read_clusters,
|
|
||||||
для продвижения по цепочке кластеров - описанную далее процедуру
|
|
||||||
get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса
|
|
||||||
8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше,
|
|
||||||
если чтение прервётся раньше) не перекрываются последующими чтениями
|
|
||||||
(это будет использовано позднее, в системе кэширования из kordldr.f32).
|
|
||||||
Выход осуществляется в любом из следующих случаев: найден запрошенный элемент;
|
|
||||||
кончились элементы в папке (первый байт очередного элемента нулевой);
|
|
||||||
кончились данные папки в соответствии с цепочкой кластеров из FAT.
|
|
||||||
|
|
||||||
Процедура вывода на экран ASCIIZ-строки (out_string):
|
|
||||||
на входе: ds:si -> строка
|
|
||||||
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh.
|
|
||||||
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
Работа вспомогательного загрузчика kordldr.f32:
|
|
||||||
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора.
|
|
||||||
В зависимости от этого устанавливает смещения используемых процедур
|
|
||||||
бутсектора. Критерий проверки: в CHS-версии по адресу err находится
|
|
||||||
байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу
|
|
||||||
находится байт 0x14, а адрес процедуры err другой.
|
|
||||||
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска
|
|
||||||
адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с
|
|
||||||
ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента
|
|
||||||
место должно быть, отсюда ограничение в 592 Kb (94000h байт).
|
|
||||||
Замечание: этот размер не может превосходить 0A0000h байт и
|
|
||||||
на практике оказывается немного (на 1-2 килобайта) меньшим из-за
|
|
||||||
наличия дополнительной области данных BIOS "вверху" базовой памяти.
|
|
||||||
3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть
|
|
||||||
данных корневой папки; копирует загруженные данные в кэш и запоминает,
|
|
||||||
что в кэше есть корневая папка.
|
|
||||||
4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только
|
|
||||||
том случае, когда ему приходится загружать данные корневой папки,
|
|
||||||
не поместившиеся в один кластер. В этом случае в памяти присутствует
|
|
||||||
один сектор FAT (если было несколько обращений - последний из
|
|
||||||
использованных).
|
|
||||||
5. Если кластер равен сектору, то бутсектор загрузил только часть файла
|
|
||||||
kordldr.f32, и загрузчик подгружает вторую свою часть, используя
|
|
||||||
значения регистров на входе в kordldr.f32.
|
|
||||||
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не
|
|
||||||
найден, или оказался папкой, или оказался слишком большим, то переходит
|
|
||||||
на код обработки ошибок из бутсектора с сообщением
|
|
||||||
"Fatal error: cannot load the secondary loader".
|
|
||||||
Замечание: на этом этапе имя файла уже можно указывать вместе с путём
|
|
||||||
и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов
|
|
||||||
по-прежнему нет.
|
|
||||||
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err.
|
|
||||||
Это нужно, чтобы последующие обращения к коду бутсектора в случае
|
|
||||||
ошибок чтения не выводил соответствующее сообщение с последующей
|
|
||||||
перезагрузкой, а рапортовал об ошибке чтения, которую могло бы
|
|
||||||
как-нибудь обработать ядро.
|
|
||||||
8. Если загрузочный диск имеет идентификатор меньше 0x80,
|
|
||||||
то устанавливает al='f' ("floppy"), ah=идентификатор диска,
|
|
||||||
иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска).
|
|
||||||
(Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но
|
|
||||||
уверены ли Вы, что нет загрузочных устройств, подобных дискетам,
|
|
||||||
но большего размера, и для которых BIOS-идентификатор меньше 0x80?)
|
|
||||||
Устанавливает bx='32' (тип файловой системы - FAT32).
|
|
||||||
Устанавливает si=смещение функции обратного вызова. Поскольку в этот
|
|
||||||
момент ds=0, то ds:si образуют полный адрес.
|
|
||||||
9. Передаёт управление по адресу 1000:0000.
|
|
||||||
|
|
||||||
Функция обратного вызова для вторичного загрузчика:
|
|
||||||
предоставляет возможность чтения файла.
|
|
||||||
Вход и выход описаны в спецификации на загрузчик.
|
|
||||||
1. Сохраняет стек вызывающего кода и устанавливает свой стек:
|
|
||||||
ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным
|
|
||||||
кодом должна указывать на 0:7C00, а -10 берётся от того, что
|
|
||||||
инициализирующий код бутсектора уже поместил в стек 10 байт параметров,
|
|
||||||
и они должны сохраняться в неизменности. (Значение [ebp-14],
|
|
||||||
"текущий сектор, находящийся в кэше FAT", не используется после
|
|
||||||
инициализации кэширования в kordldr.f32.)
|
|
||||||
2. Разбирает переданные параметры и вызывает нужную из вспомогательных
|
|
||||||
процедур (загрузки файла либо продолжения загрузки файла).
|
|
||||||
3. Восстанавливает стек вызывающего кода и возвращает управление.
|
|
||||||
|
|
||||||
Вспомогательные процедуры kordldr.f32.
|
|
||||||
Процедура получения следующего кластера в FAT (get_next_cluster):
|
|
||||||
1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент.
|
|
||||||
(В секторе 0x200 байт, каждый вход занимает 4 байта.)
|
|
||||||
2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4.
|
|
||||||
3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен,
|
|
||||||
выделяет очередной элемент в конце кэша. Если заполнен, удаляет
|
|
||||||
самый старый элемент (тот, к которому дольше всего не было обращений);
|
|
||||||
для того, чтобы отслеживать порядок элементов по времени последнего
|
|
||||||
обращения, все (выделенные) элементы кэша связаны в двусвязный список,
|
|
||||||
в котором первым элементом является самый старый, а ссылки вперёд
|
|
||||||
указывают на следующий по времени последнего обращения.
|
|
||||||
4. Читает соответствующий сектор FAT с диска.
|
|
||||||
5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции,
|
|
||||||
где он находится, и добавляется в конец. (В случае со свежедобавленными
|
|
||||||
в кэш элементами удаления не делается, поскольку их в списке ещё нет.)
|
|
||||||
6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита.
|
|
||||||
7. Сравнивает прочитанное значение с пределом: если оно строго меньше
|
|
||||||
0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке;
|
|
||||||
в противном случае цепочка закончилась.
|
|
||||||
|
|
||||||
Процедура загрузки файла (load_file):
|
|
||||||
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4.
|
|
||||||
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты
|
|
||||||
разделяются символом '/') в FAT-формат 8+3. Если это невозможно
|
|
||||||
(больше 8 символов в имени, больше 3 символов в расширении или
|
|
||||||
больше одной точки), возвращается с ошибкой.
|
|
||||||
3. Ищет элемент с таким именем в текущей рассматриваемой папке.
|
|
||||||
а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок
|
|
||||||
осуществляется по номеру начального кластера.) Если такой папки ещё
|
|
||||||
нет, добавляет её в кэш; если тот переполняется, выкидывает папку,
|
|
||||||
к которой дольше всего не было обращений. (Для каждого элемента кэша
|
|
||||||
хранится метка от 0 до (размер кэша)-1, определяющая его номер при
|
|
||||||
сортировке по давности последнего обращения. При обращении к какому-то
|
|
||||||
элементу его метка становится нулевой, а те метки, которые меньше
|
|
||||||
старого значения, увеличиваются на единицу.)
|
|
||||||
б) Просматривает в поисках запрошенного имени все элементы из кэша,
|
|
||||||
используя процедуру из бутсектора. Если обнаруживает искомый элемент,
|
|
||||||
переходит к шагу 4. Если обнаруживает конец папки, возвращается из
|
|
||||||
процедуры с ошибкой.
|
|
||||||
в) В цикле считывает папку посекторно. При этом пропускает начальные
|
|
||||||
секторы, которые уже находятся в кэше и уже были просмотрены. Каждый
|
|
||||||
прочитанный сектор копирует в кэш, если там ещё остаётся место,
|
|
||||||
и просматривает в нём все элементы. Работает, пока не случится одно из
|
|
||||||
трёх событий: найден искомый элемент; кончились кластеры (судя по
|
|
||||||
цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце
|
|
||||||
(первый байт нулевой). В двух последних случаях возвращается с ошибкой.
|
|
||||||
4. Проверяет тип найденного элемента (файл/папка): последний элемент в
|
|
||||||
запрошенном имени должен быть файлом, все промежуточные - папками.
|
|
||||||
Если текущий компонент имени - промежуточный, продвигает текущую
|
|
||||||
рассматриваемую папку и возвращается к пункту 2.
|
|
||||||
5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный
|
|
||||||
при вызове буфер последовательными вызовами функции бутсектора;
|
|
||||||
при этом если несколько кластеров файла расположены на диске
|
|
||||||
последовательно, то их чтение объединяется в одну операцию.
|
|
||||||
Следит за тем, чтобы не превысить указанный при вызове процедуры
|
|
||||||
лимит числа секторов для чтения.
|
|
||||||
|
|
||||||
Процедура продолжения загрузки файла (continue_load_file): встроена
|
|
||||||
внутрь шага 5 load_file; загружает в регистры нужные значения (ранее
|
|
||||||
сохранённые из load_file) и продолжает шаг 5.
|
|
@ -1,3 +0,0 @@
|
|||||||
@fasm -m 65535 bootsect.asm bootsect.bin
|
|
||||||
@fasm -m 65535 kordldr.f32.asm kordldr.f32
|
|
||||||
@pause
|
|
@ -1,672 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, diamond
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
org 0x7E00
|
|
||||||
; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here
|
|
||||||
; ss:bp = 0:7C00
|
|
||||||
; ds = 0
|
|
||||||
virtual at bp
|
|
||||||
rb 3 ; BS_jmpBoot
|
|
||||||
rb 8 ; BS_OEMName, ignored
|
|
||||||
dw ? ; BPB_BytsPerSec
|
|
||||||
BPB_SecsPerClus db ?
|
|
||||||
BPB_RsvdSecCnt dw ?
|
|
||||||
BPB_NumFATs db ?
|
|
||||||
BPB_RootEntCnt dw ?
|
|
||||||
dw ? ; BPB_TotSec16
|
|
||||||
db ? ; BPB_Media
|
|
||||||
dw ? ; BPB_FATSz16 = 0 for FAT32
|
|
||||||
BPB_SecPerTrk dw ?
|
|
||||||
BPB_NumHeads dw ?
|
|
||||||
BPB_HiddSec dd ?
|
|
||||||
dd ? ; BPB_TotSec32
|
|
||||||
BPB_FATSz32 dd ?
|
|
||||||
BPB_ExtFlags dw ?
|
|
||||||
dw ? ; BPB_FSVer
|
|
||||||
BPB_RootClus dd ?
|
|
||||||
filesize:
|
|
||||||
dw ? ; BPB_FSInfo
|
|
||||||
dw ? ; BPB_BkBootSec
|
|
||||||
rb 12 ; BPB_Reserved
|
|
||||||
BS_DrvNum db ?
|
|
||||||
db ? ; BS_Reserved1
|
|
||||||
db ? ; BS_BootSig
|
|
||||||
dd ? ; BS_VolID
|
|
||||||
; rb 11 ; BS_VolLab
|
|
||||||
; rb 5 ; BS_FilSysType, first 5 bytes
|
|
||||||
read_sectors32 dw ?
|
|
||||||
read_sectors2 dw ?
|
|
||||||
err_ dw ?
|
|
||||||
noloader dw ?
|
|
||||||
cachelimit dw ?
|
|
||||||
fatcachehead rw 2
|
|
||||||
fatcacheend dw ?
|
|
||||||
rb 3 ; BS_FilSysType, last 3 bytes
|
|
||||||
curseg dw ?
|
|
||||||
num_sectors dd ?
|
|
||||||
cur_cluster dd ?
|
|
||||||
next_cluster dd ?
|
|
||||||
flags dw ?
|
|
||||||
cur_delta dd ?
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
; procedures from boot sector
|
|
||||||
; LBA version
|
|
||||||
lba_read_sectors2 = 7CD6h
|
|
||||||
lba_err = 7CAAh
|
|
||||||
lba_noloader = 7CA7h ; = lba_err - 3
|
|
||||||
; CHS version
|
|
||||||
chs_read_sectors2 = 7CD2h
|
|
||||||
chs_err = 7CA6h
|
|
||||||
chs_noloader = 7CA3h ; = chs_err - 3
|
|
||||||
|
|
||||||
push eax cx ; save our position on disk
|
|
||||||
; determine version of bootsector (LBA vs CHS)
|
|
||||||
mov [read_sectors2], chs_read_sectors2
|
|
||||||
mov bx, chs_err
|
|
||||||
mov [err_], bx
|
|
||||||
; mov [noloader], chs_noloader
|
|
||||||
cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version
|
|
||||||
jz @f
|
|
||||||
add [read_sectors2], lba_read_sectors2 - chs_read_sectors2
|
|
||||||
add [err_], lba_err - chs_err
|
|
||||||
; mov [noloader], lba_noloader
|
|
||||||
@@:
|
|
||||||
xor bx, bx
|
|
||||||
; determine size of cache for folders
|
|
||||||
int 12h ; ax = size of available base memory in Kb
|
|
||||||
sub ax, 92000h / 1024
|
|
||||||
jae @f
|
|
||||||
nomem:
|
|
||||||
mov si, nomem_str
|
|
||||||
jmp [err_]
|
|
||||||
@@:
|
|
||||||
shr ax, 3
|
|
||||||
mov [cachelimit], ax ; size of cache - 1
|
|
||||||
mov es, bx
|
|
||||||
; no folders in cache yet
|
|
||||||
mov di, foldcache_clus
|
|
||||||
mov cx, 8*4/2 + 1
|
|
||||||
xor ax, ax
|
|
||||||
rep stosw
|
|
||||||
; bootsector code caches one FAT sector, [bp-14], in 6000:0000
|
|
||||||
; initialize our (more advanced) FAT caching from this
|
|
||||||
mov di, 8400h
|
|
||||||
mov cx, di
|
|
||||||
lea si, [fatcachehead]
|
|
||||||
mov [si], si ; no sectors in cache:
|
|
||||||
mov [si+2], si ; 'prev' & 'next' links point to self
|
|
||||||
mov [fatcacheend], di ; first free item = 8400h
|
|
||||||
stosw ; 'next cached sector' link
|
|
||||||
stosw ; 'prev cached sector' link
|
|
||||||
mov eax, [bp-14]
|
|
||||||
stosd ; first sector number in cache
|
|
||||||
test eax, eax
|
|
||||||
js @f
|
|
||||||
mov [si], cx ; 'first cached sector' link = 8400h
|
|
||||||
mov [si+2], cx ; 'next cached sector' link = 8400h
|
|
||||||
mov [fatcacheend], di ; first free item = 8406h
|
|
||||||
@@:
|
|
||||||
; if cluster = sector, we need to read second part of our file
|
|
||||||
; (bootsector loads only first cluster of kordldr.f32)
|
|
||||||
pop cx eax ; restore our position on disk
|
|
||||||
cmp cx, 1
|
|
||||||
ja kordldr_full
|
|
||||||
sub eax, [bp-10]
|
|
||||||
inc eax
|
|
||||||
inc eax ; eax = first cluster of kordldr.f32
|
|
||||||
call get_next_cluster
|
|
||||||
jc @f
|
|
||||||
; jmp [noloader]
|
|
||||||
mov ax, [err_]
|
|
||||||
sub ax, 3
|
|
||||||
jmp ax
|
|
||||||
@@:
|
|
||||||
dec eax
|
|
||||||
dec eax
|
|
||||||
push 0x800
|
|
||||||
pop es
|
|
||||||
call [read_sectors2]
|
|
||||||
kordldr_full:
|
|
||||||
; bootsector code has read some data of root directory to 8000:0000
|
|
||||||
; initialize our folder caching from this
|
|
||||||
mov eax, [BPB_RootClus]
|
|
||||||
mov [foldcache_clus], eax
|
|
||||||
mov cx, [curseg]
|
|
||||||
mov ax, 8000h
|
|
||||||
sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes)
|
|
||||||
shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes)
|
|
||||||
mov [foldcache_size], cx
|
|
||||||
shl cx, 4
|
|
||||||
push ds
|
|
||||||
mov ds, ax
|
|
||||||
push 0x9000
|
|
||||||
pop es
|
|
||||||
xor si, si
|
|
||||||
xor di, di
|
|
||||||
rep movsw
|
|
||||||
pop ds
|
|
||||||
; ...continue loading...
|
|
||||||
mov di, secondary_loader_info
|
|
||||||
call load_file
|
|
||||||
test bx, bx
|
|
||||||
mov bx, [err_]
|
|
||||||
jz @f
|
|
||||||
mov si, aKernelNotFound
|
|
||||||
jmp bx
|
|
||||||
@@:
|
|
||||||
; for subsequent calls to callback function, hook error handler
|
|
||||||
; push hooked_err / ret
|
|
||||||
mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24)
|
|
||||||
; set registers for secondary loader
|
|
||||||
mov ah, [bp-2] ; drive id
|
|
||||||
mov al, 'f'
|
|
||||||
btr ax, 15
|
|
||||||
jnc @f
|
|
||||||
mov al, 'h'
|
|
||||||
@@:
|
|
||||||
mov bx, '32'
|
|
||||||
mov si, callback
|
|
||||||
jmp far [si+secondary_loader_info-callback]
|
|
||||||
|
|
||||||
nomem_str db 'No memory',0
|
|
||||||
|
|
||||||
cluster2sector:
|
|
||||||
sub eax, 2
|
|
||||||
clustersz2sectorsz:
|
|
||||||
movzx ecx, [BPB_SecsPerClus]
|
|
||||||
mul ecx
|
|
||||||
ret
|
|
||||||
|
|
||||||
get_next_cluster:
|
|
||||||
; in: eax = cluster
|
|
||||||
; out: if there is next cluster: CF=1, eax = next cluster
|
|
||||||
; out: if there is no next cluster: CF=0
|
|
||||||
push di bx
|
|
||||||
push ds
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
push ax
|
|
||||||
shr eax, 7
|
|
||||||
; eax = FAT sector number; look in cache
|
|
||||||
mov di, 8400h
|
|
||||||
.cache_lookup:
|
|
||||||
cmp di, [fatcacheend]
|
|
||||||
jae .not_in_cache
|
|
||||||
scasd
|
|
||||||
scasd
|
|
||||||
jnz .cache_lookup
|
|
||||||
.in_cache:
|
|
||||||
sub di, 8
|
|
||||||
; delete this sector from the list
|
|
||||||
push si
|
|
||||||
mov si, [di]
|
|
||||||
mov bx, [di+2]
|
|
||||||
mov [si+2], bx
|
|
||||||
mov [bx], si
|
|
||||||
pop si
|
|
||||||
jmp @f
|
|
||||||
.not_in_cache:
|
|
||||||
; cache miss
|
|
||||||
; cache is full?
|
|
||||||
mov di, [fatcacheend]
|
|
||||||
cmp di, 8C00h
|
|
||||||
jnz .cache_not_full
|
|
||||||
; yes, delete the oldest entry
|
|
||||||
mov di, [fatcachehead]
|
|
||||||
mov bx, [di]
|
|
||||||
mov [fatcachehead], bx
|
|
||||||
push word [di+2]
|
|
||||||
pop word [bx+2]
|
|
||||||
jmp .cache_append
|
|
||||||
.cache_not_full:
|
|
||||||
; no, allocate new sector
|
|
||||||
add [fatcacheend], 8
|
|
||||||
.cache_append:
|
|
||||||
; read FAT
|
|
||||||
mov [di+4], eax
|
|
||||||
push es
|
|
||||||
pushad
|
|
||||||
lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] ; +0x10000 - for FASM
|
|
||||||
shl cx, 9-3
|
|
||||||
mov es, cx
|
|
||||||
xor bx, bx
|
|
||||||
mov cx, 1
|
|
||||||
add eax, [bp-6] ; FAT start
|
|
||||||
sub eax, [bp-10]
|
|
||||||
call [read_sectors2]
|
|
||||||
popad
|
|
||||||
pop es
|
|
||||||
@@:
|
|
||||||
; add new sector to the end of list
|
|
||||||
mov bx, di
|
|
||||||
xchg bx, [fatcachehead+2]
|
|
||||||
push word [bx]
|
|
||||||
pop word [di]
|
|
||||||
mov [bx], di
|
|
||||||
mov [di+2], bx
|
|
||||||
; get requested item
|
|
||||||
lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))]
|
|
||||||
pop di
|
|
||||||
and di, 0x7F
|
|
||||||
shl di, 2
|
|
||||||
shl ax, 9-3
|
|
||||||
mov ds, ax
|
|
||||||
and byte [di+3], 0x0F
|
|
||||||
mov eax, [di]
|
|
||||||
pop ds
|
|
||||||
pop bx di
|
|
||||||
;and eax, 0x0FFFFFFF
|
|
||||||
cmp eax, 0x0FFFFFF7
|
|
||||||
ret
|
|
||||||
|
|
||||||
if $ > 0x8000
|
|
||||||
error 'get_next_cluster must fit in first sector of kordldr.f32!'
|
|
||||||
end if
|
|
||||||
|
|
||||||
load_file:
|
|
||||||
; in: ss:bp = 0:7C00
|
|
||||||
; in: ds:di -> information structure
|
|
||||||
; dw:dw address
|
|
||||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
|
||||||
; ASCIIZ name
|
|
||||||
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found
|
|
||||||
; out: dx:ax = file size (0xFFFFFFFF if file not found)
|
|
||||||
mov eax, [BPB_RootClus] ; start from root directory
|
|
||||||
or dword [filesize], -1 ; initialize file size with invalid value
|
|
||||||
lea si, [di+6]
|
|
||||||
parse_dir_loop:
|
|
||||||
; convert name to FAT name
|
|
||||||
push di
|
|
||||||
push ax
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
; convert ASCIIZ filename to FAT name
|
|
||||||
filename equ bp
|
|
||||||
mov di, filename
|
|
||||||
push di
|
|
||||||
mov cx, 8+3
|
|
||||||
mov al, ' '
|
|
||||||
rep stosb
|
|
||||||
pop di
|
|
||||||
mov cl, 8 ; 8 symbols per name
|
|
||||||
mov bl, 1
|
|
||||||
nameloop:
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz namedone
|
|
||||||
cmp al, '/'
|
|
||||||
jz namedone
|
|
||||||
cmp al, '.'
|
|
||||||
jz namedot
|
|
||||||
dec cx
|
|
||||||
js badname
|
|
||||||
cmp al, 'a'
|
|
||||||
jb @f
|
|
||||||
cmp al, 'z'
|
|
||||||
ja @f
|
|
||||||
sub al, 'a'-'A'
|
|
||||||
@@:
|
|
||||||
stosb
|
|
||||||
jmp nameloop
|
|
||||||
namedot:
|
|
||||||
inc bx
|
|
||||||
jp badname
|
|
||||||
add di, cx
|
|
||||||
mov cl, 3
|
|
||||||
jmp nameloop
|
|
||||||
badname: ; do not make direct js/jp to notfound_pop:
|
|
||||||
; this generates long forms of conditional jumps and results in longer code
|
|
||||||
jmp notfound_pop
|
|
||||||
namedone:
|
|
||||||
; scan directory
|
|
||||||
pop ax ; eax = cluster of directory
|
|
||||||
; high word of eax is preserved by operations above
|
|
||||||
push ds
|
|
||||||
push si
|
|
||||||
; read a folder sector-by-sector and scan
|
|
||||||
; first, try to use the cache
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov di, foldcache_mark
|
|
||||||
xor bx, bx
|
|
||||||
mov cx, [cachelimit]
|
|
||||||
@@:
|
|
||||||
lea si, [di+bx]
|
|
||||||
mov edx, dword [foldcache_clus+si-foldcache_mark+bx]
|
|
||||||
cmp edx, eax
|
|
||||||
jz cacheok
|
|
||||||
test edx, edx
|
|
||||||
jz cacheadd ; the cache has place for new entry
|
|
||||||
inc bx
|
|
||||||
inc bx
|
|
||||||
dec cx
|
|
||||||
jns @b
|
|
||||||
; the folder is not present in the cache, so add it
|
|
||||||
; the cache is full; find the oldest entry and replace it with the new one
|
|
||||||
mov bx, -2
|
|
||||||
mov dx, [cachelimit]
|
|
||||||
@@:
|
|
||||||
inc bx
|
|
||||||
inc bx
|
|
||||||
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
|
|
||||||
jnz @b
|
|
||||||
lea si, [di+bx]
|
|
||||||
cacheadd:
|
|
||||||
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
|
|
||||||
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
|
|
||||||
mov dword [foldcache_clus+si-foldcache_mark+bx], eax
|
|
||||||
cacheok:
|
|
||||||
; update cache marks
|
|
||||||
mov dx, [di+bx]
|
|
||||||
mov cx, [foldcache_size+di-foldcache_mark+bx]
|
|
||||||
mov di, [cachelimit]
|
|
||||||
add di, di
|
|
||||||
cacheupdate:
|
|
||||||
cmp [foldcache_mark+di], dx
|
|
||||||
adc [foldcache_mark+di], 0
|
|
||||||
dec di
|
|
||||||
dec di
|
|
||||||
jns cacheupdate
|
|
||||||
and [foldcache_mark+bx], 0
|
|
||||||
; done, bx contains (position in cache)*2
|
|
||||||
;mov dx, bx
|
|
||||||
;shl dx, 8 ; dx = (position in cache)*0x2000/0x10
|
|
||||||
;add dx, 0x9000
|
|
||||||
lea dx, [bx + 0x90]
|
|
||||||
xchg dl, dh
|
|
||||||
mov ds, dx
|
|
||||||
mov si, filename ; ss:si -> filename in FAT style
|
|
||||||
call scan_for_filename
|
|
||||||
jz lookup_done
|
|
||||||
; cache miss, read folder data from disk
|
|
||||||
mov bx, cx
|
|
||||||
shr bx, 4
|
|
||||||
shl cx, 5
|
|
||||||
mov di, cx ; es:di -> free space in cache entry
|
|
||||||
; external loop: scan clusters
|
|
||||||
folder_next_cluster:
|
|
||||||
; internal loop: scan sectors in cluster
|
|
||||||
push eax
|
|
||||||
call cluster2sector
|
|
||||||
folder_next_sector:
|
|
||||||
; skip first bx sectors
|
|
||||||
dec bx
|
|
||||||
jns folder_skip_sector
|
|
||||||
push cx
|
|
||||||
push es di
|
|
||||||
push 0x8000
|
|
||||||
pop es
|
|
||||||
xor bx, bx
|
|
||||||
mov cx, 1
|
|
||||||
push es
|
|
||||||
push eax
|
|
||||||
call [read_sectors2]
|
|
||||||
pop eax
|
|
||||||
; copy data to the cache...
|
|
||||||
pop ds
|
|
||||||
pop di es
|
|
||||||
cmp di, 0x2000 ; ...if there is free space, of course
|
|
||||||
jae @f
|
|
||||||
pusha
|
|
||||||
mov cx, 0x100
|
|
||||||
xor si, si
|
|
||||||
rep movsw
|
|
||||||
mov di, es
|
|
||||||
shr di, 8
|
|
||||||
add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache
|
|
||||||
popa
|
|
||||||
@@:
|
|
||||||
push es
|
|
||||||
mov cl, 0x10 ; ch=0 at this point
|
|
||||||
call scan_for_filename
|
|
||||||
pop es
|
|
||||||
pop cx
|
|
||||||
jz lookup_done_pop
|
|
||||||
folder_skip_sector:
|
|
||||||
inc eax
|
|
||||||
loop folder_next_sector
|
|
||||||
pop eax ; eax = current cluster
|
|
||||||
call get_next_cluster
|
|
||||||
jc folder_next_cluster
|
|
||||||
stc
|
|
||||||
push eax
|
|
||||||
lookup_done_pop:
|
|
||||||
pop eax
|
|
||||||
lookup_done:
|
|
||||||
pop si
|
|
||||||
; CF=1 <=> failed
|
|
||||||
jnc found
|
|
||||||
pop ds
|
|
||||||
notfound:
|
|
||||||
pop di
|
|
||||||
notfound2:
|
|
||||||
mov bx, 2 ; file not found
|
|
||||||
mov ax, 0xFFFF
|
|
||||||
mov dx, ax ; invalid file size
|
|
||||||
ret
|
|
||||||
notfound_pop:
|
|
||||||
pop ax
|
|
||||||
jmp notfound
|
|
||||||
found:
|
|
||||||
mov eax, [di+20-2]
|
|
||||||
mov edx, [di+28]
|
|
||||||
mov ax, [di+26] ; get cluster
|
|
||||||
test byte [di+11], 10h ; directory?
|
|
||||||
pop ds
|
|
||||||
pop di
|
|
||||||
jz regular_file
|
|
||||||
cmp byte [si-1], 0
|
|
||||||
jz notfound2 ; don't read directories as regular files
|
|
||||||
; ok, we have found a directory and the caller requested a file into it
|
|
||||||
jmp parse_dir_loop ; restart with new cluster in ax
|
|
||||||
regular_file:
|
|
||||||
cmp byte [si-1], 0
|
|
||||||
jnz notfound2 ; file does not contain another files
|
|
||||||
; ok, we have found a regular file and the caller requested it
|
|
||||||
; save file size
|
|
||||||
mov [filesize], edx
|
|
||||||
mov si, [di+4] ; [ds:di+4] = limit in 4K blocks
|
|
||||||
shl si, 3
|
|
||||||
push si
|
|
||||||
les bx, [di] ; es:bx -> buffer
|
|
||||||
clusloop:
|
|
||||||
; eax = first cluster, top of stack contains limit in sectors
|
|
||||||
mov esi, eax ; remember current cluster
|
|
||||||
xor ecx, ecx ; ecx will contain number of consecutive clusters
|
|
||||||
mov [cur_delta], ecx
|
|
||||||
mov edi, eax
|
|
||||||
clusfind:
|
|
||||||
inc edi
|
|
||||||
inc ecx
|
|
||||||
call get_next_cluster
|
|
||||||
jnc clusread
|
|
||||||
cmp eax, edi
|
|
||||||
jz clusfind
|
|
||||||
stc
|
|
||||||
clusread:
|
|
||||||
pop di ; limit in sectors
|
|
||||||
movzx edi, di
|
|
||||||
push eax ; save next cluster
|
|
||||||
pushf ; save flags
|
|
||||||
; read cx clusters, starting from si
|
|
||||||
; calculate number of sectors
|
|
||||||
xchg eax, ecx
|
|
||||||
call clustersz2sectorsz
|
|
||||||
mov [num_sectors], eax
|
|
||||||
jmp @f
|
|
||||||
continue_load_file:
|
|
||||||
les bx, [di] ; es:bx -> buffer
|
|
||||||
movzx edi, word [di+4] ; di = limit in 4K blocks
|
|
||||||
shl di, 3 ; now di = limit in sectors
|
|
||||||
mov eax, [num_sectors]
|
|
||||||
mov esi, [cur_cluster]
|
|
||||||
push [next_cluster]
|
|
||||||
push [flags]
|
|
||||||
test eax, eax
|
|
||||||
jz nextclus
|
|
||||||
@@:
|
|
||||||
; eax = number of sectors; compare with limit
|
|
||||||
cmp eax, edi
|
|
||||||
seta dl
|
|
||||||
push dx ; limit was exceeded?
|
|
||||||
jbe @f
|
|
||||||
mov eax, edi
|
|
||||||
@@:
|
|
||||||
sub di, ax ; calculate new limit
|
|
||||||
sub [num_sectors], eax
|
|
||||||
mov [cur_cluster], esi
|
|
||||||
; calculate starting sector
|
|
||||||
push ax
|
|
||||||
xchg eax, esi
|
|
||||||
call cluster2sector
|
|
||||||
pop cx
|
|
||||||
add eax, [cur_delta]
|
|
||||||
add [cur_delta], ecx
|
|
||||||
; read
|
|
||||||
call [read_sectors2]
|
|
||||||
pop dx
|
|
||||||
; next cluster?
|
|
||||||
nextclus:
|
|
||||||
popf
|
|
||||||
pop eax
|
|
||||||
mov [next_cluster], eax
|
|
||||||
pushf
|
|
||||||
pop [flags]
|
|
||||||
jnc @f ; no next cluster => return
|
|
||||||
mov dl, 1 ; dh=0 in any case
|
|
||||||
test di, di
|
|
||||||
jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded
|
|
||||||
push di
|
|
||||||
jmp clusloop ; all is ok, continue
|
|
||||||
hooked_err:
|
|
||||||
mov sp, 7C00h-14-2 ; restore stack
|
|
||||||
mov dx, 3 ; return: read error
|
|
||||||
@@:
|
|
||||||
mov bx, dx
|
|
||||||
mov ax, [filesize]
|
|
||||||
mov dx, [filesize+2]
|
|
||||||
ret
|
|
||||||
|
|
||||||
scan_for_filename:
|
|
||||||
; in: ss:si -> 11-bytes FAT name
|
|
||||||
; in: ds:0 -> part of directory data
|
|
||||||
; in: cx = number of entries
|
|
||||||
; in: bh = 0
|
|
||||||
; out: if found: CF=0, ZF=1, es:di -> directory entry
|
|
||||||
; out: if not found, but continue required: CF=1 and ZF=0
|
|
||||||
; out: if not found and zero item reached: CF=1 and ZF=1
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
xor di, di
|
|
||||||
push cx
|
|
||||||
jcxz snoent
|
|
||||||
sloop:
|
|
||||||
cmp byte [di], bh
|
|
||||||
jz snotfound
|
|
||||||
test byte [di+11], 8 ; volume label?
|
|
||||||
jnz scont ; ignore volume labels
|
|
||||||
pusha
|
|
||||||
mov cx, 11
|
|
||||||
repz cmps byte [ss:si], byte [es:di]
|
|
||||||
popa
|
|
||||||
jz sdone
|
|
||||||
scont:
|
|
||||||
add di, 0x20
|
|
||||||
loop sloop
|
|
||||||
snoent:
|
|
||||||
inc cx ; clear ZF flag
|
|
||||||
snotfound:
|
|
||||||
stc
|
|
||||||
sdone:
|
|
||||||
pop cx
|
|
||||||
lrdret:
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Callback function for secondary loader
|
|
||||||
callback:
|
|
||||||
; in: ax = function number; only functions 1 and 2 are defined for now
|
|
||||||
; save caller's stack
|
|
||||||
mov dx, ss
|
|
||||||
mov cx, sp
|
|
||||||
; set our stack (required because we need ss=0)
|
|
||||||
xor si, si
|
|
||||||
mov ss, si
|
|
||||||
mov sp, 7C00h-10
|
|
||||||
mov bp, 7C00h
|
|
||||||
push dx
|
|
||||||
push cx
|
|
||||||
; call our function
|
|
||||||
stc ; unsupported function
|
|
||||||
dec ax
|
|
||||||
jz callback_readfile
|
|
||||||
dec ax
|
|
||||||
jnz callback_ret
|
|
||||||
; function 2: continue loading file
|
|
||||||
; can be called only after function 1 returned value bx=1 (only part of file was loaded)
|
|
||||||
; in: ds:di -> information structure
|
|
||||||
; dw:dw address
|
|
||||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
|
||||||
; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error
|
|
||||||
; out: dx:ax = file size
|
|
||||||
call continue_load_file
|
|
||||||
jmp callback_ret_succ
|
|
||||||
callback_readfile:
|
|
||||||
; function 1: read file
|
|
||||||
; in: ds:di -> information structure
|
|
||||||
; dw:dw address
|
|
||||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
|
||||||
; ASCIIZ name
|
|
||||||
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
|
|
||||||
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
|
|
||||||
call load_file
|
|
||||||
callback_ret_succ:
|
|
||||||
clc ; function is supported
|
|
||||||
callback_ret:
|
|
||||||
; restore caller's stack
|
|
||||||
pop cx
|
|
||||||
pop ss
|
|
||||||
mov sp, cx
|
|
||||||
; return to caller
|
|
||||||
retf
|
|
||||||
|
|
||||||
secondary_loader_info:
|
|
||||||
dw 0, 0x1000
|
|
||||||
dw 0x30000 / 0x1000
|
|
||||||
db 'kord/loader',0
|
|
||||||
aKernelNotFound db 'Fatal error: cannot load the secondary loader',0
|
|
||||||
|
|
||||||
;if $ > 0x8200
|
|
||||||
;error 'total size of kordldr.f32 must not exceed 1024 bytes!'
|
|
||||||
;end if
|
|
||||||
|
|
||||||
;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache
|
|
||||||
;foldcache_mark dw 0
|
|
||||||
; rw 7
|
|
||||||
;foldcache_size rw 8
|
|
||||||
foldcache_clus rd 8
|
|
||||||
foldcache_mark rw 8
|
|
||||||
foldcache_size rw 8
|
|
@ -1,49 +0,0 @@
|
|||||||
include "mkfloppy.inc"
|
|
||||||
;// insert boot sect
|
|
||||||
file "fat1x/bootsect.bin", 512
|
|
||||||
|
|
||||||
; fat1
|
|
||||||
db 0F0h, 0FFh, 0FFh, 9*512-3 dup 0
|
|
||||||
; fat2
|
|
||||||
db 0F0h, 0FFh, 0FFh, 9*512-3 dup 0
|
|
||||||
|
|
||||||
; root
|
|
||||||
dent kordldr, "KORDLDR F1X", FA_ARC
|
|
||||||
dent kord, "KORD ",FA_DIR
|
|
||||||
dent kolibri, "KOLIBRI ",FA_DIR
|
|
||||||
; ...
|
|
||||||
|
|
||||||
rb 33*512-$
|
|
||||||
;///////////////////////////
|
|
||||||
defdir kord
|
|
||||||
{
|
|
||||||
dent loader, "LOADER ", FA_ARC
|
|
||||||
dent ini,"STARTOS INI", FA_ARC
|
|
||||||
}
|
|
||||||
|
|
||||||
defdir kolibri
|
|
||||||
{
|
|
||||||
dent kolibri_ldm, "KOLIBRI LDM", FA_ARC
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
; data
|
|
||||||
stof kordldr, "fat1x/kordldr.f1x"
|
|
||||||
stod kord,root
|
|
||||||
|
|
||||||
stof loader, "../loader"
|
|
||||||
stof ini,"../startos.ini"
|
|
||||||
|
|
||||||
store dword ini_base/512+1 at ini_base+1F8h
|
|
||||||
store word (ini_size+511)/512-1 at ini_base+1FCh
|
|
||||||
store word 220h at ini_base+1FEh
|
|
||||||
|
|
||||||
stod kolibri,root
|
|
||||||
stof kolibri_ldm, "../kolibri_ldm/bin/kolibri.ldm"
|
|
||||||
store dword kolibri_ldm_base/512+1 at kolibri_ldm_base+1F8h
|
|
||||||
store word (kolibri_ldm_size+511)/512-1 at kolibri_ldm_base+1FCh
|
|
||||||
store word 220h at kolibri_ldm_base+1FEh
|
|
||||||
|
|
||||||
|
|
||||||
; ...
|
|
||||||
rb 2*80*18*512-$
|
|
@ -1,90 +0,0 @@
|
|||||||
; ---------------------------------------------------------------------------
|
|
||||||
; mkfloppy.inc
|
|
||||||
; ---------------------------------------------------------------------------
|
|
||||||
; Created by Phantom-84
|
|
||||||
; ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
FA_RO equ 01h
|
|
||||||
FA_HID equ 02h
|
|
||||||
FA_SYS equ 04h
|
|
||||||
FA_VOL equ 08h
|
|
||||||
FA_DIR equ 10h
|
|
||||||
FA_ARC equ 20h
|
|
||||||
|
|
||||||
DSTAMP equ 28C1h
|
|
||||||
TSTAMP equ 6000h
|
|
||||||
|
|
||||||
root_size=0
|
|
||||||
|
|
||||||
macro reset id
|
|
||||||
{
|
|
||||||
local count, cur, disp, val, var
|
|
||||||
times 511-($+511) mod 512 db 0
|
|
||||||
if id#_size>0
|
|
||||||
count=(id#_size+511)/512
|
|
||||||
cur=id#_base/512-(33-2)
|
|
||||||
repeat count
|
|
||||||
if %=count
|
|
||||||
val=0FFFh
|
|
||||||
else
|
|
||||||
val=cur+1
|
|
||||||
end if
|
|
||||||
if cur and 1
|
|
||||||
val=val shl 4
|
|
||||||
end if
|
|
||||||
disp=(cur*3)/2
|
|
||||||
load var word from 512+disp
|
|
||||||
var=var or val
|
|
||||||
store word var at 512+disp
|
|
||||||
store word var at 10*512+disp
|
|
||||||
cur=cur+1
|
|
||||||
end repeat
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro dent id, name, attr
|
|
||||||
{
|
|
||||||
@@ db name
|
|
||||||
times @b+11-$ db 32
|
|
||||||
db attr
|
|
||||||
dw 0, TSTAMP, DSTAMP, DSTAMP, 0, TSTAMP, DSTAMP
|
|
||||||
if id#_size=0
|
|
||||||
dw 0
|
|
||||||
else
|
|
||||||
dw id#_base/512-(33-2)
|
|
||||||
end if
|
|
||||||
if (attr) and FA_DIR
|
|
||||||
dd 0
|
|
||||||
else
|
|
||||||
dd id#_size
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro orgdir id, parentid
|
|
||||||
{
|
|
||||||
id#_base:
|
|
||||||
dent id, ".", FA_DIR
|
|
||||||
dent parentid, "..", FA_DIR
|
|
||||||
}
|
|
||||||
|
|
||||||
macro findir id
|
|
||||||
{
|
|
||||||
id#_size=$-id#_base
|
|
||||||
reset id
|
|
||||||
}
|
|
||||||
|
|
||||||
macro stod id, parentid
|
|
||||||
{
|
|
||||||
orgdir id, parentid
|
|
||||||
id
|
|
||||||
findir id
|
|
||||||
}
|
|
||||||
|
|
||||||
macro stof id, name
|
|
||||||
{
|
|
||||||
id#_base: file name
|
|
||||||
id#_size=$-id#_base
|
|
||||||
reset id
|
|
||||||
}
|
|
||||||
|
|
||||||
defdir fix macro
|
|
@ -1,68 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
;======================================================================
|
|
||||||
;
|
|
||||||
; BOOT DATA
|
|
||||||
;
|
|
||||||
;======================================================================
|
|
||||||
|
|
||||||
|
|
||||||
version db 'Secondary Loader v 0.010',0
|
|
||||||
version_end:
|
|
||||||
|
|
||||||
select_section db 'Select section:'
|
|
||||||
select_section_end:
|
|
||||||
section_description db 'Section description:'
|
|
||||||
section_description_end:
|
|
||||||
soft_mes db 'Soft (c) 2008-2009'
|
|
||||||
soft_mes_end:
|
|
||||||
|
|
||||||
badprocessor db '>Fatal - CPU 586+ required.',0
|
|
||||||
error_ini_f1 db '>Error: cannot load ini file, buffer is full',0
|
|
||||||
error_ini_f2 db '>Error: ini file not found',0
|
|
||||||
error_ini_f3 db '>Error: cannot read ini file',0
|
|
||||||
error_ini_nf db '>Error: unrecognized error when loading ini file',0
|
|
||||||
not_found_sec_loader db '>Not found section [loader]',0
|
|
||||||
not_found_def_sect db '>Not found value default in section [loader]',0
|
|
||||||
default_eq_loader db '>Error in section [loader] parametr default=loader',0
|
|
||||||
found_equal_default db '>Found equal parametr default will be use first value',0
|
|
||||||
found_equal_timeout db '>Found equal parametr timeout will be use first value',0
|
|
||||||
set_default_timeout_val db '>Section timeout has incorrect value, will be use default value',0
|
|
||||||
error_ini_common db ">I will use predefined settings and try to boot. Let's hope for the best..."
|
|
||||||
db 13,10,"Press any key to continue...",0
|
|
||||||
load_ini db '>Ini file loaded successfully',0
|
|
||||||
parse_ini_end db '>End parsing ini file',0
|
|
||||||
point_to_default_sec_not_found db '>Point to default section is not found in ini file',0
|
|
||||||
incorect_section_define db ">Incorect section define not found ']'",0
|
|
||||||
default_section_name db '"Section unname"'
|
|
||||||
|
|
||||||
start_msg db "Press any key to change default section, press [Enter] to continue booting"
|
|
||||||
start_msg_e:
|
|
||||||
time_msg db "or wait 4 seconds before default continuation"
|
|
||||||
time_msg_e:
|
|
||||||
time_str db "seconds before default continuation"
|
|
||||||
time_str_e:
|
|
@ -1,4 +0,0 @@
|
|||||||
@fasm -m 65535 loader.asm loader
|
|
||||||
@echo off
|
|
||||||
REM @fasm -m 65535 loader.asm loader > loader.lst
|
|
||||||
REM @pause
|
|
@ -1,77 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
;Òóò îïðåäåëåíû âñå ñîîáùåíèÿ, êîòîðûå íóæíû â ïðîöåññå îòëàäêè, è ñîâñåì íå íóæíû â ðàáî÷åé êîïèè ïðîãðàììû.
|
|
||||||
If DEBUG
|
|
||||||
cseg_msg db ' - Adress of code segment',0
|
|
||||||
stack_msg db 'Set stack & segments is have completed',0
|
|
||||||
show_string db 'Have loaded size:'
|
|
||||||
show_decode db ' ',0
|
|
||||||
show_db1 db ' -Message debug1',0
|
|
||||||
show_db2 db ' -Message debug2',0
|
|
||||||
|
|
||||||
|
|
||||||
lm_l_found db '[loader] is found',0
|
|
||||||
lm_lf_timeout db 'timeout is found',0
|
|
||||||
lm_lf_default db 'name default is found and end parsing section',0
|
|
||||||
lm_lf_section db 'found section [',0
|
|
||||||
lm_lf_default_f db 'found default parametr',0
|
|
||||||
lm_l_end db 'section [loader] is end',0
|
|
||||||
show_all_sect db 'SHOW ALL Sections',0
|
|
||||||
no_show_only_w db 'Not show sections - only work on default sect',0
|
|
||||||
_not_found db '[ not found',0
|
|
||||||
_found_1 db '[] found',0
|
|
||||||
_found_2 db '[ found',0
|
|
||||||
say_hello db 'Hello $)',0
|
|
||||||
ramdiskFS_st db 'Start use_RamdiskFS macros',0
|
|
||||||
free_memory_msg db ' -Kb availability system free memory',0
|
|
||||||
RamdiskSize_msg db ' -Kb equal RamdiskSize',0
|
|
||||||
RamdiskSector_msg db ' -byts RamdiskSector',0
|
|
||||||
RamdiskCluster_msg db ' -RamdiskCluster',0
|
|
||||||
RamdiskFile_msg db ' -size RamdiskFile',0
|
|
||||||
fat_create_msg db ' -first create fat table, point to next block',0
|
|
||||||
BPB_msg db ' -in byte, why we get data from move BPB struct',0
|
|
||||||
firstDataSect_msg db ' -first data sector, offset to data in sectors',0
|
|
||||||
size_root_dir_msg db ' -size root dir in sectrors',0
|
|
||||||
DataClasters_msg db ' -size data in Clasters',0
|
|
||||||
first_entry_in_fat db ' -data segment in FIRST entry FAT',0
|
|
||||||
check_root_fat_ db ' : --------------',0
|
|
||||||
check_name_fat_msg_y db 'Name is present that is BAD',0
|
|
||||||
check_name_fat_msg_n db 'Name is not present that is GOOD',0
|
|
||||||
name_of_seg_get_64 db ' -name of seg where we get 64 Kb of data',0
|
|
||||||
convertion_file_name_msg_y db '->Destination name of file is GOOD',0
|
|
||||||
convertion_file_name_msg_n db '->Destination name of file is BAD',0
|
|
||||||
alarm_msg db '%%%%%%%% WARNING: MISS THE FILE %%%%%%%%%%%',0
|
|
||||||
start_making_FAT12_msg db '>>>>>> Begin make a RAMDISK and FS after 1 Mb <<<<<<<',0
|
|
||||||
make_fat12_RFS_msg db '-Make FAT12 Ram FS',0
|
|
||||||
get_type_FS_msg db '-End make RamDisk',0
|
|
||||||
seg_where_get_data db ' - Segment where we get data for move up file',0
|
|
||||||
return_code_af_move db ' -return code after 0x87 int 0x15, move block',0
|
|
||||||
return_code_af_fat_m db ' -return code after 0x87 int 0x15, move fat struc',0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end if
|
|
Binary file not shown.
@ -1,98 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;; booteng.asm the module for Secondary Loader ;;
|
|
||||||
;; ;;
|
|
||||||
;; KolibriOS 16-bit loader module, ;;
|
|
||||||
;; based on bootcode for KolibriOS ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;======================================================================
|
|
||||||
;
|
|
||||||
; BOOT DATA
|
|
||||||
;
|
|
||||||
;======================================================================
|
|
||||||
|
|
||||||
d80x25_bottom:
|
|
||||||
db 186,' KolibriOS is based on MenuetOS and comes with ABSOLUTELY '
|
|
||||||
db 'NO WARRANTY ',186
|
|
||||||
db 186,' See file COPYING for details '
|
|
||||||
db ' ',186
|
|
||||||
line_full_bottom
|
|
||||||
d80x25_bottom_num = 3
|
|
||||||
|
|
||||||
msg_apm db " APM x.x ", 0
|
|
||||||
vervesa db "Version of Vesa: Vesa x.x",13,10,0
|
|
||||||
novesa db "Display: EGA/CGA",13,10,0
|
|
||||||
s_vesa db "Version of VESA: "
|
|
||||||
.ver db "?.?",13,10,0
|
|
||||||
|
|
||||||
gr_mode db "Select a videomode: ",13,10,0
|
|
||||||
|
|
||||||
vrrmprint db "Apply VRR? (picture frequency greater than 60Hz"
|
|
||||||
db " only for transfers:",13,10
|
|
||||||
db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0
|
|
||||||
|
|
||||||
|
|
||||||
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
|
|
||||||
|
|
||||||
bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "3-use preloaded ram-image from kernel restart;"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "4-create blank image]: ",0
|
|
||||||
probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, "
|
|
||||||
db "2-probe bios (Vesa 3.0)]: ",0
|
|
||||||
prnotfnd db "Fatal - Videomode not found.",0
|
|
||||||
not386 db "Fatal - CPU 386+ required.",0
|
|
||||||
btns db "Fatal - Can't determine color depth.",0
|
|
||||||
fatalsel db "Fatal - Graphics mode not supported by hardware.",0
|
|
||||||
pres_key db "Press any key to choose a new videomode.",0
|
|
||||||
badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0
|
|
||||||
memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0
|
|
||||||
okt db " ... OK"
|
|
||||||
linef db 13,10,0
|
|
||||||
diskload db "Loading diskette: 00 %",8,8,8,8,0
|
|
||||||
pros db "00"
|
|
||||||
backspace2 db 8,8,0
|
|
||||||
boot_dev db 0 ; 0=floppy, 1=hd
|
|
||||||
start_msg db "Press [abc] to change settings, press [Enter] to continue booting",13,10,0
|
|
||||||
time_msg db " or wait "
|
|
||||||
time_str db " 5 seconds"
|
|
||||||
db " before automatical continuation",13,10,0
|
|
||||||
current_cfg_msg db "Current settings:",13,10,0
|
|
||||||
curvideo_msg db " [a] Videomode: ",0
|
|
||||||
|
|
||||||
mode0 db "320x200, EGA/CGA 256 colors",13,10,0
|
|
||||||
mode9 db "640x480, VGA 16 colors",13,10,0
|
|
||||||
|
|
||||||
usebd_msg db " [b] Add disks visible by BIOS:",0
|
|
||||||
on_msg db " on",13,10,0
|
|
||||||
off_msg db " off",13,10,0
|
|
||||||
;readonly_msg db " only for reading",13,10,0
|
|
||||||
vrrm_msg db " [c] Use VRR:",0
|
|
||||||
preboot_device_msg db " [d] Floppy image: ",0
|
|
||||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
|
|
||||||
pdm1 db "real floppy",13,10,0
|
|
||||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
|
||||||
pdm3 db "use already loaded image",13,10,0
|
|
||||||
pdm4 db "create blank image",13,10,0
|
|
||||||
loading_msg db "Loading KolibriOS...",0
|
|
||||||
save_quest db "Remember current settings? [y/n]: ",0
|
|
||||||
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0
|
|
||||||
|
|
||||||
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0
|
|
||||||
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0
|
|
||||||
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0
|
|
||||||
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0
|
|
||||||
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0
|
|
||||||
|
|
||||||
remark1 db "Default values were selected to match most of configurations, but not all.",0
|
|
||||||
remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0
|
|
||||||
remark3 db "If the system does not boot, try to disable the item [b].",0
|
|
||||||
remarks dw remark1, remark2, remark3
|
|
||||||
num_remarks = 3
|
|
@ -1,119 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;; kolibri_ldm.asm the module for Secondary Loader ;;
|
|
||||||
;; ;;
|
|
||||||
;; KolibriOS 16-bit loader module, ;;
|
|
||||||
;; based on bootcode for KolibriOS ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;======================================================================
|
|
||||||
;
|
|
||||||
; BOOT DATA
|
|
||||||
;
|
|
||||||
;======================================================================
|
|
||||||
|
|
||||||
|
|
||||||
d80x25_bottom:
|
|
||||||
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
|
|
||||||
db 'NO WARRANTY ',186
|
|
||||||
db 186,' See file COPYING for details '
|
|
||||||
db ' ',186
|
|
||||||
line_full_bottom
|
|
||||||
d80x25_bottom_num = 3
|
|
||||||
|
|
||||||
novesa db "Ekraan: EGA/CGA",13,10,0
|
|
||||||
vervesa db "Vesa versioon: Vesa x.x",13,10,0
|
|
||||||
vervesa_off=20
|
|
||||||
msg_apm db " APM x.x ", 0
|
|
||||||
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
|
|
||||||
db "[3] 1024x768, [4] 1280x1024",13,10
|
|
||||||
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
|
|
||||||
db "[7] 1024x768, [8] 1280x1024",13,10
|
|
||||||
db 186," EGA/CGA 256 värvi: [9] 320x200, "
|
|
||||||
db "VGA 16 värvi: [0] 640x480",13,10
|
|
||||||
db 186," Vali reziim: ",0
|
|
||||||
bt24 db "Bitti pikseli kohta: 24",13,10,0
|
|
||||||
bt32 db "Bitti pikseli kohta: 32",13,10,0
|
|
||||||
vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz"
|
|
||||||
db " ainult:",13,10
|
|
||||||
db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0
|
|
||||||
;askmouse db " Hiir:"
|
|
||||||
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
|
|
||||||
; db " Vali port [1-3]: ",0
|
|
||||||
;no_com1 db 13,10,186, " No COM1 mouse",0
|
|
||||||
;no_com2 db 13,10,186, " No COM2 mouse",0
|
|
||||||
;ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-no]: ",0
|
|
||||||
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
|
|
||||||
;gr_direct db 186," Use direct LFB writing? "
|
|
||||||
; db "[1-yes/2-no] ? ",0
|
|
||||||
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / "
|
|
||||||
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
|
|
||||||
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
|
|
||||||
bdev db "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "3-kasuta eellaaditud mäluketast kerneli restardist;"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "4-loo tühi pilt]: ",0
|
|
||||||
probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, "
|
|
||||||
db "2-leia biosist (Vesa 3.0)]: ",0
|
|
||||||
;memokz256 db 13,10,186," RAM 256 Mb",0
|
|
||||||
;memokz128 db 13,10,186," RAM 128 Mb",0
|
|
||||||
;memokz64 db 13,10,186," RAM 64 Mb",0
|
|
||||||
;memokz32 db 13,10,186," RAM 32 Mb",0
|
|
||||||
;memokz16 db 13,10,186," RAM 16 Mb",0
|
|
||||||
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0
|
|
||||||
;modena db "Fataalne - VBE 0x112+ on vajalik.",0
|
|
||||||
not386 db "Fataalne - CPU 386+ on vajalik.",0
|
|
||||||
btns db "Fataalne - Ei suuda värvisügavust määratleda.",0
|
|
||||||
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0
|
|
||||||
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0
|
|
||||||
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
|
|
||||||
okt db " ... OK"
|
|
||||||
linef db 13,10,0
|
|
||||||
diskload db "Loen disketti: 00 %",8,8,8,8,0
|
|
||||||
pros db "00"
|
|
||||||
backspace2 db 8,8,0
|
|
||||||
boot_dev db 0 ; 0=floppy, 1=hd
|
|
||||||
start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
|
|
||||||
time_msg db " või oota "
|
|
||||||
time_str db " 5 sekundit"
|
|
||||||
db " automaatseks jätkamiseks",13,10,0
|
|
||||||
current_cfg_msg db "Praegused seaded:",13,10,0
|
|
||||||
curvideo_msg db " [a] Videoreziim: ",0
|
|
||||||
mode1 db "640x480",0
|
|
||||||
mode2 db "800x600",0
|
|
||||||
mode3 db "1024x768",0
|
|
||||||
mode4 db "1280x1024",0
|
|
||||||
modes_msg dw mode4,mode1,mode2,mode3
|
|
||||||
modevesa20 db " koos LFB",0
|
|
||||||
modevesa12 db ", VESA 1.2 Bnk",0
|
|
||||||
mode9 db "320x200, EGA/CGA 256 värvi",0
|
|
||||||
mode10 db "640x480, VGA 16 värvi",0
|
|
||||||
probeno_msg db " (standard reziim)",0
|
|
||||||
probeok_msg db " (kontrolli ebastandardseid reziime)",0
|
|
||||||
;dma_msg db " [b] Kasuta DMA'd HDD juurdepääsuks:",0
|
|
||||||
usebd_msg db " [b] Add disks visible by BIOS:",0
|
|
||||||
on_msg db " sees",13,10,0
|
|
||||||
off_msg db " väljas",13,10,0
|
|
||||||
;readonly_msg db " ainult lugemiseks",13,10,0
|
|
||||||
vrrm_msg db " [c] Kasuta VRR:",0
|
|
||||||
preboot_device_msg db " [d] Disketi kujutis: ",0
|
|
||||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
|
|
||||||
pdm1 db "reaalne diskett",13,10,0
|
|
||||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
|
||||||
pdm3 db "kasuta juba laaditud kujutist",13,10,0
|
|
||||||
pdm4 db "loo tühi pilt",13,10,0
|
|
||||||
loading_msg db "Laadin KolibriOS...",0
|
|
||||||
save_quest db "Jäta meelde praegused seaded? [y/n]: ",0
|
|
||||||
loader_block_error db "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0
|
|
||||||
|
|
||||||
remark1 db "Default values were selected to match most of configurations, but not all.",0
|
|
||||||
remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0
|
|
||||||
remark3 db "If the system does not boot, try to disable the item [b].",0
|
|
||||||
remarks dw remark1, remark2, remark3
|
|
||||||
num_remarks = 3
|
|
@ -1,118 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;======================================================================
|
|
||||||
;
|
|
||||||
; BOOT DATA
|
|
||||||
;
|
|
||||||
;======================================================================
|
|
||||||
|
|
||||||
|
|
||||||
d80x25_bottom:
|
|
||||||
; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
|
|
||||||
; db 'NO WARRANTY ',186
|
|
||||||
; db 186,' See file COPYING for details '
|
|
||||||
; db ' ',186
|
|
||||||
|
|
||||||
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche '
|
|
||||||
db ' Garantie vertrieben ',186
|
|
||||||
db 186,' Details stehen in der Datei COPYING '
|
|
||||||
db ' ',186
|
|
||||||
line_full_bottom
|
|
||||||
d80x25_bottom_num = 3
|
|
||||||
|
|
||||||
novesa db "Anzeige: EGA/CGA ",13,10,0
|
|
||||||
vervesa db "Vesa-Version: Vesa ",13,10,0
|
|
||||||
vervesa_off=22
|
|
||||||
msg_apm db " APM x.x ", 0
|
|
||||||
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
|
|
||||||
db "[3] 1024x768, [4] 1280x1024",13,10
|
|
||||||
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
|
|
||||||
db "[7] 1024x768, [8] 1280x1024",13,10
|
|
||||||
db 186," EGA/CGA 256 Farben: [9] 320x200, "
|
|
||||||
db "VGA 16 Farben: [0] 640x480",13,10
|
|
||||||
db 186," Waehle Modus: ",0
|
|
||||||
bt24 db "Bits Per Pixel: 24",13,10,0
|
|
||||||
bt32 db "Bits Per Pixel: 32",13,10,0
|
|
||||||
vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz"
|
|
||||||
db " only for transfers:",13,10
|
|
||||||
db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0
|
|
||||||
;askmouse db " Maus angeschlossen an:"
|
|
||||||
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
|
|
||||||
; db " Waehle Port [1-3]: ",0
|
|
||||||
;no_com1 db 13,10,186, " Keine COM1 Maus",0
|
|
||||||
;no_com2 db 13,10,186, " Keine COM2 Maus",0
|
|
||||||
;ask_dma db "Nutze DMA zum HDD Zugriff? [1-ja, 2-allein fur Lesen, 3-nein]: ",0
|
|
||||||
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
|
|
||||||
;gr_direct db 186," Benutze direct LFB? "
|
|
||||||
; db "[1-ja/2-nein] ? ",0
|
|
||||||
;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / "
|
|
||||||
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
|
|
||||||
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
|
|
||||||
bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\kolibri.img (FAT32);"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "3-benutze ein bereits geladenes Kernel image;"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "4-create blank image]: ",0
|
|
||||||
probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, "
|
|
||||||
db "2-BIOS Test (Vesa 3.0)]: ",0
|
|
||||||
;memokz256 db 13,10,186," RAM 256 Mb",0
|
|
||||||
;memokz128 db 13,10,186," RAM 128 Mb",0
|
|
||||||
;memokz64 db 13,10,186," RAM 64 Mb",0
|
|
||||||
;memokz32 db 13,10,186," RAM 32 Mb",0
|
|
||||||
;memokz16 db 13,10,186," RAM 16 Mb",0
|
|
||||||
prnotfnd db "Fatal - Videomodus nicht gefunden.",0
|
|
||||||
;modena db "Fatal - VBE 0x112+ required.",0
|
|
||||||
not386 db "Fatal - CPU 386+ benoetigt.",0
|
|
||||||
btns db "Fatal - konnte Farbtiefe nicht erkennen.",0
|
|
||||||
fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0
|
|
||||||
badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0
|
|
||||||
memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0
|
|
||||||
okt db " ... OK"
|
|
||||||
linef db 13,10,0
|
|
||||||
diskload db "Lade Diskette: 00 %",8,8,8,8,0
|
|
||||||
pros db "00"
|
|
||||||
backspace2 db 8,8,0
|
|
||||||
boot_dev db 0 ; 0=floppy, 1=hd
|
|
||||||
start_msg db "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0
|
|
||||||
time_msg db " oder warte "
|
|
||||||
time_str db " 5 Sekunden"
|
|
||||||
db " bis zum automatischen Start",13,10,0
|
|
||||||
current_cfg_msg db "Aktuelle Einstellungen:",13,10,0
|
|
||||||
curvideo_msg db " [a] Videomodus: ",0
|
|
||||||
mode1 db "640x480",0
|
|
||||||
mode2 db "800x600",0
|
|
||||||
mode3 db "1024x768",0
|
|
||||||
mode4 db "1280x1024",0
|
|
||||||
modes_msg dw mode4,mode1,mode2,mode3
|
|
||||||
modevesa20 db " mit LFB",0
|
|
||||||
modevesa12 db ", VESA 1.2 Bnk",0
|
|
||||||
mode9 db "320x200, EGA/CGA 256 colors",0
|
|
||||||
mode10 db "640x480, VGA 16 colors",0
|
|
||||||
probeno_msg db " (Standard Modus)",0
|
|
||||||
probeok_msg db " (teste nicht-standard Modi)",0
|
|
||||||
;dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0
|
|
||||||
usebd_msg db " [b] Add disks visible by BIOS:",0
|
|
||||||
on_msg db " an",13,10,0
|
|
||||||
off_msg db " aus",13,10,0
|
|
||||||
;readonly_msg db " fur Lesen",13,10,0
|
|
||||||
vrrm_msg db " [c] Nutze VRR:",0
|
|
||||||
preboot_device_msg db " [d] Diskettenimage: ",0
|
|
||||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
|
|
||||||
pdm1 db "Echte Diskette",13,10,0
|
|
||||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
|
||||||
pdm3 db "Nutze bereits geladenes Image",13,10,0
|
|
||||||
pdm4 db "create blank image",13,10,0
|
|
||||||
loading_msg db "Lade KolibriOS...",0
|
|
||||||
save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0
|
|
||||||
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0
|
|
||||||
|
|
||||||
remark1 db "Default values were selected to match most of configurations, but not all.",0
|
|
||||||
remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0
|
|
||||||
remark3 db "If the system does not boot, try to disable the item [b].",0
|
|
||||||
remarks dw remark1, remark2, remark3
|
|
||||||
num_remarks = 3
|
|
@ -1,87 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;=================================================================
|
|
||||||
;
|
|
||||||
; BOOT DATA
|
|
||||||
;
|
|
||||||
;=================================================================
|
|
||||||
|
|
||||||
|
|
||||||
d80x25_bottom:
|
|
||||||
db 186,' Kolibri OS ®á®¢ Menuet OS ¨ ¥ ¯à¥¤®áâ ¢«ï¥â '
|
|
||||||
db '¨ª ª¨å £ àa⨩. ',186
|
|
||||||
db 186,' <20>®¤à®¡¥¥ ᬮâà¨â¥ ¢ ä ©«¥ COPYING.TXT '
|
|
||||||
db ' ',186
|
|
||||||
line_full_bottom
|
|
||||||
msg_apm db " APM x.x ", 0
|
|
||||||
novesa db "‚¨¤¥®ª àâ : EGA/CGA",13,10,0
|
|
||||||
s_vesa db "‚¥àá¨ï VESA: "
|
|
||||||
.ver db "?.?",13,10,0
|
|
||||||
|
|
||||||
gr_mode db "‚ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",13,10,0
|
|
||||||
vrrmprint db "ˆá¯®«ì§®¢ âì VRR? (ç áâ®â ª ¤à®¢ ¢ëè¥ 60 ƒæ"
|
|
||||||
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10
|
|
||||||
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-¥â]: ",0
|
|
||||||
;ask_dma db "ˆá¯®«ì§®¢ âì DMA ¤«ï ¤®áâ㯠ª HDD? [1-¤ , 2-⮫쪮 ç⥨¥, 3-¥â]: ",0
|
|
||||||
ask_bd db "„®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS ¢ ०¨¬¥ V86? [1-¤ , 2-¥â]: ",0
|
|
||||||
bdev db "‡ £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\kolibri.img (FAT32);"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "3-¨á¯®«ì§®¢ âì 㦥 § £àã¦¥ë© ®¡à §;"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "4-ᮧ¤ âì ç¨áâë© ®¡à §]: ",0
|
|
||||||
prnotfnd db "Žè¨¡ª - ‚¨¤¥®à¥¦¨¬ ¥ ©¤¥.",0
|
|
||||||
not386 db "Žè¨¡ª - ’ॡã¥âáï ¯à®æ¥áá®à 386+.",0
|
|
||||||
fatalsel db "Žè¨¡ª - ‚ë¡à ë© ¢¨¤¥®à¥¦¨¬ ¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0
|
|
||||||
pres_key db "<EFBFBD> ¦¨¬¨â¥ «î¡ãî ª« ¢¨èã, ¤«ï ¯¥à¥å®¤ ¢ ¢ë¡®à ०¨¬®¢.",0
|
|
||||||
badsect db 13,10,186," Žè¨¡ª - „¨áª¥â ¯®¢à¥¦¤¥ . <20>®¯à®¡ã©â¥ ¤àã£ãî.",0
|
|
||||||
memmovefailed db 13,10,186," Žè¨¡ª - Int 0x15 move failed.",0
|
|
||||||
okt db " ... OK"
|
|
||||||
linef db 13,10,0
|
|
||||||
diskload db "‡ £à㧪 ¤¨áª¥âë: 00 %",8,8,8,8,0
|
|
||||||
pros db "00"
|
|
||||||
backspace2 db 8,8,0
|
|
||||||
boot_dev db 0
|
|
||||||
start_msg db "<EFBFBD> ¦¬¨â¥ [abc] ¤«ï ¨§¬¥¥¨ï áâ஥ª, [Enter] ¤«ï ¯à®¤®«¦¥¨ï § £à㧪¨",13,10,0
|
|
||||||
time_msg db " ¨«¨ ¯®¤®¦¤¨â¥ "
|
|
||||||
time_str db " 5 ᥪ㤠"
|
|
||||||
db " ¤® ¢â®¬ â¨ç¥áª®£® ¯à®¤®«¦¥¨ï",13,10,0
|
|
||||||
current_cfg_msg db "’¥ªã騥 áâனª¨:",13,10,0
|
|
||||||
curvideo_msg db " [a] ‚¨¤¥®à¥¦¨¬: ",0
|
|
||||||
|
|
||||||
|
|
||||||
mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0
|
|
||||||
mode9 db "640x480, VGA 16 梥⮢",13,10,0
|
|
||||||
|
|
||||||
usebd_msg db " [b] „®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS:",0
|
|
||||||
on_msg db " ¢ª«",13,10,0
|
|
||||||
off_msg db " ¢ëª«",13,10,0
|
|
||||||
readonly_msg db " ⮫쪮 ç⥨¥",13,10,0
|
|
||||||
vrrm_msg db " [c] ˆá¯®«ì§®¢ ¨¥ VRR:",0
|
|
||||||
;preboot_device_msg db " [d] Ž¡à § ¤¨áª¥âë: ",0
|
|
||||||
;preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4
|
|
||||||
;pdm1 db " áâ®ïé ï ¤¨áª¥â ",13,10,0
|
|
||||||
;pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
|
||||||
;pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £àã¦¥ë© ®¡à §",13,10,0
|
|
||||||
;pdm4 db "ᮧ¤ âì ç¨áâë© ®¡à §",13,10,0
|
|
||||||
loading_msg db "ˆ¤ñâ § £à㧪 KolibriOS...",0
|
|
||||||
save_quest db "‡ ¯®¬¨âì ⥪ã騥 áâனª¨? [y/n]: ",0
|
|
||||||
loader_block_error db "Žè¨¡ª ¢ ¤ ëå ç «ì®£® § £àã§ç¨ª , ¯à®¤®«¦¥¨¥ ¥¢®§¬®¦®.",0
|
|
||||||
|
|
||||||
|
|
||||||
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ',13,10,0
|
|
||||||
_r1 db 186,' ³ 320x200 EGA/CGA 256 梥⮢ ³ ³ ',13,10,0
|
|
||||||
_r2 db 186,' ³ 640x480 VGA 16 梥⮢ ³ ³ ',13,10,0
|
|
||||||
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³ ',13,10,0
|
|
||||||
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ',13,10,0
|
|
||||||
|
|
||||||
|
|
||||||
remark1 db "‡ ç¥¨ï ¯® 㬮«ç ¨î ¢ë¡à ë ¤«ï 㤮¡á⢠¡®«ìè¨á⢠, ® ¥ ¢á¥å.",0
|
|
||||||
remark2 db "…᫨ ã ‚ á LCD-¬®¨â®à, ®âª«îç¨â¥ VRR ¢ ¯ãªâ¥ [c] - ® ‚ ¬ ¥ 㦥.",0
|
|
||||||
remark3 db "…᫨ ã ‚ á ¥ £à㧨âáï á¨á⥬ , ¯®¯à®¡ã©â¥ ®âª«îç¨âì ¯ãªâ [b].",0
|
|
||||||
remarks dw remark1, remark2, remark3
|
|
||||||
num_remarks = 3
|
|
@ -1,55 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; boot data: common strings (for all languages)
|
|
||||||
macro line_full_top {
|
|
||||||
db 201
|
|
||||||
times 78 db 205
|
|
||||||
db 187
|
|
||||||
}
|
|
||||||
macro line_full_bottom {
|
|
||||||
db 200
|
|
||||||
times 78 db 205
|
|
||||||
db 188
|
|
||||||
}
|
|
||||||
macro line_half {
|
|
||||||
db 186,' '
|
|
||||||
times 76 db 0xc4
|
|
||||||
db ' ',186
|
|
||||||
}
|
|
||||||
macro line_space {
|
|
||||||
db 186
|
|
||||||
times 78 db 32
|
|
||||||
db 186
|
|
||||||
}
|
|
||||||
d80x25_top:
|
|
||||||
line_full_top
|
|
||||||
cur_line_pos = 75
|
|
||||||
; store byte ' ' at d80x25_top+cur_line_pos+1
|
|
||||||
; store byte ' ' at d80x25_top+cur_line_pos
|
|
||||||
; store dword ' SVN' at d80x25_top+cur_line_pos-4
|
|
||||||
|
|
||||||
space_msg: line_space
|
|
||||||
;verstr:
|
|
||||||
; line_space
|
|
||||||
; version string
|
|
||||||
; db 186,32
|
|
||||||
; repeat 78
|
|
||||||
; load a byte from version+%-1
|
|
||||||
; if a = 13
|
|
||||||
; break
|
|
||||||
; end if
|
|
||||||
; db a
|
|
||||||
; end repeat
|
|
||||||
; repeat 78 - ($-verstr)
|
|
||||||
; db ' '
|
|
||||||
; end repeat
|
|
||||||
; db 32,186
|
|
||||||
; line_half
|
|
||||||
|
|
@ -1,754 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
struc VBE_VGAInfo {
|
|
||||||
.VESASignature dd ? ; char
|
|
||||||
.VESAVersion dw ? ; short
|
|
||||||
.OemStringPtr dd ? ; char *
|
|
||||||
.Capabilities dd ? ; ulong
|
|
||||||
.VideoModePtr dd ? ; ulong
|
|
||||||
.TotalMemory dw ? ; short
|
|
||||||
; VBE 2.0+
|
|
||||||
.OemSoftwareRev db ? ; short
|
|
||||||
.OemVendorNamePtr dw ? ; char *
|
|
||||||
.OemProductNamePtr dw ? ; char *
|
|
||||||
.OemProductRevPtr dw ? ; char *
|
|
||||||
.reserved rb 222 ; char
|
|
||||||
.OemData rb 256 ; char
|
|
||||||
}
|
|
||||||
|
|
||||||
struc VBE_ModeInfo {
|
|
||||||
.ModeAttributes dw ? ; short
|
|
||||||
.WinAAttributes db ? ; char
|
|
||||||
.WinBAttributes db ? ; char
|
|
||||||
.WinGranularity dw ? ; short
|
|
||||||
.WinSize dw ? ; short
|
|
||||||
.WinASegment dw ? ; ushort
|
|
||||||
.WinBSegment dw ? ; ushort
|
|
||||||
.WinFuncPtr dd ? ; void *
|
|
||||||
.BytesPerScanLine dw ? ; short
|
|
||||||
.XRes dw ? ; short
|
|
||||||
.YRes dw ? ; short
|
|
||||||
.XCharSize db ? ; char
|
|
||||||
.YCharSize db ? ; char
|
|
||||||
.NumberOfPlanes db ? ; char
|
|
||||||
.BitsPerPixel db ? ; char
|
|
||||||
.NumberOfBanks db ? ; char
|
|
||||||
.MemoryModel db ? ; char
|
|
||||||
.BankSize db ? ; char
|
|
||||||
.NumberOfImagePages db ? ; char
|
|
||||||
.res1 db ? ; char
|
|
||||||
.RedMaskSize db ? ; char
|
|
||||||
.RedFieldPosition db ? ; char
|
|
||||||
.GreenMaskSize db ? ; char
|
|
||||||
.GreenFieldPosition db ? ; char
|
|
||||||
.BlueMaskSize db ? ; char
|
|
||||||
.BlueFieldPosition db ? ; char
|
|
||||||
.RsvedMaskSize db ? ; char
|
|
||||||
.RsvedFieldPosition db ? ; char
|
|
||||||
.DirectColorModeInfo db ? ; char ; MISSED IN THIS TUTORIAL!! SEE ABOVE
|
|
||||||
; VBE 2.0+
|
|
||||||
.PhysBasePtr dd ? ; ulong
|
|
||||||
.OffScreenMemOffset dd ? ; ulong
|
|
||||||
.OffScreenMemSize dw ? ; short
|
|
||||||
; VBE 3.0+
|
|
||||||
.LinbytesPerScanLine dw ? ; short
|
|
||||||
.BankNumberOfImagePages db ? ; char
|
|
||||||
.LinNumberOfImagePages db ? ; char
|
|
||||||
.LinRedMaskSize db ? ; char
|
|
||||||
.LinRedFieldPosition db ? ; char
|
|
||||||
.LingreenMaskSize db ? ; char
|
|
||||||
.LinGreenFieldPosition db ? ; char
|
|
||||||
.LinBlueMaskSize db ? ; char
|
|
||||||
.LinBlueFieldPosition db ? ; char
|
|
||||||
.LinRsvdMaskSize db ? ; char
|
|
||||||
.LinRsvdFieldPosition db ? ; char
|
|
||||||
.MaxPixelClock dd ? ; ulong
|
|
||||||
.res2 rb 190 ; char
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual at $A000
|
|
||||||
vi VBE_VGAInfo
|
|
||||||
mi VBE_ModeInfo
|
|
||||||
modes_table:
|
|
||||||
end virtual
|
|
||||||
cursor_pos dw 0 ;âðåìåííîå õðàíåíèå êóðñîðà.
|
|
||||||
home_cursor dw 0 ;current shows rows a table
|
|
||||||
end_cursor dw 0 ;end of position current shows rows a table
|
|
||||||
scroll_start dw 0 ;start position of scroll bar
|
|
||||||
scroll_end dw 0 ;end position of scroll bar
|
|
||||||
long_v_table equ 9 ;long of visible video table
|
|
||||||
size_of_step equ 10
|
|
||||||
scroll_area_size equ (long_v_table-2)
|
|
||||||
int2str:
|
|
||||||
dec bl
|
|
||||||
jz @f
|
|
||||||
xor edx,edx
|
|
||||||
div ecx
|
|
||||||
push edx
|
|
||||||
call int2str
|
|
||||||
pop eax
|
|
||||||
@@: or al,0x30
|
|
||||||
mov [ds:di],al
|
|
||||||
inc di
|
|
||||||
ret
|
|
||||||
|
|
||||||
int2strnz:
|
|
||||||
cmp eax,ecx
|
|
||||||
jb @f
|
|
||||||
xor edx,edx
|
|
||||||
div ecx
|
|
||||||
push edx
|
|
||||||
call int2strnz
|
|
||||||
pop eax
|
|
||||||
@@: or al,0x30
|
|
||||||
mov [es:di],al
|
|
||||||
inc di
|
|
||||||
ret
|
|
||||||
|
|
||||||
;-------------------------------------------------------
|
|
||||||
;Write message about incorrect v_mode and write message about jmp on swith v_mode
|
|
||||||
v_mode_error:
|
|
||||||
_setcursor 19,2
|
|
||||||
mov si, fatalsel
|
|
||||||
call printplain
|
|
||||||
_setcursor 20,2
|
|
||||||
mov si,pres_key
|
|
||||||
call printplain
|
|
||||||
xor eax,eax
|
|
||||||
int 16h
|
|
||||||
jmp cfgmanager.d
|
|
||||||
;-------------------------------------------------------
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-------------------------------------------------------
|
|
||||||
print_vesa_info:
|
|
||||||
_setcursor 5,2
|
|
||||||
|
|
||||||
mov [es:vi.VESASignature],'VBE2'
|
|
||||||
mov ax,0x4F00
|
|
||||||
mov di,vi ;0xa000
|
|
||||||
int 0x10
|
|
||||||
or ah,ah
|
|
||||||
jz @f
|
|
||||||
mov [es:vi.VESASignature],'VESA'
|
|
||||||
mov ax,$4F00
|
|
||||||
mov di,vi
|
|
||||||
int 0x10
|
|
||||||
or ah,ah
|
|
||||||
jnz .exit
|
|
||||||
@@:
|
|
||||||
cmp [es:vi.VESASignature],'VESA'
|
|
||||||
jne .exit
|
|
||||||
cmp [es:vi.VESAVersion],0x0100
|
|
||||||
jb .exit
|
|
||||||
jmp .vesaok2
|
|
||||||
|
|
||||||
.exit:
|
|
||||||
mov si,novesa
|
|
||||||
call printplain
|
|
||||||
ret
|
|
||||||
|
|
||||||
.vesaok2:
|
|
||||||
mov ax,[es:vi.VESAVersion]
|
|
||||||
add ax,'00'
|
|
||||||
|
|
||||||
mov [s_vesa.ver], ah
|
|
||||||
mov [s_vesa.ver+2], al
|
|
||||||
mov si,s_vesa
|
|
||||||
call printplain
|
|
||||||
|
|
||||||
_setcursor 4,2
|
|
||||||
mov si,word[es:vi.OemStringPtr]
|
|
||||||
mov di,si
|
|
||||||
|
|
||||||
push ds
|
|
||||||
mov ds,word[es:vi.OemStringPtr+2]
|
|
||||||
call printplain
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
ret
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
calc_vmodes_table:
|
|
||||||
pushad
|
|
||||||
|
|
||||||
; push 0
|
|
||||||
; pop es
|
|
||||||
|
|
||||||
lfs si, [es:vi.VideoModePtr]
|
|
||||||
|
|
||||||
mov bx,modes_table
|
|
||||||
;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢
|
|
||||||
mov word [es:bx],640
|
|
||||||
mov word [es:bx+2],480
|
|
||||||
mov word [es:bx+6],0x13
|
|
||||||
|
|
||||||
mov word [es:bx+10],640
|
|
||||||
mov word [es:bx+12],480
|
|
||||||
mov word [es:bx+16],0x12
|
|
||||||
add bx,20
|
|
||||||
.next_mode:
|
|
||||||
mov cx,word [fs:si] ; mode number
|
|
||||||
cmp cx,-1
|
|
||||||
je .modes_ok.2
|
|
||||||
|
|
||||||
mov ax,0x4F01
|
|
||||||
mov di,mi
|
|
||||||
int 0x10
|
|
||||||
|
|
||||||
or ah,ah
|
|
||||||
jnz .modes_ok.2;vesa_info.exit
|
|
||||||
|
|
||||||
test [es:mi.ModeAttributes],00000001b ;videomode support ?
|
|
||||||
jz @f
|
|
||||||
test [es:mi.ModeAttributes],00010000b ;picture ?
|
|
||||||
jz @f
|
|
||||||
test [es:mi.ModeAttributes],10000000b ;LFB ?
|
|
||||||
jz @f
|
|
||||||
|
|
||||||
cmp [es:mi.BitsPerPixel], 24 ;It show only videomodes to have support 24 and 32 bpp
|
|
||||||
jb @f
|
|
||||||
|
|
||||||
; cmp [es:mi.BitsPerPixel],16
|
|
||||||
; jne .l0
|
|
||||||
; cmp [es:mi.GreenMaskSize],5
|
|
||||||
; jne .l0
|
|
||||||
; mov [es:mi.BitsPerPixel],15
|
|
||||||
|
|
||||||
|
|
||||||
.l0:
|
|
||||||
cmp [es:mi.XRes],640
|
|
||||||
jb @f
|
|
||||||
cmp [es:mi.YRes],480
|
|
||||||
jb @f
|
|
||||||
; cmp [es:mi.BitsPerPixel],8
|
|
||||||
; jb @f
|
|
||||||
|
|
||||||
mov ax,[es:mi.XRes]
|
|
||||||
mov [es:bx+0],ax ; +0[2] : resolution X
|
|
||||||
mov ax,[es:mi.YRes]
|
|
||||||
mov [es:bx+2],ax ; +2[2] : resolution Y
|
|
||||||
mov ax,[es:mi.ModeAttributes]
|
|
||||||
mov [es:bx+4],ax ; +4[2] : attributes
|
|
||||||
|
|
||||||
cmp [s_vesa.ver],'2'
|
|
||||||
jb .lp1
|
|
||||||
|
|
||||||
or cx,0x4000 ; use LFB
|
|
||||||
.lp1: mov [es:bx+6],cx ; +6 : mode number
|
|
||||||
movzx ax,byte [es:mi.BitsPerPixel]
|
|
||||||
mov word [es:bx+8],ax ; +8 : bits per pixel
|
|
||||||
add bx,size_of_step ; size of record
|
|
||||||
|
|
||||||
@@:
|
|
||||||
add si,2
|
|
||||||
jmp .next_mode
|
|
||||||
|
|
||||||
.modes_ok.2:
|
|
||||||
|
|
||||||
mov word[es:bx],-1 ;end video table
|
|
||||||
mov word[end_cursor],bx ;save end cursor position
|
|
||||||
;;;;;;;;;;;;;;;;;;
|
|
||||||
;Sort array
|
|
||||||
; mov si,modes_table
|
|
||||||
;.new_mode:
|
|
||||||
; mov ax,word [es:si]
|
|
||||||
; cmp ax,-1
|
|
||||||
; je .exxit
|
|
||||||
; add ax,word [es:si+2]
|
|
||||||
; add ax,word [es:si+8]
|
|
||||||
; mov bp,si
|
|
||||||
;.again:
|
|
||||||
; add bp,12
|
|
||||||
; mov bx,word [es:bp]
|
|
||||||
; cmp bx,-1
|
|
||||||
; je .exit
|
|
||||||
; add bx,word [es:bp+2]
|
|
||||||
; add bx,word [es:bp+8]
|
|
||||||
;
|
|
||||||
; cmp ax,bx
|
|
||||||
; ja .loops
|
|
||||||
; jmp .again
|
|
||||||
;.loops:
|
|
||||||
; push dword [es:si]
|
|
||||||
; push dword [es:si+4]
|
|
||||||
; push dword [es:si+8]
|
|
||||||
; push dword [es:bp]
|
|
||||||
; push dword [es:bp+4]
|
|
||||||
; push dword [es:bp+8]
|
|
||||||
;
|
|
||||||
; pop dword [es:si+8]
|
|
||||||
; pop dword [es:si+4]
|
|
||||||
; pop dword [es:si]
|
|
||||||
; pop dword [es:bp+8]
|
|
||||||
; pop dword [es:bp+4]
|
|
||||||
; pop dword [es:bp]
|
|
||||||
; jmp .new_mode
|
|
||||||
;
|
|
||||||
;.exit: add si,12
|
|
||||||
; jmp .new_mode
|
|
||||||
;.exxit:
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
draw_current_vmode:
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
|
|
||||||
mov si,word [cursor_pos]
|
|
||||||
|
|
||||||
cmp word [es:si+6],0x12
|
|
||||||
je .no_vesa_0x12
|
|
||||||
|
|
||||||
cmp word [es:si+6],0x13
|
|
||||||
je .no_vesa_0x13
|
|
||||||
|
|
||||||
mov di,loader_block_error
|
|
||||||
movzx eax,word[es:si+0]
|
|
||||||
mov ecx,10
|
|
||||||
call int2strnz
|
|
||||||
mov byte[es:di],'x'
|
|
||||||
inc di
|
|
||||||
movzx eax,word[es:si+2]
|
|
||||||
call int2strnz
|
|
||||||
mov byte[es:di],'x'
|
|
||||||
inc di
|
|
||||||
movzx eax,word[es:si+8]
|
|
||||||
call int2strnz
|
|
||||||
mov dword[es:di],0x00000d0a
|
|
||||||
mov si,loader_block_error
|
|
||||||
push ds
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
call printplain
|
|
||||||
pop ds
|
|
||||||
ret
|
|
||||||
.no_vesa_0x13:
|
|
||||||
mov si,mode0
|
|
||||||
jmp .print
|
|
||||||
.no_vesa_0x12:
|
|
||||||
mov si,mode9
|
|
||||||
.print:
|
|
||||||
call printplain
|
|
||||||
ret
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
check_first_parm:
|
|
||||||
mov si,word [preboot_graph]
|
|
||||||
test si,si
|
|
||||||
jnz .no_zero ;if no zero
|
|
||||||
.zerro:
|
|
||||||
; mov ax,modes_table
|
|
||||||
; mov word [cursor_pos],ax
|
|
||||||
; mov word [home_cursor],ax
|
|
||||||
; mov word [preboot_graph],ax
|
|
||||||
;SET default video of mode first probe will fined a move of work 1024x768@32
|
|
||||||
|
|
||||||
mov ax,1024
|
|
||||||
mov bx,768
|
|
||||||
mov si,modes_table
|
|
||||||
call .loops
|
|
||||||
test ax,ax
|
|
||||||
jz .ok_found_mode
|
|
||||||
mov ax,800
|
|
||||||
mov bx,600
|
|
||||||
mov si,modes_table
|
|
||||||
call .loops
|
|
||||||
test ax,ax
|
|
||||||
jz .ok_found_mode
|
|
||||||
mov ax,640
|
|
||||||
mov bx,480
|
|
||||||
mov si,modes_table
|
|
||||||
call .loops
|
|
||||||
test ax,ax
|
|
||||||
jz .ok_found_mode
|
|
||||||
|
|
||||||
mov si,modes_table
|
|
||||||
jmp .ok_found_mode
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.no_zero:
|
|
||||||
mov bp,word [number_vm]
|
|
||||||
cmp bp,word [es:si+6]
|
|
||||||
jz .ok_found_mode
|
|
||||||
mov ax,word [x_save]
|
|
||||||
mov bx,word [y_save]
|
|
||||||
mov si,modes_table
|
|
||||||
call .loops
|
|
||||||
test ax,ax
|
|
||||||
jz .ok_found_mode
|
|
||||||
|
|
||||||
mov si,modes_table
|
|
||||||
; cmp ax,modes_table
|
|
||||||
; jb .zerro ;check on correct if bellow
|
|
||||||
; cmp ax,word [end_cursor]
|
|
||||||
; ja .zerro ;check on correct if anymore
|
|
||||||
|
|
||||||
.ok_found_mode:
|
|
||||||
mov word [home_cursor],si
|
|
||||||
; mov word [cursor_pos],si
|
|
||||||
mov word [preboot_graph],si
|
|
||||||
mov ax,si
|
|
||||||
|
|
||||||
mov ecx,long_v_table
|
|
||||||
|
|
||||||
.loop: add ax,size_of_step
|
|
||||||
cmp ax,word [end_cursor]
|
|
||||||
jae .next_step
|
|
||||||
loop .loop
|
|
||||||
.next_step:
|
|
||||||
sub ax,size_of_step*long_v_table
|
|
||||||
cmp ax,modes_table
|
|
||||||
jae @f
|
|
||||||
mov ax,modes_table
|
|
||||||
@@:
|
|
||||||
|
|
||||||
mov word [home_cursor],ax
|
|
||||||
mov si,[preboot_graph]
|
|
||||||
mov word [cursor_pos],si
|
|
||||||
|
|
||||||
push word [es:si]
|
|
||||||
pop word [x_save]
|
|
||||||
push word [es:si+2]
|
|
||||||
pop word [y_save]
|
|
||||||
push word [es:si+6]
|
|
||||||
pop word [number_vm]
|
|
||||||
|
|
||||||
ret
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
.loops:
|
|
||||||
cmp ax,word [es:si]
|
|
||||||
jne .next
|
|
||||||
cmp bx,word [es:si+2]
|
|
||||||
jne .next
|
|
||||||
cmp word [es:si+8],32
|
|
||||||
je .ok
|
|
||||||
cmp word [es:si+8],24
|
|
||||||
je .ok
|
|
||||||
.next: add si,size_of_step
|
|
||||||
cmp word [es:si],-1
|
|
||||||
je .exit
|
|
||||||
jmp .loops
|
|
||||||
.ok: xor ax,ax
|
|
||||||
ret
|
|
||||||
.exit: or ax,-1
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;default_vmode:
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
draw_vmodes_table:
|
|
||||||
_setcursor 9, 2
|
|
||||||
mov si,gr_mode
|
|
||||||
call printplain
|
|
||||||
|
|
||||||
mov si,_st
|
|
||||||
call printplain
|
|
||||||
|
|
||||||
push word [cursor_pos]
|
|
||||||
pop ax
|
|
||||||
push word [home_cursor]
|
|
||||||
pop si
|
|
||||||
mov cx,si
|
|
||||||
|
|
||||||
cmp ax,si
|
|
||||||
je .ok
|
|
||||||
jb .low
|
|
||||||
|
|
||||||
|
|
||||||
add cx,size_of_step*long_v_table
|
|
||||||
|
|
||||||
cmp ax,cx
|
|
||||||
jb .ok
|
|
||||||
|
|
||||||
sub cx,size_of_step*long_v_table
|
|
||||||
add cx,size_of_step
|
|
||||||
cmp cx,word[end_cursor]
|
|
||||||
jae .ok
|
|
||||||
add si,size_of_step
|
|
||||||
push si
|
|
||||||
pop word [home_cursor]
|
|
||||||
jmp .ok
|
|
||||||
|
|
||||||
|
|
||||||
.low: sub cx,size_of_step
|
|
||||||
cmp cx,modes_table
|
|
||||||
jb .ok
|
|
||||||
push cx
|
|
||||||
push cx
|
|
||||||
pop word [home_cursor]
|
|
||||||
pop si
|
|
||||||
|
|
||||||
|
|
||||||
.ok:
|
|
||||||
; calculate scroll position
|
|
||||||
push si
|
|
||||||
mov ax, [end_cursor]
|
|
||||||
sub ax, modes_table
|
|
||||||
mov bx, size_of_step
|
|
||||||
cwd
|
|
||||||
div bx
|
|
||||||
mov si, ax ; si = size of list
|
|
||||||
mov ax, [home_cursor]
|
|
||||||
sub ax, modes_table
|
|
||||||
cwd
|
|
||||||
div bx
|
|
||||||
mov di, ax
|
|
||||||
mov ax, scroll_area_size*long_v_table
|
|
||||||
cwd
|
|
||||||
div si
|
|
||||||
test ax, ax
|
|
||||||
jnz @f
|
|
||||||
inc ax
|
|
||||||
@@:
|
|
||||||
cmp al, scroll_area_size
|
|
||||||
jb @f
|
|
||||||
mov al, scroll_area_size
|
|
||||||
@@:
|
|
||||||
mov cx, ax
|
|
||||||
; cx = scroll height
|
|
||||||
; calculate scroll pos
|
|
||||||
xor bx, bx ; initialize scroll pos
|
|
||||||
sub al, scroll_area_size+1
|
|
||||||
neg al
|
|
||||||
sub si, long_v_table-1
|
|
||||||
jbe @f
|
|
||||||
mul di
|
|
||||||
div si
|
|
||||||
mov bx, ax
|
|
||||||
@@:
|
|
||||||
inc bx
|
|
||||||
imul ax, bx, size_of_step
|
|
||||||
add ax, [home_cursor]
|
|
||||||
mov [scroll_start], ax
|
|
||||||
imul cx, size_of_step
|
|
||||||
add ax, cx
|
|
||||||
mov [scroll_end], ax
|
|
||||||
pop si
|
|
||||||
mov bp,long_v_table ;show rows
|
|
||||||
.@@_next_bit:
|
|
||||||
;clear cursor
|
|
||||||
mov ax,' '
|
|
||||||
mov word[ds:_r1+21],ax
|
|
||||||
mov word[ds:_r1+50],ax
|
|
||||||
|
|
||||||
mov word[ds:_r2+21],ax
|
|
||||||
mov word[ds:_r2+45],ax
|
|
||||||
|
|
||||||
mov word[ds:_rs+21],ax
|
|
||||||
mov word[ds:_rs+46],ax
|
|
||||||
; draw string
|
|
||||||
cmp word [es:si+6],0x12
|
|
||||||
je .show_0x12
|
|
||||||
cmp word [es:si+6],0x13
|
|
||||||
je .show_0x13
|
|
||||||
|
|
||||||
movzx eax,word[es:si]
|
|
||||||
cmp ax,-1
|
|
||||||
je .@@_end
|
|
||||||
mov di,_rs+23
|
|
||||||
mov ecx,10
|
|
||||||
mov bl,4
|
|
||||||
call int2str
|
|
||||||
movzx eax,word[es:si+2]
|
|
||||||
inc di
|
|
||||||
mov bl,4
|
|
||||||
call int2str
|
|
||||||
|
|
||||||
movzx eax,word[es:si+8]
|
|
||||||
inc di
|
|
||||||
mov bl,2
|
|
||||||
call int2str
|
|
||||||
|
|
||||||
cmp si, word [cursor_pos]
|
|
||||||
jne .next
|
|
||||||
;draw cursor
|
|
||||||
mov word[ds:_rs+21],'>>'
|
|
||||||
mov word[ds:_rs+46],'<<'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.next:
|
|
||||||
push si
|
|
||||||
mov si,_rs
|
|
||||||
.@@_sh:
|
|
||||||
; add to the string pseudographics for scrollbar
|
|
||||||
pop bx
|
|
||||||
push bx
|
|
||||||
mov byte [si+53], ' '
|
|
||||||
cmp bx, [scroll_start]
|
|
||||||
jb @f
|
|
||||||
cmp bx, [scroll_end]
|
|
||||||
jae @f
|
|
||||||
mov byte [si+53], 0xDB ; filled bar
|
|
||||||
@@:
|
|
||||||
push bx
|
|
||||||
add bx, size_of_step
|
|
||||||
cmp bx, [end_cursor]
|
|
||||||
jnz @f
|
|
||||||
mov byte [si+53], 31 ; 'down arrow' symbol
|
|
||||||
@@:
|
|
||||||
sub bx, [home_cursor]
|
|
||||||
cmp bx, size_of_step*long_v_table
|
|
||||||
jnz @f
|
|
||||||
mov byte [si+53], 31 ; 'down arrow' symbol
|
|
||||||
@@:
|
|
||||||
pop bx
|
|
||||||
cmp bx, [home_cursor]
|
|
||||||
jnz @f
|
|
||||||
mov byte [si+53], 30 ; 'up arrow' symbol
|
|
||||||
@@:
|
|
||||||
call printplain
|
|
||||||
pop si
|
|
||||||
add si,size_of_step
|
|
||||||
|
|
||||||
dec bp
|
|
||||||
jnz .@@_next_bit
|
|
||||||
|
|
||||||
.@@_end:
|
|
||||||
mov si,_bt
|
|
||||||
call printplain
|
|
||||||
ret
|
|
||||||
.show_0x13:
|
|
||||||
push si
|
|
||||||
|
|
||||||
cmp si, word [cursor_pos]
|
|
||||||
jne @f
|
|
||||||
mov word[ds:_r1+21],'>>'
|
|
||||||
mov word[ds:_r1+50],'<<'
|
|
||||||
@@:
|
|
||||||
mov si,_r1
|
|
||||||
jmp .@@_sh
|
|
||||||
.show_0x12:
|
|
||||||
push si
|
|
||||||
cmp si, word [cursor_pos]
|
|
||||||
jne @f
|
|
||||||
|
|
||||||
mov word[ds:_r2+21],'>>'
|
|
||||||
mov word[ds:_r2+45],'<<'
|
|
||||||
@@:
|
|
||||||
mov si,_r2
|
|
||||||
jmp .@@_sh
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
;Clear arrea of current video page (0xb800)
|
|
||||||
clear_vmodes_table:
|
|
||||||
pusha
|
|
||||||
; draw frames
|
|
||||||
push es
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
mov di,1444
|
|
||||||
xor ax,ax
|
|
||||||
mov ah, 1*16+15
|
|
||||||
mov cx,70
|
|
||||||
mov bp,12
|
|
||||||
.loop_start:
|
|
||||||
rep stosw
|
|
||||||
mov cx,70
|
|
||||||
add di,20
|
|
||||||
dec bp
|
|
||||||
jns .loop_start
|
|
||||||
pop es
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
set_vmode:
|
|
||||||
push 0 ;0;x1000
|
|
||||||
pop es
|
|
||||||
|
|
||||||
mov si,word [preboot_graph] ;[preboot_graph]
|
|
||||||
mov cx,word [es:si+6] ; number of mode
|
|
||||||
|
|
||||||
|
|
||||||
mov ax,word [es:si+0] ; resolution X
|
|
||||||
mov bx,word [es:si+2] ; resolution Y
|
|
||||||
|
|
||||||
|
|
||||||
mov word [es:0x900A],ax ; resolution X
|
|
||||||
mov word [es:0x900C],bx ; resolution Y
|
|
||||||
mov word [es:0x9008],cx ; number of mode
|
|
||||||
|
|
||||||
cmp cx,0x12
|
|
||||||
je .mode0x12_0x13
|
|
||||||
cmp cx,0x13
|
|
||||||
je .mode0x12_0x13
|
|
||||||
|
|
||||||
|
|
||||||
cmp byte [s_vesa.ver],'2'
|
|
||||||
jb .vesa12
|
|
||||||
|
|
||||||
; VESA 2 and Vesa 3
|
|
||||||
|
|
||||||
mov ax,0x4f01
|
|
||||||
and cx,0xfff
|
|
||||||
mov di,mi;0xa000
|
|
||||||
int 0x10
|
|
||||||
; LFB
|
|
||||||
mov eax,[es:mi.PhysBasePtr];di+0x28]
|
|
||||||
mov [es:0x9018],eax
|
|
||||||
; ---- vbe voodoo
|
|
||||||
BytesPerLine equ 0x10
|
|
||||||
mov ax, [es:di+BytesPerLine]
|
|
||||||
mov [es:0x9001], ax
|
|
||||||
; BPP
|
|
||||||
cmp [es:mi.BitsPerPixel],16
|
|
||||||
jne .l0
|
|
||||||
cmp [es:mi.GreenMaskSize],5
|
|
||||||
jne .l0
|
|
||||||
mov [es:mi.BitsPerPixel],15
|
|
||||||
.l0:
|
|
||||||
mov al, byte [es:di+0x19]
|
|
||||||
mov [es:0x9000], al
|
|
||||||
jmp .exit
|
|
||||||
|
|
||||||
.mode0x12_0x13:
|
|
||||||
mov byte [es:0x9000], 32
|
|
||||||
or dword [es:0x9018], 0xFFFFFFFF; 0x800000
|
|
||||||
|
|
||||||
|
|
||||||
; VESA 1.2 PM BANK SWITCH ADDRESS
|
|
||||||
|
|
||||||
.vesa12:
|
|
||||||
|
|
||||||
|
|
||||||
mov ax,0x4f0A
|
|
||||||
xor bx,bx
|
|
||||||
int 0x10
|
|
||||||
xor eax,eax
|
|
||||||
xor ebx,ebx
|
|
||||||
mov ax,es
|
|
||||||
shl eax,4
|
|
||||||
mov bx,di
|
|
||||||
add eax,ebx
|
|
||||||
movzx ebx,word[es:di]
|
|
||||||
add eax,ebx
|
|
||||||
push 0x0000
|
|
||||||
pop es
|
|
||||||
mov [es:0x9014],eax
|
|
||||||
.exit:
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
; mov dword[es:0x9018],0x000A0000
|
|
||||||
; ret
|
|
||||||
|
|
||||||
;=============================================================================
|
|
||||||
;=============================================================================
|
|
||||||
;=============================================================================
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
set languages=en ru ge et
|
|
||||||
call :Check_Lang %1
|
|
||||||
for %%a in (ru) do if %%a==%target%
|
|
||||||
call :Target_%target%
|
|
||||||
|
|
||||||
if ERRORLEVEL 0 goto Exit_OK
|
|
||||||
|
|
||||||
echo There was an error executing script.
|
|
||||||
echo For any help, please send a report.
|
|
||||||
pause
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:Check_Lang
|
|
||||||
set res=%1
|
|
||||||
:Check_Lang_loop
|
|
||||||
for %%a in (%languages%) do if %%a==%res% set lang=%res%
|
|
||||||
if defined lang call :make_all goto :eof
|
|
||||||
|
|
||||||
echo Language '%res%' is incorrect
|
|
||||||
echo Enter valid language [ %languages% ]:
|
|
||||||
|
|
||||||
set /P res=">
|
|
||||||
goto Check_Lang_loop
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
:make_all
|
|
||||||
echo *** building module Kolibri.ldm for Secondary Loader with language '%lang%' ...
|
|
||||||
|
|
||||||
if not exist bin mkdir bin
|
|
||||||
echo lang fix %lang% > lang.inc
|
|
||||||
fasm -m 65536 kolibri_ldm.asm bin\kolibri.ldm
|
|
||||||
if not %errorlevel%==0 goto :Error_FasmFailed
|
|
||||||
erase lang.inc
|
|
||||||
goto Exit_OK
|
|
||||||
|
|
||||||
|
|
||||||
:Target_all
|
|
||||||
call :Target_kernel
|
|
||||||
call :Target_drivers
|
|
||||||
call :Target_skins
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
:Target_drivers
|
|
||||||
echo *** building drivers ...
|
|
||||||
|
|
||||||
if not exist bin\drivers mkdir bin\drivers
|
|
||||||
cd drivers
|
|
||||||
for %%a in (%drivers%) do (
|
|
||||||
fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj
|
|
||||||
if not %errorlevel%==0 goto :Error_FasmFailed
|
|
||||||
)
|
|
||||||
cd ..
|
|
||||||
move bin\drivers\vmode.obj bin\drivers\vmode.mdr
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
|
|
||||||
:Target_skins
|
|
||||||
echo *** building skins ...
|
|
||||||
|
|
||||||
if not exist bin\skins mkdir bin\skins
|
|
||||||
cd skin
|
|
||||||
fasm -m 65536 default.asm ..\bin\skins\default.skn
|
|
||||||
if not %errorlevel%==0 goto :Error_FasmFailed
|
|
||||||
cd ..
|
|
||||||
goto :eof
|
|
||||||
|
|
||||||
:Target_clean
|
|
||||||
echo *** cleaning ...
|
|
||||||
rmdir /S /Q bin
|
|
||||||
goto :Exit_OK
|
|
||||||
|
|
||||||
|
|
||||||
:Error_FasmFailed
|
|
||||||
echo error: fasm execution failed
|
|
||||||
erase lang.inc
|
|
||||||
pause
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
:Exit_OK
|
|
||||||
echo all operations has been done
|
|
||||||
pause
|
|
||||||
exit 0
|
|
@ -1,14 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
; Full ASCII code font
|
|
||||||
; only õ and ä added
|
|
||||||
; Kaitz
|
|
||||||
ET_FNT:
|
|
||||||
fontfile file "ETFONT.FNT"
|
|
||||||
|
|
@ -1,808 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Last modify Alexey Teplov <Lrz> 2008. All rights reserved. ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;; kolibri_ldm.asm the module for Secondary Loader ;;
|
|
||||||
;; ;;
|
|
||||||
;; KolibriOS 16-bit loader module, ;;
|
|
||||||
;; based on bootcode for KolibriOS ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
include "lang.inc"
|
|
||||||
|
|
||||||
macro _setcursor row,column
|
|
||||||
{
|
|
||||||
mov dx, row*256 + column
|
|
||||||
call setcursor
|
|
||||||
}
|
|
||||||
long_v_table equ 9 ;long of visible video table
|
|
||||||
size_of_step equ 10
|
|
||||||
d80x25_bottom_num equ 3
|
|
||||||
d80x25_top_num equ 4
|
|
||||||
;It's a module for Secondary Loader to load kolibri OS
|
|
||||||
;
|
|
||||||
start_of_code:
|
|
||||||
cld
|
|
||||||
; \begin{diamond}[02.12.2005]
|
|
||||||
; if bootloader sets ax = 'KL', then ds:si points to loader block
|
|
||||||
; cmp ax, 'KL'
|
|
||||||
; jnz @f
|
|
||||||
; mov word [cs:cfgmanager.loader_block], si
|
|
||||||
; mov word [cs:cfgmanager.loader_block+2], ds
|
|
||||||
;@@:
|
|
||||||
; \end{diamond}[02.12.2005]
|
|
||||||
|
|
||||||
; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk
|
|
||||||
; (see comment to bx_from_load)
|
|
||||||
; cmp cx, 'HA'
|
|
||||||
; jnz no_hd_load
|
|
||||||
; cmp dx,'RD'
|
|
||||||
; jnz no_hd_load
|
|
||||||
; mov word [cs:bx_from_load], bx ; {SPraid}[13.03.2007]
|
|
||||||
;no_hd_load:
|
|
||||||
|
|
||||||
; set up stack
|
|
||||||
push cs
|
|
||||||
pop ss
|
|
||||||
xor ax,ax
|
|
||||||
mov sp,ax
|
|
||||||
; mov ax, 3000h
|
|
||||||
; mov ss, ax
|
|
||||||
; mov sp, 0EC00h
|
|
||||||
; set up segment registers
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
push cs
|
|
||||||
pop es
|
|
||||||
|
|
||||||
; set videomode
|
|
||||||
mov ax, 3
|
|
||||||
int 0x10
|
|
||||||
|
|
||||||
;if lang eq ru
|
|
||||||
; Load & set russian VGA font (RU.INC)
|
|
||||||
mov bp, RU_FNT1 ; RU_FNT1 - First part
|
|
||||||
mov bx, 1000h ; 768 bytes
|
|
||||||
mov cx, 30h ; 48 symbols
|
|
||||||
mov dx, 80h ; 128 - position of first symbol
|
|
||||||
mov ax, 1100h
|
|
||||||
int 10h
|
|
||||||
|
|
||||||
mov bp, RU_FNT2 ; RU_FNT2 -Second part
|
|
||||||
mov bx, 1000h ; 512 bytes
|
|
||||||
mov cx, 20h ; 32 symbols
|
|
||||||
mov dx, 0E0h ; 224 - position of first symbol
|
|
||||||
mov ax, 1100h
|
|
||||||
int 10h
|
|
||||||
; End set VGA russian font
|
|
||||||
;else if lang eq et
|
|
||||||
; mov bp, ET_FNT ; ET_FNT1
|
|
||||||
; mov bx, 1000h ;
|
|
||||||
; mov cx, 255 ; 256 symbols
|
|
||||||
; xor dx, dx ; 0 - position of first symbol
|
|
||||||
; mov ax, 1100h
|
|
||||||
; int 10h
|
|
||||||
;end if
|
|
||||||
|
|
||||||
; draw frames
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
xor di, di
|
|
||||||
mov ah, 1*16+15
|
|
||||||
|
|
||||||
; draw top
|
|
||||||
mov si, d80x25_top
|
|
||||||
mov cx, d80x25_top_num * 80
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
; draw spaces
|
|
||||||
mov si, space_msg
|
|
||||||
mov dx, 25 - d80x25_top_num - d80x25_bottom_num
|
|
||||||
dfl1:
|
|
||||||
push si
|
|
||||||
mov cx, 80
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
pop si
|
|
||||||
dec dx
|
|
||||||
jnz dfl1
|
|
||||||
; draw bottom
|
|
||||||
mov si, d80x25_bottom
|
|
||||||
mov cx, d80x25_bottom_num * 80
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
|
|
||||||
mov byte [space_msg+80], 0 ; now space_msg is null terminated
|
|
||||||
|
|
||||||
_setcursor d80x25_top_num,0
|
|
||||||
|
|
||||||
|
|
||||||
; TEST FOR 386+
|
|
||||||
|
|
||||||
mov bx, 0x4000
|
|
||||||
pushf
|
|
||||||
pop ax
|
|
||||||
mov dx, ax
|
|
||||||
xor ax, bx
|
|
||||||
push ax
|
|
||||||
popf
|
|
||||||
pushf
|
|
||||||
pop ax
|
|
||||||
and ax, bx
|
|
||||||
and dx, bx
|
|
||||||
cmp ax, dx
|
|
||||||
jnz cpugood
|
|
||||||
mov si, not386
|
|
||||||
sayerr:
|
|
||||||
call print
|
|
||||||
jmp $
|
|
||||||
cpugood:
|
|
||||||
|
|
||||||
push 0
|
|
||||||
popf
|
|
||||||
sti
|
|
||||||
|
|
||||||
; set up esp
|
|
||||||
movzx esp, sp
|
|
||||||
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
and word [es:0x9031], 0
|
|
||||||
; \begin{Mario79}
|
|
||||||
; find HDD IDE DMA PCI device
|
|
||||||
; check for PCI BIOS
|
|
||||||
mov ax, 0xB101
|
|
||||||
int 0x1A
|
|
||||||
jc .nopci
|
|
||||||
cmp edx, 'PCI '
|
|
||||||
jnz .nopci
|
|
||||||
; find PCI class code
|
|
||||||
; class 1 = mass storage
|
|
||||||
; subclass 1 = IDE controller
|
|
||||||
; a) class 1, subclass 1, programming interface 0x80
|
|
||||||
mov ax, 0xB103
|
|
||||||
mov ecx, 1*10000h + 1*100h + 0x80
|
|
||||||
xor si, si ; device index = 0
|
|
||||||
int 0x1A
|
|
||||||
jnc .found
|
|
||||||
; b) class 1, subclass 1, programming interface 0x8A
|
|
||||||
mov ax, 0xB103
|
|
||||||
mov ecx, 1*10000h + 1*100h + 0x8A
|
|
||||||
xor si, si ; device index = 0
|
|
||||||
int 0x1A
|
|
||||||
jnc .found
|
|
||||||
; c) class 1, subclass 1, programming interface 0x85
|
|
||||||
mov ax, 0xB103
|
|
||||||
mov ecx, 1*10000h + 1*100h + 0x85
|
|
||||||
xor si, si
|
|
||||||
int 0x1A
|
|
||||||
jc .nopci
|
|
||||||
.found:
|
|
||||||
; get memory base
|
|
||||||
mov ax, 0xB10A
|
|
||||||
mov di, 0x20 ; memory base is config register at 0x20
|
|
||||||
int 0x1A
|
|
||||||
jc .nopci
|
|
||||||
and cx, 0xFFF0 ; clear address decode type
|
|
||||||
mov [es:0x9031], cx
|
|
||||||
.nopci:
|
|
||||||
; \end{Mario79}
|
|
||||||
|
|
||||||
mov al, 0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
|
|
||||||
out 0x60, al
|
|
||||||
xor cx, cx
|
|
||||||
wait_loop: ; variant 2
|
|
||||||
; reading state of port of 8042 controller
|
|
||||||
in al, 64h
|
|
||||||
and al, 00000010b ; ready flag
|
|
||||||
; wait until 8042 controller is ready
|
|
||||||
loopnz wait_loop
|
|
||||||
|
|
||||||
;;;/diamond today 5.02.2008
|
|
||||||
; set keyboard typematic rate & delay
|
|
||||||
mov al, 0xf3
|
|
||||||
out 0x60, al
|
|
||||||
xor cx, cx
|
|
||||||
@@:
|
|
||||||
in al, 64h
|
|
||||||
test al, 2
|
|
||||||
loopnz @b
|
|
||||||
mov al, 0
|
|
||||||
out 0x60, al
|
|
||||||
xor cx, cx
|
|
||||||
@@:
|
|
||||||
in al, 64h
|
|
||||||
test al, 2
|
|
||||||
loopnz @b
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; --------------- APM ---------------------
|
|
||||||
and word [es:0x9044], 0 ; ver = 0.0 (APM not found)
|
|
||||||
mov ax, 0x5300
|
|
||||||
xor bx, bx
|
|
||||||
int 0x15
|
|
||||||
jc apm_end ; APM not found
|
|
||||||
test cx, 2
|
|
||||||
jz apm_end ; APM 32-bit protected-mode interface not supported
|
|
||||||
mov [es:0x9044], ax ; Save APM Version
|
|
||||||
mov [es:0x9046], cx ; Save APM flags
|
|
||||||
|
|
||||||
; Write APM ver ----
|
|
||||||
and ax, 0xf0f
|
|
||||||
add ax, '00'
|
|
||||||
mov si, msg_apm
|
|
||||||
mov [si + 5], ah
|
|
||||||
mov [si + 7], al
|
|
||||||
_setcursor 0, 3
|
|
||||||
call printplain
|
|
||||||
; ------------------
|
|
||||||
|
|
||||||
mov ax, 0x5304 ; Disconnect interface
|
|
||||||
xor bx, bx
|
|
||||||
int 0x15
|
|
||||||
mov ax, 0x5303 ; Connect 32 bit mode interface
|
|
||||||
xor bx, bx
|
|
||||||
int 0x15
|
|
||||||
|
|
||||||
mov [es:0x9040], ebx
|
|
||||||
mov [es:0x9050], ax
|
|
||||||
mov [es:0x9052], cx
|
|
||||||
mov [es:0x9054], dx
|
|
||||||
|
|
||||||
apm_end:
|
|
||||||
_setcursor d80x25_top_num, 0
|
|
||||||
|
|
||||||
;CHECK current of code
|
|
||||||
cmp [cfgmanager.loader_block], -1
|
|
||||||
jz noloaderblock
|
|
||||||
les bx, [cfgmanager.loader_block]
|
|
||||||
cmp byte [es:bx], 1
|
|
||||||
mov si, loader_block_error
|
|
||||||
jnz sayerr
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
|
|
||||||
noloaderblock:
|
|
||||||
; DISPLAY VESA INFORMATION
|
|
||||||
call print_vesa_info
|
|
||||||
call calc_vmodes_table
|
|
||||||
call check_first_parm ;check and enable cursor_pos
|
|
||||||
|
|
||||||
|
|
||||||
; \begin{diamond}[30.11.2005]
|
|
||||||
cfgmanager:
|
|
||||||
; settings:
|
|
||||||
; a) preboot_graph = graphical mode
|
|
||||||
; preboot_gprobe = probe this mode?
|
|
||||||
; b) preboot_dma = use DMA access?
|
|
||||||
; c) preboot_vrrm = use VRR?
|
|
||||||
|
|
||||||
; determine default settings
|
|
||||||
mov [.bSettingsChanged], 0
|
|
||||||
|
|
||||||
;.preboot_gr_end:
|
|
||||||
mov di, preboot_device
|
|
||||||
; if image in memory is present and [preboot_device] is uninitialized,
|
|
||||||
; set it to use this preloaded image
|
|
||||||
cmp byte [di], 0
|
|
||||||
jnz .preboot_device_inited
|
|
||||||
cmp [.loader_block], -1
|
|
||||||
jz @f
|
|
||||||
les bx, [.loader_block]
|
|
||||||
test byte [es:bx+1], 1
|
|
||||||
jz @f
|
|
||||||
mov byte [di], 3
|
|
||||||
jmp .preboot_device_inited
|
|
||||||
@@:
|
|
||||||
; otherwise, set [preboot_device] to 1 (default value - boot from floppy)
|
|
||||||
mov byte [di], 1
|
|
||||||
.preboot_device_inited:
|
|
||||||
; following 6 lines set variables to 1 if its current value is 0
|
|
||||||
cmp byte [di+preboot_dma-preboot_device], 1
|
|
||||||
adc byte [di+preboot_dma-preboot_device], 0
|
|
||||||
cmp byte [di+preboot_biosdisk-preboot_device], 1
|
|
||||||
adc byte [di+preboot_biosdisk-preboot_device], 0
|
|
||||||
cmp byte [di+preboot_vrrm-preboot_device], 1
|
|
||||||
adc byte [di+preboot_vrrm-preboot_device], 0
|
|
||||||
; notify user
|
|
||||||
_setcursor 5,2
|
|
||||||
|
|
||||||
mov si, linef
|
|
||||||
call printplain
|
|
||||||
mov si, start_msg
|
|
||||||
call print
|
|
||||||
mov si, time_msg
|
|
||||||
call print
|
|
||||||
; get start time
|
|
||||||
call .gettime
|
|
||||||
mov [.starttime], eax
|
|
||||||
mov word [.timer], .newtimer
|
|
||||||
mov word [.timer+2], cs
|
|
||||||
.printcfg:
|
|
||||||
_setcursor 9,0
|
|
||||||
mov si, current_cfg_msg
|
|
||||||
call print
|
|
||||||
mov si, curvideo_msg
|
|
||||||
call print
|
|
||||||
|
|
||||||
call draw_current_vmode
|
|
||||||
|
|
||||||
mov si, usebd_msg
|
|
||||||
cmp [preboot_biosdisk], 1
|
|
||||||
call .say_on_off
|
|
||||||
mov si, vrrm_msg
|
|
||||||
cmp [preboot_vrrm], 1
|
|
||||||
call .say_on_off
|
|
||||||
; mov si, preboot_device_msg
|
|
||||||
; call print
|
|
||||||
; mov al, [preboot_device]
|
|
||||||
; and eax, 7
|
|
||||||
; mov si, [preboot_device_msgs+eax*2]
|
|
||||||
; call printplain
|
|
||||||
.show_remarks:
|
|
||||||
; show remarks in gray color
|
|
||||||
mov di, ((21-num_remarks)*80 + 2)*2
|
|
||||||
push 0xB800
|
|
||||||
pop es
|
|
||||||
mov cx, num_remarks
|
|
||||||
mov si, remarks
|
|
||||||
.write_remarks:
|
|
||||||
lodsw
|
|
||||||
push si
|
|
||||||
xchg ax, si
|
|
||||||
mov ah, 1*16+7 ; background: blue (1), foreground: gray (7)
|
|
||||||
push di
|
|
||||||
.write_remark:
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz @f
|
|
||||||
stosw
|
|
||||||
jmp .write_remark
|
|
||||||
@@:
|
|
||||||
pop di
|
|
||||||
pop si
|
|
||||||
add di, 80*2
|
|
||||||
loop .write_remarks
|
|
||||||
.wait:
|
|
||||||
_setcursor 25,0 ; out of screen
|
|
||||||
; set timer interrupt handler
|
|
||||||
cli
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
push dword [es:8*4]
|
|
||||||
pop dword [.oldtimer]
|
|
||||||
push dword [.timer]
|
|
||||||
pop dword [es:8*4]
|
|
||||||
; mov eax, [es:8*4]
|
|
||||||
; mov [.oldtimer], eax
|
|
||||||
; mov eax, [.timer]
|
|
||||||
; mov [es:8*4], eax
|
|
||||||
sti
|
|
||||||
; wait for keypressed
|
|
||||||
xor ax,ax
|
|
||||||
int 16h
|
|
||||||
push ax
|
|
||||||
; restore timer interrupt
|
|
||||||
; push 0
|
|
||||||
; pop es
|
|
||||||
mov eax, [.oldtimer]
|
|
||||||
mov [es:8*4], eax
|
|
||||||
mov [.timer], eax
|
|
||||||
_setcursor 7,0
|
|
||||||
mov si, space_msg
|
|
||||||
call printplain
|
|
||||||
; clear remarks and restore normal attributes
|
|
||||||
push es
|
|
||||||
mov di, ((21-num_remarks)*80 + 2)*2
|
|
||||||
push 0xB800
|
|
||||||
pop es
|
|
||||||
mov cx, num_remarks
|
|
||||||
mov ax, ' ' + (1*16 + 15)*100h
|
|
||||||
@@:
|
|
||||||
push cx
|
|
||||||
mov cx, 76
|
|
||||||
rep stosw
|
|
||||||
pop cx
|
|
||||||
add di, 4*2
|
|
||||||
loop @b
|
|
||||||
pop es
|
|
||||||
pop ax
|
|
||||||
; switch on key
|
|
||||||
cmp al, 13
|
|
||||||
jz .continue
|
|
||||||
or al, 20h
|
|
||||||
cmp al, 'a'
|
|
||||||
jz .change_a
|
|
||||||
cmp al, 'b'
|
|
||||||
jz .change_b
|
|
||||||
cmp al, 'c'
|
|
||||||
jnz .show_remarks
|
|
||||||
|
|
||||||
_setcursor 15,0
|
|
||||||
mov si, vrrmprint
|
|
||||||
call print
|
|
||||||
mov bx, '12'
|
|
||||||
call getkey
|
|
||||||
mov [preboot_vrrm], al
|
|
||||||
_setcursor 12,0
|
|
||||||
.d:
|
|
||||||
mov [.bSettingsChanged], 1
|
|
||||||
call clear_vmodes_table ;clear vmodes_table
|
|
||||||
jmp .printcfg
|
|
||||||
.change_a:
|
|
||||||
.loops:
|
|
||||||
call draw_vmodes_table
|
|
||||||
_setcursor 25,0 ; out of screen
|
|
||||||
xor ax,ax
|
|
||||||
int 0x16
|
|
||||||
; call clear_table_cursor ;clear current position of cursor
|
|
||||||
|
|
||||||
mov si,word [cursor_pos]
|
|
||||||
|
|
||||||
cmp ah,0x48;x,0x48E0 ; up
|
|
||||||
jne .down
|
|
||||||
cmp si,modes_table
|
|
||||||
jbe .loops
|
|
||||||
sub word [cursor_pos],size_of_step
|
|
||||||
jmp .loops
|
|
||||||
|
|
||||||
.down: cmp ah,0x50;x,0x50E0 ; down
|
|
||||||
jne .pgup
|
|
||||||
cmp word[es:si+10],-1
|
|
||||||
je .loops
|
|
||||||
add word [cursor_pos],size_of_step
|
|
||||||
jmp .loops
|
|
||||||
|
|
||||||
.pgup: cmp ah,0x49 ; page up
|
|
||||||
jne .pgdn
|
|
||||||
sub si, size_of_step*long_v_table
|
|
||||||
cmp si, modes_table
|
|
||||||
jae @f
|
|
||||||
mov si, modes_table
|
|
||||||
@@:
|
|
||||||
mov word [cursor_pos], si
|
|
||||||
mov si, word [home_cursor]
|
|
||||||
sub si, size_of_step*long_v_table
|
|
||||||
cmp si, modes_table
|
|
||||||
jae @f
|
|
||||||
mov si, modes_table
|
|
||||||
@@:
|
|
||||||
mov word [home_cursor], si
|
|
||||||
jmp .loops
|
|
||||||
|
|
||||||
.pgdn: cmp ah,0x51 ; page down
|
|
||||||
jne .enter
|
|
||||||
mov ax, [end_cursor]
|
|
||||||
add si, size_of_step*long_v_table
|
|
||||||
cmp si, ax
|
|
||||||
jb @f
|
|
||||||
mov si, ax
|
|
||||||
sub si, size_of_step
|
|
||||||
@@:
|
|
||||||
mov word [cursor_pos], si
|
|
||||||
mov si, word [home_cursor]
|
|
||||||
sub ax, size_of_step*long_v_table
|
|
||||||
add si, size_of_step*long_v_table
|
|
||||||
cmp si, ax
|
|
||||||
jb @f
|
|
||||||
mov si, ax
|
|
||||||
@@:
|
|
||||||
mov word [home_cursor], si
|
|
||||||
jmp .loops
|
|
||||||
|
|
||||||
.enter: cmp al,0x0D;x,0x1C0D ; enter
|
|
||||||
jne .loops
|
|
||||||
push word [cursor_pos]
|
|
||||||
pop bp
|
|
||||||
push word [es:bp]
|
|
||||||
pop word [x_save]
|
|
||||||
push word [es:bp+2]
|
|
||||||
pop word [y_save]
|
|
||||||
push word [es:bp+6]
|
|
||||||
pop word [number_vm]
|
|
||||||
mov word [preboot_graph],bp ;save choose
|
|
||||||
|
|
||||||
jmp .d
|
|
||||||
|
|
||||||
.change_b:
|
|
||||||
_setcursor 15,0
|
|
||||||
; mov si, ask_dma
|
|
||||||
; call print
|
|
||||||
; mov bx, '13'
|
|
||||||
; call getkey
|
|
||||||
; mov [preboot_dma], al
|
|
||||||
mov si, ask_bd
|
|
||||||
call print
|
|
||||||
mov bx, '12'
|
|
||||||
call getkey
|
|
||||||
mov [preboot_biosdisk], al
|
|
||||||
_setcursor 11,0
|
|
||||||
jmp .d
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
.say_on_off:
|
|
||||||
pushf
|
|
||||||
call print
|
|
||||||
mov si, on_msg
|
|
||||||
popf
|
|
||||||
jz @f
|
|
||||||
mov si, off_msg
|
|
||||||
@@: jmp printplain
|
|
||||||
; novesa and vervesa strings are not used at the moment of executing this code
|
|
||||||
virtual at novesa
|
|
||||||
.oldtimer dd ?
|
|
||||||
.starttime dd ?
|
|
||||||
.bSettingsChanged db ?
|
|
||||||
.timer dd ?
|
|
||||||
end virtual
|
|
||||||
.loader_block dd -1
|
|
||||||
.gettime:
|
|
||||||
mov ah, 0
|
|
||||||
int 1Ah
|
|
||||||
xchg ax, cx
|
|
||||||
shl eax, 10h
|
|
||||||
xchg ax, dx
|
|
||||||
ret
|
|
||||||
.newtimer:
|
|
||||||
push ds
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
pushf
|
|
||||||
call [.oldtimer]
|
|
||||||
pushad
|
|
||||||
call .gettime
|
|
||||||
sub eax, [.starttime]
|
|
||||||
sub ax, 18*5
|
|
||||||
jae .timergo
|
|
||||||
neg ax
|
|
||||||
add ax, 18-1
|
|
||||||
mov bx, 18
|
|
||||||
xor dx, dx
|
|
||||||
div bx
|
|
||||||
if lang eq ru
|
|
||||||
; ¯®¤®¦¤¨â¥ 5 ᥪã¤, 4/3/2 ᥪã¤ë, 1 ᥪã¤ã
|
|
||||||
cmp al, 5
|
|
||||||
mov cl, ' '
|
|
||||||
jae @f
|
|
||||||
cmp al, 1
|
|
||||||
mov cl, 'ã'
|
|
||||||
jz @f
|
|
||||||
mov cl, 'ë'
|
|
||||||
@@: mov [time_str+9], cl
|
|
||||||
else if lang eq et
|
|
||||||
cmp al, 1
|
|
||||||
ja @f
|
|
||||||
mov [time_str+9], ' '
|
|
||||||
mov [time_str+10],' '
|
|
||||||
@@:
|
|
||||||
else
|
|
||||||
; wait 5/4/3/2 seconds, 1 second
|
|
||||||
cmp al, 1
|
|
||||||
mov cl, 's'
|
|
||||||
ja @f
|
|
||||||
mov cl, ' '
|
|
||||||
@@: mov [time_str+9], cl
|
|
||||||
end if
|
|
||||||
add al, '0'
|
|
||||||
mov [time_str+1], al
|
|
||||||
mov si, time_msg
|
|
||||||
_setcursor 7,0
|
|
||||||
call print
|
|
||||||
_setcursor 25,0
|
|
||||||
popad
|
|
||||||
pop ds
|
|
||||||
iret
|
|
||||||
.timergo:
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
mov eax, [.oldtimer]
|
|
||||||
mov [es:8*4], eax
|
|
||||||
mov sp, 0EC00h
|
|
||||||
.continue:
|
|
||||||
sti
|
|
||||||
_setcursor 6,0
|
|
||||||
mov si, space_msg
|
|
||||||
call printplain
|
|
||||||
call printplain
|
|
||||||
_setcursor 6,0
|
|
||||||
mov si, loading_msg
|
|
||||||
call print
|
|
||||||
_setcursor 15,0
|
|
||||||
cmp [.bSettingsChanged], 0
|
|
||||||
jz .load
|
|
||||||
cmp [.loader_block], -1
|
|
||||||
jz .load
|
|
||||||
les bx, [.loader_block]
|
|
||||||
mov eax, [es:bx+3]
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
test eax, eax
|
|
||||||
jz .load
|
|
||||||
push eax
|
|
||||||
mov si, save_quest
|
|
||||||
call print
|
|
||||||
.waityn:
|
|
||||||
mov ah, 0
|
|
||||||
int 16h
|
|
||||||
or al, 20h
|
|
||||||
cmp al, 'n'
|
|
||||||
jz .loadc
|
|
||||||
cmp al, 'y'
|
|
||||||
jnz .waityn
|
|
||||||
call putchar
|
|
||||||
mov byte [space_msg+80], 186
|
|
||||||
pop eax
|
|
||||||
push cs
|
|
||||||
push .cont
|
|
||||||
push eax
|
|
||||||
retf
|
|
||||||
.loadc:
|
|
||||||
pop eax
|
|
||||||
.cont:
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
mov si, space_msg
|
|
||||||
mov byte [si+80], 0
|
|
||||||
_setcursor 15,0
|
|
||||||
call printplain
|
|
||||||
_setcursor 15,0
|
|
||||||
.load:
|
|
||||||
; \end{diamond}[02.12.2005]
|
|
||||||
|
|
||||||
; ASK GRAPHICS MODE
|
|
||||||
|
|
||||||
call set_vmode
|
|
||||||
|
|
||||||
; GRAPHICS ACCELERATION
|
|
||||||
; force yes
|
|
||||||
mov [es:0x901C], byte 1
|
|
||||||
|
|
||||||
; DMA ACCESS TO HD
|
|
||||||
|
|
||||||
mov al, [preboot_dma]
|
|
||||||
mov [es:0x901F], al
|
|
||||||
|
|
||||||
; VRR_M USE
|
|
||||||
|
|
||||||
mov al,[preboot_vrrm]
|
|
||||||
mov [es:0x9030], al
|
|
||||||
mov [es:0x901E], byte 1
|
|
||||||
|
|
||||||
; BOOT DEVICE
|
|
||||||
|
|
||||||
mov al, [preboot_device]
|
|
||||||
dec al
|
|
||||||
mov [boot_dev], al
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;; set videomode
|
|
||||||
xor ax, ax
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
mov ax, [es:0x9008] ; vga & 320x200
|
|
||||||
mov bx, ax
|
|
||||||
cmp ax, 0x13
|
|
||||||
je setgr
|
|
||||||
cmp ax, 0x12
|
|
||||||
je setgr
|
|
||||||
mov ax, 0x4f02 ; Vesa
|
|
||||||
setgr:
|
|
||||||
int 0x10
|
|
||||||
test ah, ah
|
|
||||||
mov si, fatalsel
|
|
||||||
jnz v_mode_error
|
|
||||||
; set mode 0x12 graphics registers:
|
|
||||||
cmp bx, 0x12
|
|
||||||
jne gmok2
|
|
||||||
|
|
||||||
mov al, 0x05
|
|
||||||
mov dx, 0x03ce
|
|
||||||
push dx
|
|
||||||
out dx, al ; select GDC mode register
|
|
||||||
mov al, 0x02
|
|
||||||
inc dx
|
|
||||||
out dx, al ; set write mode 2
|
|
||||||
|
|
||||||
mov al, 0x02
|
|
||||||
mov dx, 0x03c4
|
|
||||||
out dx, al ; select VGA sequencer map mask register
|
|
||||||
mov al, 0x0f
|
|
||||||
inc dx
|
|
||||||
out dx, al ; set mask for all planes 0-3
|
|
||||||
|
|
||||||
mov al, 0x08
|
|
||||||
pop dx
|
|
||||||
out dx, al ; select GDC bit mask register
|
|
||||||
; for writes to 0x03cf
|
|
||||||
gmok2:
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;data
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
include "lang.inc"
|
|
||||||
include "bootstr.inc" ; language-independent boot messages
|
|
||||||
;if lang eq en
|
|
||||||
;include "booteng.inc" ; english system boot messages
|
|
||||||
;else if lang eq ru
|
|
||||||
include "bootru.inc" ; russian system boot messages
|
|
||||||
include "ru.inc" ; Russian font
|
|
||||||
;else if lang eq et
|
|
||||||
;include "bootet.inc" ; estonian system boot messages
|
|
||||||
;include "et.inc" ; Estonian font
|
|
||||||
;else
|
|
||||||
;include "bootge.inc" ; german system boot messages
|
|
||||||
;end if
|
|
||||||
|
|
||||||
include 'macros.inc'
|
|
||||||
include 'bootvesa.inc'
|
|
||||||
|
|
||||||
include "preboot.inc"
|
|
||||||
|
|
||||||
|
|
||||||
setcursor:
|
|
||||||
; in: dl=column, dh=row
|
|
||||||
mov ah, 2
|
|
||||||
mov bh, 0
|
|
||||||
int 10h
|
|
||||||
ret
|
|
||||||
|
|
||||||
putchar:
|
|
||||||
; in: al=character
|
|
||||||
mov ah, 0Eh
|
|
||||||
mov bh, 0
|
|
||||||
int 10h
|
|
||||||
ret
|
|
||||||
|
|
||||||
print:
|
|
||||||
; in: si->string
|
|
||||||
mov al, 186
|
|
||||||
call putchar
|
|
||||||
mov al, ' '
|
|
||||||
call putchar
|
|
||||||
|
|
||||||
printplain:
|
|
||||||
; in: si->string
|
|
||||||
pusha
|
|
||||||
lodsb
|
|
||||||
@@:
|
|
||||||
call putchar
|
|
||||||
lodsb
|
|
||||||
cmp al, 0
|
|
||||||
jnz @b
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
getkey:
|
|
||||||
; get number in range [bl,bh] (bl,bh in ['0'..'9'])
|
|
||||||
; in: bx=range
|
|
||||||
; out: ax=digit (1..9, 10 for 0)
|
|
||||||
mov ah, 0
|
|
||||||
int 16h
|
|
||||||
cmp al, bl
|
|
||||||
jb getkey
|
|
||||||
cmp al, bh
|
|
||||||
ja getkey
|
|
||||||
push ax
|
|
||||||
call putchar
|
|
||||||
pop ax
|
|
||||||
and ax, 0Fh
|
|
||||||
jnz @f
|
|
||||||
mov al, 10
|
|
||||||
@@:
|
|
||||||
ret
|
|
@ -1,86 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
; structure definition helper
|
|
||||||
macro struct name, [arg]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
name@struct equ name
|
|
||||||
struc name arg {
|
|
||||||
}
|
|
||||||
|
|
||||||
macro struct_helper name
|
|
||||||
{
|
|
||||||
match xname,name
|
|
||||||
\{
|
|
||||||
virtual at 0
|
|
||||||
xname xname
|
|
||||||
sizeof.#xname = $ - xname
|
|
||||||
name equ sizeof.#xname
|
|
||||||
end virtual
|
|
||||||
\}
|
|
||||||
}
|
|
||||||
|
|
||||||
ends fix } struct_helper name@struct
|
|
||||||
|
|
||||||
;// mike.dld, 2006-29-01 [
|
|
||||||
|
|
||||||
; macros definition
|
|
||||||
macro diff16 title,l1,l2
|
|
||||||
{
|
|
||||||
local s,d
|
|
||||||
s = l2-l1
|
|
||||||
display title,': 0x'
|
|
||||||
repeat 16
|
|
||||||
d = 48 + s shr ((16-%) shl 2) and $0F
|
|
||||||
if d > 57
|
|
||||||
d = d + 65-57-1
|
|
||||||
end if
|
|
||||||
display d
|
|
||||||
end repeat
|
|
||||||
display 13,10
|
|
||||||
}
|
|
||||||
macro diff10 title,l1,l2
|
|
||||||
{
|
|
||||||
local s,d,z,m
|
|
||||||
s = l2-l1
|
|
||||||
z = 0
|
|
||||||
m = 1000000000
|
|
||||||
display title,': '
|
|
||||||
repeat 10
|
|
||||||
d = '0' + s / m
|
|
||||||
s = s - (s/m)*m
|
|
||||||
m = m / 10
|
|
||||||
if d <> '0'
|
|
||||||
z = 1
|
|
||||||
end if
|
|
||||||
if z <> 0
|
|
||||||
display d
|
|
||||||
end if
|
|
||||||
end repeat
|
|
||||||
display 13,10
|
|
||||||
}
|
|
||||||
|
|
||||||
; \begin{diamond}[29.09.2006]
|
|
||||||
; may be useful for kernel debugging
|
|
||||||
; example 1:
|
|
||||||
; dbgstr 'Hello, World!'
|
|
||||||
; example 2:
|
|
||||||
; dbgstr 'Hello, World!', save_flags
|
|
||||||
macro dbgstr string*, f
|
|
||||||
{
|
|
||||||
local a
|
|
||||||
iglobal_nested
|
|
||||||
a db 'K : ',string,13,10,0
|
|
||||||
endg_nested
|
|
||||||
if ~ f eq
|
|
||||||
pushfd
|
|
||||||
end if
|
|
||||||
push esi
|
|
||||||
mov esi, a
|
|
||||||
call sys_msg_board_str
|
|
||||||
pop esi
|
|
||||||
if ~ f eq
|
|
||||||
popfd
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
; \end{diamond}[29.09.2006]
|
|
@ -1,36 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
display_modechg db 0 ; display mode change for text, yes/no (0 or 2)
|
|
||||||
;
|
|
||||||
; !! Important note !!
|
|
||||||
;
|
|
||||||
; Must be set to 2, to avoid two screenmode
|
|
||||||
; changes within a very short period of time.
|
|
||||||
|
|
||||||
display_atboot db 0 ; show boot screen messages ( 2-no )
|
|
||||||
|
|
||||||
preboot_graph dw 0 ; graph mode
|
|
||||||
x_save dw 0 ; x
|
|
||||||
y_save dw 0 ; y
|
|
||||||
number_vm dw 0 ;
|
|
||||||
;pixel_save dw 0 ; per to pixel
|
|
||||||
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
|
|
||||||
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
|
|
||||||
preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never)
|
|
||||||
preboot_device db 0 ; boot device
|
|
||||||
; (1-floppy 2-harddisk 3-kernel restart 4-format ram disk)
|
|
||||||
;!!!! 0 - autodetect !!!!
|
|
||||||
preboot_blogesc = 0 ; start immediately after bootlog
|
|
||||||
preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no)
|
|
||||||
|
|
||||||
; if $>0x200
|
|
||||||
;ERROR: prebooting parameters must fit in first sector!!!
|
|
||||||
; end if
|
|
||||||
;hdsysimage db 'KOLIBRI IMG' ; load from
|
|
||||||
;image_save db 'KOLIBRI IMG' ; save to
|
|
@ -1,123 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
; READ RAMDISK IMAGE FROM HD
|
|
||||||
|
|
||||||
cmp [boot_dev+OS_BASE+0x10000],1
|
|
||||||
jne no_sys_on_hd
|
|
||||||
|
|
||||||
test [DRIVE_DATA+1],byte 0x40
|
|
||||||
jz position_2
|
|
||||||
mov [hdbase],0x1f0
|
|
||||||
mov [hdid],0x0
|
|
||||||
mov [hdpos],1
|
|
||||||
mov [fat32part],0
|
|
||||||
position_1_1:
|
|
||||||
inc [fat32part]
|
|
||||||
call search_and_read_image
|
|
||||||
cmp [image_retrieved],1
|
|
||||||
je yes_sys_on_hd
|
|
||||||
movzx eax,byte [DRIVE_DATA+2]
|
|
||||||
cmp [fat32part],eax
|
|
||||||
jle position_1_1
|
|
||||||
position_2:
|
|
||||||
test [DRIVE_DATA+1],byte 0x10
|
|
||||||
jz position_3
|
|
||||||
mov [hdbase],0x1f0
|
|
||||||
mov [hdid],0x10
|
|
||||||
mov [hdpos],2
|
|
||||||
mov [fat32part],0
|
|
||||||
position_2_1:
|
|
||||||
inc [fat32part]
|
|
||||||
call search_and_read_image
|
|
||||||
cmp [image_retrieved],1
|
|
||||||
je yes_sys_on_hd
|
|
||||||
movzx eax,byte [DRIVE_DATA+3]
|
|
||||||
cmp eax,[fat32part]
|
|
||||||
jle position_2_1
|
|
||||||
position_3:
|
|
||||||
test [DRIVE_DATA+1],byte 0x4
|
|
||||||
jz position_4
|
|
||||||
mov [hdbase],0x170
|
|
||||||
mov [hdid],0x0
|
|
||||||
mov [hdpos],3
|
|
||||||
mov [fat32part],0
|
|
||||||
position_3_1:
|
|
||||||
inc [fat32part]
|
|
||||||
call search_and_read_image
|
|
||||||
cmp [image_retrieved],1
|
|
||||||
je yes_sys_on_hd
|
|
||||||
movzx eax,byte [DRIVE_DATA+4]
|
|
||||||
cmp eax,[fat32part]
|
|
||||||
jle position_3_1
|
|
||||||
position_4:
|
|
||||||
test [DRIVE_DATA+1],byte 0x1
|
|
||||||
jz no_sys_on_hd
|
|
||||||
mov [hdbase],0x170
|
|
||||||
mov [hdid],0x10
|
|
||||||
mov [hdpos],4
|
|
||||||
mov [fat32part],0
|
|
||||||
position_4_1:
|
|
||||||
inc [fat32part]
|
|
||||||
call search_and_read_image
|
|
||||||
cmp [image_retrieved],1
|
|
||||||
je yes_sys_on_hd
|
|
||||||
movzx eax,byte [DRIVE_DATA+5]
|
|
||||||
cmp eax,[fat32part]
|
|
||||||
jle position_4_1
|
|
||||||
jmp yes_sys_on_hd
|
|
||||||
|
|
||||||
search_and_read_image:
|
|
||||||
call set_FAT32_variables
|
|
||||||
mov edx, bootpath
|
|
||||||
call read_image
|
|
||||||
test eax, eax
|
|
||||||
jz image_present
|
|
||||||
mov edx, bootpath2
|
|
||||||
call read_image
|
|
||||||
test eax, eax
|
|
||||||
jz image_present
|
|
||||||
ret
|
|
||||||
image_present:
|
|
||||||
mov [image_retrieved],1
|
|
||||||
ret
|
|
||||||
|
|
||||||
read_image:
|
|
||||||
mov eax, hdsysimage+OS_BASE+0x10000
|
|
||||||
mov ebx, 1474560/512
|
|
||||||
mov ecx, RAMDISK
|
|
||||||
mov esi, 0
|
|
||||||
mov edi, 12
|
|
||||||
call file_read
|
|
||||||
ret
|
|
||||||
|
|
||||||
image_retrieved db 0
|
|
||||||
counter_of_partitions db 0
|
|
||||||
no_sys_on_hd:
|
|
||||||
; test_to_format_ram_disk (need if not using ram disk)
|
|
||||||
cmp [boot_dev+OS_BASE+0x10000],3
|
|
||||||
jne not_format_ram_disk
|
|
||||||
; format_ram_disk
|
|
||||||
mov edi, RAMDISK
|
|
||||||
mov ecx, 0x1080
|
|
||||||
xor eax,eax
|
|
||||||
@@:
|
|
||||||
stosd
|
|
||||||
loop @b
|
|
||||||
|
|
||||||
mov ecx, 0x58F7F
|
|
||||||
mov eax,0xF6F6F6F6
|
|
||||||
@@:
|
|
||||||
stosd
|
|
||||||
loop @b
|
|
||||||
|
|
||||||
mov [RAMDISK+0x200],dword 0xFFFFF0 ; fat table
|
|
||||||
mov [RAMDISK+0x4200],dword 0xFFFFF0
|
|
||||||
|
|
||||||
not_format_ram_disk:
|
|
||||||
yes_sys_on_hd:
|
|
@ -1,100 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
; Generated by RUFNT.EXE
|
|
||||||
; By BadBugsKiller (C)
|
|
||||||
; Modifyed by BadBugsKiller 12.01.2004 17:45
|
|
||||||
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé,
|
|
||||||
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà.
|
|
||||||
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòðàíèöà 866.
|
|
||||||
RU_FNT1:
|
|
||||||
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
|
|
||||||
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
|
|
||||||
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
|
|
||||||
RU_FNT2:
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
|
|
||||||
|
|
||||||
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
|
|
||||||
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
@ -1,207 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;; Shutdown for Menuet ;;
|
|
||||||
;; ;;
|
|
||||||
;; Distributed under General Public License ;;
|
|
||||||
;; See file COPYING for details. ;;
|
|
||||||
;; Copyright 2003 Ville Turjanmaa ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
align 4
|
|
||||||
pr_mode_exit:
|
|
||||||
|
|
||||||
; setup stack
|
|
||||||
mov ax, 0x3000
|
|
||||||
mov ss, ax
|
|
||||||
mov esp, 0x0EC00
|
|
||||||
; setup ds
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
lidt [old_ints_h]
|
|
||||||
;remap IRQs
|
|
||||||
mov al,0x11
|
|
||||||
out 0x20,al
|
|
||||||
call rdelay
|
|
||||||
out 0xA0,al
|
|
||||||
call rdelay
|
|
||||||
|
|
||||||
mov al,0x08
|
|
||||||
out 0x21,al
|
|
||||||
call rdelay
|
|
||||||
mov al,0x70
|
|
||||||
out 0xA1,al
|
|
||||||
call rdelay
|
|
||||||
|
|
||||||
mov al,0x04
|
|
||||||
out 0x21,al
|
|
||||||
call rdelay
|
|
||||||
mov al,0x02
|
|
||||||
out 0xA1,al
|
|
||||||
call rdelay
|
|
||||||
|
|
||||||
mov al,0x01
|
|
||||||
out 0x21,al
|
|
||||||
call rdelay
|
|
||||||
out 0xA1,al
|
|
||||||
call rdelay
|
|
||||||
|
|
||||||
mov al,0xB8
|
|
||||||
out 0x21,al
|
|
||||||
call rdelay
|
|
||||||
mov al,0xBD
|
|
||||||
out 0xA1,al
|
|
||||||
sti
|
|
||||||
|
|
||||||
temp_3456:
|
|
||||||
xor ax,ax
|
|
||||||
mov es,ax
|
|
||||||
mov al,byte [es:0x9030]
|
|
||||||
cmp al,1
|
|
||||||
jl nbw
|
|
||||||
cmp al,4
|
|
||||||
jle nbw32
|
|
||||||
|
|
||||||
nbw:
|
|
||||||
in al,0x60
|
|
||||||
cmp al,6
|
|
||||||
jae nbw
|
|
||||||
mov bl,al
|
|
||||||
nbw2:
|
|
||||||
in al,0x60
|
|
||||||
cmp al,bl
|
|
||||||
je nbw2
|
|
||||||
cmp al,240 ;ax,240
|
|
||||||
jne nbw31
|
|
||||||
mov al,bl
|
|
||||||
dec ax
|
|
||||||
jmp nbw32
|
|
||||||
nbw31:
|
|
||||||
add bl,128
|
|
||||||
cmp al,bl
|
|
||||||
jne nbw
|
|
||||||
sub al,129
|
|
||||||
|
|
||||||
nbw32:
|
|
||||||
|
|
||||||
dec ax
|
|
||||||
dec ax ; 2 = power off
|
|
||||||
jnz no_apm_off
|
|
||||||
call APM_PowerOff
|
|
||||||
jmp $
|
|
||||||
no_apm_off:
|
|
||||||
|
|
||||||
dec ax ; 3 = reboot
|
|
||||||
jnz restart_kernel ; 4 = restart kernel
|
|
||||||
push 0x40
|
|
||||||
pop ds
|
|
||||||
mov word[0x0072],0x1234
|
|
||||||
jmp 0xF000:0xFFF0
|
|
||||||
|
|
||||||
|
|
||||||
rdelay:
|
|
||||||
ret
|
|
||||||
|
|
||||||
APM_PowerOff:
|
|
||||||
mov ax, 5304h
|
|
||||||
xor bx, bx
|
|
||||||
int 15h
|
|
||||||
;!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
mov ax,0x5300
|
|
||||||
xor bx,bx
|
|
||||||
int 0x15
|
|
||||||
push ax
|
|
||||||
|
|
||||||
mov ax,0x5301
|
|
||||||
xor bx,bx
|
|
||||||
int 0x15
|
|
||||||
|
|
||||||
mov ax,0x5308
|
|
||||||
mov bx,1
|
|
||||||
mov cx,bx
|
|
||||||
int 0x15
|
|
||||||
|
|
||||||
mov ax,0x530E
|
|
||||||
xor bx,bx
|
|
||||||
pop cx
|
|
||||||
int 0x15
|
|
||||||
|
|
||||||
mov ax,0x530D
|
|
||||||
mov bx,1
|
|
||||||
mov cx,bx
|
|
||||||
int 0x15
|
|
||||||
|
|
||||||
mov ax,0x530F
|
|
||||||
mov bx,1
|
|
||||||
mov cx,bx
|
|
||||||
int 0x15
|
|
||||||
|
|
||||||
mov ax,0x5307
|
|
||||||
mov bx,1
|
|
||||||
mov cx,3
|
|
||||||
int 0x15
|
|
||||||
;!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
ret
|
|
||||||
|
|
||||||
restart_kernel:
|
|
||||||
|
|
||||||
mov ax,0x0003 ; set text mode for screen
|
|
||||||
int 0x10
|
|
||||||
jmp 0x4000:0000
|
|
||||||
|
|
||||||
restart_kernel_4000:
|
|
||||||
cli
|
|
||||||
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
mov cx, 0x8000
|
|
||||||
push cx
|
|
||||||
push 0x7000
|
|
||||||
pop ds
|
|
||||||
xor si, si
|
|
||||||
xor di, di
|
|
||||||
rep movsw
|
|
||||||
pop cx
|
|
||||||
mov ds, cx
|
|
||||||
push 0x2000
|
|
||||||
pop es
|
|
||||||
rep movsw
|
|
||||||
push 0x9000
|
|
||||||
pop ds
|
|
||||||
push 0x3000
|
|
||||||
pop es
|
|
||||||
mov cx, 0xE000/2
|
|
||||||
rep movsw
|
|
||||||
|
|
||||||
wbinvd ; write and invalidate cache
|
|
||||||
|
|
||||||
mov al, 00110100b
|
|
||||||
out 43h, al
|
|
||||||
jcxz $+2
|
|
||||||
mov al, 0xFF
|
|
||||||
out 40h, al
|
|
||||||
jcxz $+2
|
|
||||||
out 40h, al
|
|
||||||
jcxz $+2
|
|
||||||
sti
|
|
||||||
|
|
||||||
; (hint by Black_mirror)
|
|
||||||
; We must read data from keyboard port,
|
|
||||||
; because there may be situation when previous keyboard interrupt is lost
|
|
||||||
; (due to return to real mode and IRQ reprogramming)
|
|
||||||
; and next interrupt will not be generated (as keyboard waits for handling)
|
|
||||||
in al, 0x60
|
|
||||||
|
|
||||||
; bootloader interface
|
|
||||||
push 0x1000
|
|
||||||
pop ds
|
|
||||||
mov si, kernel_restart_bootblock
|
|
||||||
mov ax, 'KL'
|
|
||||||
jmp 0x1000:0000
|
|
||||||
|
|
||||||
|
|
@ -1,635 +0,0 @@
|
|||||||
; Listing generator
|
|
||||||
; LocoDelAssembly 2007.06.01
|
|
||||||
|
|
||||||
INSTRUCTIONS equ bt in ja jb jc je jg jl jo jp js jz or \
|
|
||||||
aaa aad aam aas adc add and bsf bsr btc btr bts cbw cdq clc \
|
|
||||||
cld cli cmc cmp cqo cwd daa das dec div fld fst hlt inc ins \
|
|
||||||
int jae jbe jge jle jmp jna jnb jnc jne jng jnl jno jnp jns \
|
|
||||||
jnz jpe jpo lar lds lea les lfs lgs lsl lss ltr mov mul neg \
|
|
||||||
nop not out pop por rcl rcr ret rol ror rsm sal sar sbb shl \
|
|
||||||
shr stc std sti str sub ud2 xor \
|
|
||||||
arpl call cdqe clgi clts cmps cwde emms fabs fadd fbld fchs \
|
|
||||||
fcom fcos fdiv feni fild fist fld1 fldz fmul fnop fsin fstp \
|
|
||||||
fsub ftst fxam fxch idiv imul insb insd insw int1 int3 into \
|
|
||||||
invd iret jcxz jnae jnbe jnge jnle lahf lgdt lidt lldt lmsw \
|
|
||||||
lods loop movd movq movs orpd orps outs pand popa popd popf \
|
|
||||||
popq popw push pxor retd retf retn retq retw sahf salc scas \
|
|
||||||
seta setb setc sete setg setl seto setp sets setz sgdt shld \
|
|
||||||
shrd sidt sldt smsw stgi stos test verr verw wait xadd xchg \
|
|
||||||
xlat \
|
|
||||||
addpd addps addsd addss andpd andps bound bswap cmova cmovb \
|
|
||||||
cmovc cmove cmovg cmovl cmovo cmovp cmovs cmovz cmppd cmpps \
|
|
||||||
cmpsb cmpsd cmpsq cmpss cmpsw cpuid divpd divps divsd divss \
|
|
||||||
enter f2xm1 faddp fbstp fclex fcomi fcomp fdisi fdivp fdivr \
|
|
||||||
femms ffree fiadd ficom fidiv fimul finit fistp fisub fldcw \
|
|
||||||
fldpi fmulp fneni fprem fptan fsave fsqrt fstcw fstsw fsubp \
|
|
||||||
fsubr fucom fwait fyl2x icebp iretd iretq iretw jecxz jrcxz \
|
|
||||||
lddqu leave lodsb lodsd lodsq lodsw loopd loope loopq loopw \
|
|
||||||
loopz maxpd maxps maxsd maxss minpd minps minsd minss movsb \
|
|
||||||
movsd movsq movss movsw movsx movzx mulpd mulps mulsd mulss \
|
|
||||||
mwait outsb outsd outsw pabsb pabsd pabsw paddb paddd paddq \
|
|
||||||
paddw pandn pause pavgb pavgw pf2id pf2iw pfacc pfadd pfmax \
|
|
||||||
pfmin pfmul pfrcp pfsub pi2fd pi2fw popad popaw popfd popfq \
|
|
||||||
popfw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb \
|
|
||||||
psubd psubq psubw pusha pushd pushf pushq pushw rcpps rcpss \
|
|
||||||
rdmsr rdpmc rdtsc retfd retfq retfw retnd retnq retnw scasb \
|
|
||||||
scasd scasq scasw setae setbe setge setle setna setnb setnc \
|
|
||||||
setne setng setnl setno setnp setns setnz setpe setpo stosb \
|
|
||||||
stosd stosq stosw subpd subps subsd subss vmrun vmxon wrmsr \
|
|
||||||
xlatb xorpd xorps \
|
|
||||||
andnpd andnps cmovae cmovbe cmovge cmovle cmovna cmovnb cmovnc\
|
|
||||||
cmovne cmovng cmovnl cmovno cmovnp cmovns cmovnz cmovpe cmovpo\
|
|
||||||
comisd comiss fcmovb fcmove fcmovu fcomip fcompp fdivrp ffreep\
|
|
||||||
ficomp fidivr fisttp fisubr fldenv fldl2e fldl2t fldlg2 fldln2\
|
|
||||||
fnclex fndisi fninit fnsave fnstcw fnstsw fpatan fprem1 frstor\
|
|
||||||
frstpm fscale fsetpm fstenv fsubrp fucomi fucomp fxsave haddpd\
|
|
||||||
haddps hsubpd hsubps invlpg lfence looped loopeq loopew loopne\
|
|
||||||
loopnz loopzd loopzq loopzw mfence movapd movaps movdqa movdqu\
|
|
||||||
movhpd movhps movlpd movlps movnti movntq movsxd movupd movups\
|
|
||||||
paddsb paddsw pextrw pfnacc pfsubr phaddd phaddw phsubd phsubw\
|
|
||||||
pinsrw pmaxsw pmaxub pminsw pminub pmulhw pmullw psadbw pshufb\
|
|
||||||
pshufd pshufw psignb psignd psignw pslldq psrldq psubsb psubsw\
|
|
||||||
pswapd pushad pushaw pushfd pushfq pushfw rdmsrq rdtscp setalc\
|
|
||||||
setnae setnbe setnge setnle sfence shufpd shufps skinit sqrtpd\
|
|
||||||
sqrtps sqrtsd sqrtss swapgs sysret vmcall vmload vmread vmsave\
|
|
||||||
vmxoff wbinvd wrmsrq \
|
|
||||||
clflush cmovnae cmovnbe cmovnge cmovnle cmpeqpd cmpeqps \
|
|
||||||
cmpeqsd cmpeqss cmplepd cmpleps cmplesd cmpless cmpltpd \
|
|
||||||
cmpltps cmpltsd cmpltss cmpxchg fcmovbe fcmovnb fcmovne \
|
|
||||||
fcmovnu fdecstp fincstp fnstenv frndint fsincos fucomip \
|
|
||||||
fucompp fxrstor fxtract fyl2xp1 invlpga ldmxcsr loopned \
|
|
||||||
loopneq loopnew loopnzd loopnzq loopnzw monitor movddup \
|
|
||||||
movdq2q movhlps movlhps movntdq movntpd movntps movq2dq \
|
|
||||||
paddusb paddusw palignr pavgusb pcmpeqb pcmpeqd pcmpeqw \
|
|
||||||
pcmpgtb pcmpgtd pcmpgtw pfcmpeq pfcmpge pfcmpgt pfpnacc \
|
|
||||||
pfrsqrt phaddsw phsubsw pmaddwd pmulhrw pmulhuw pmuludq \
|
|
||||||
pshufhw pshuflw psubusb psubusw rsqrtps rsqrtss stmxcsr \
|
|
||||||
syscall sysexit sysretq ucomisd ucomiss vmclear vmmcall \
|
|
||||||
vmptrld vmptrst vmwrite \
|
|
||||||
addsubpd addsubps cmpneqpd cmpneqps cmpneqsd cmpneqss cmpnlepd\
|
|
||||||
cmpnleps cmpnlesd cmpnless cmpnltpd cmpnltps cmpnltsd cmpnltss\
|
|
||||||
cmpordpd cmpordps cmpordsd cmpordss cvtdq2pd cvtdq2ps cvtpd2dq\
|
|
||||||
cvtpd2pi cvtpd2ps cvtpi2pd cvtpi2ps cvtps2dq cvtps2pd cvtps2pi\
|
|
||||||
cvtsd2si cvtsd2ss cvtsi2sd cvtsi2ss cvtss2sd cvtss2si fcmovnbe\
|
|
||||||
maskmovq movmskpd movmskps movshdup movsldup packssdw packsswb\
|
|
||||||
packuswb pfrcpit1 pfrcpit2 pfrsqit1 pmovmskb pmulhrsw prefetch\
|
|
||||||
sysenter sysexitq unpckhpd unpckhps unpcklpd unpcklps vmlaunch\
|
|
||||||
vmresume \
|
|
||||||
cmpxchg8b cvttpd2dq cvttpd2pi cvttps2dq cvttps2pi cvttsd2si \
|
|
||||||
cvttss2si pmaddubsw prefetchw punpckhbw punpckhdq punpckhwd \
|
|
||||||
punpcklbw punpckldq punpcklwd \
|
|
||||||
cmpunordpd cmpunordps cmpunordsd cmpunordss cmpxchg16b \
|
|
||||||
loadall286 loadall386 maskmovdqu prefetcht0 prefetcht1 \
|
|
||||||
prefetcht2 punpckhqdq punpcklqdq prefetchnta
|
|
||||||
|
|
||||||
PREFIXES equ rep lock repe repz repne repnz
|
|
||||||
|
|
||||||
DATA_DEFINITORS equ db dw du dd dp df dq dt file
|
|
||||||
DATA_RESERVERS equ rb rw rd rp rf rq rt
|
|
||||||
|
|
||||||
CRLF equ 13, 10 ; Remove 13 for Linux
|
|
||||||
MAX_BYTES equ 13
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MODE MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
macro use16
|
|
||||||
{
|
|
||||||
use16
|
|
||||||
_USE = 16
|
|
||||||
}
|
|
||||||
|
|
||||||
macro use32
|
|
||||||
{
|
|
||||||
use32
|
|
||||||
_USE = 32
|
|
||||||
}
|
|
||||||
|
|
||||||
macro use64
|
|
||||||
{
|
|
||||||
use64
|
|
||||||
_USE = 64
|
|
||||||
}
|
|
||||||
|
|
||||||
macro detect_mode
|
|
||||||
{
|
|
||||||
local aux
|
|
||||||
|
|
||||||
_USE = 32
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
xchg eax, eax
|
|
||||||
load aux byte from 0
|
|
||||||
|
|
||||||
if aux = $66
|
|
||||||
_USE = 16
|
|
||||||
else if aux = $87
|
|
||||||
_USE = 64
|
|
||||||
end if
|
|
||||||
end virtual
|
|
||||||
}
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAYING MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
macro display_address address*
|
|
||||||
{
|
|
||||||
local aux, digit
|
|
||||||
|
|
||||||
aux = address
|
|
||||||
|
|
||||||
repeat _USE / 4
|
|
||||||
digit = aux shr (_USE - 4 * %) and $F
|
|
||||||
|
|
||||||
display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F
|
|
||||||
end repeat
|
|
||||||
|
|
||||||
display ': '
|
|
||||||
}
|
|
||||||
|
|
||||||
macro display_bytes pointer
|
|
||||||
{
|
|
||||||
local aux, size, digit
|
|
||||||
|
|
||||||
size = $ - pointer
|
|
||||||
|
|
||||||
if size > MAX_BYTES
|
|
||||||
size = MAX_BYTES
|
|
||||||
end if
|
|
||||||
|
|
||||||
repeat size
|
|
||||||
load aux byte from pointer+%-1
|
|
||||||
|
|
||||||
digit = aux shr 4
|
|
||||||
display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F
|
|
||||||
|
|
||||||
digit = aux and $F
|
|
||||||
display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F
|
|
||||||
|
|
||||||
|
|
||||||
display ' '
|
|
||||||
end repeat
|
|
||||||
|
|
||||||
repeat MAX_BYTES - size
|
|
||||||
display ' '
|
|
||||||
end repeat
|
|
||||||
}
|
|
||||||
|
|
||||||
; The macro below in some situations doesn't adds a space to separate things unfortunatelly, so for readability ensurance
|
|
||||||
; another one will be used instead...
|
|
||||||
;macro display_args [args]
|
|
||||||
;{
|
|
||||||
;common
|
|
||||||
; aux = 1
|
|
||||||
;
|
|
||||||
;forward
|
|
||||||
; if ~args eq
|
|
||||||
; if aux
|
|
||||||
; display ' '
|
|
||||||
; else
|
|
||||||
; display ', '
|
|
||||||
; end if
|
|
||||||
;
|
|
||||||
; aux = 0
|
|
||||||
;
|
|
||||||
; match =ON, _RESOLVE_EQUATES
|
|
||||||
; \{
|
|
||||||
; match args, args
|
|
||||||
; \\{
|
|
||||||
; irps arg, args
|
|
||||||
; \\\{
|
|
||||||
; display \\\`arg
|
|
||||||
; \\\}
|
|
||||||
; \\}
|
|
||||||
; \}
|
|
||||||
; match =OFF, _RESOLVE_EQUATES
|
|
||||||
; \{
|
|
||||||
; irps arg, args
|
|
||||||
; \\{
|
|
||||||
; display \\`arg
|
|
||||||
; \\}
|
|
||||||
;
|
|
||||||
; \}
|
|
||||||
; end if
|
|
||||||
;}
|
|
||||||
|
|
||||||
; This one separates everything with one space. A very ugly listing but at least you will not see things
|
|
||||||
; like "push ebxesiedi" nor "ret word0"
|
|
||||||
|
|
||||||
macro display_args [args]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
aux = 1
|
|
||||||
|
|
||||||
forward
|
|
||||||
if ~args eq
|
|
||||||
if ~aux
|
|
||||||
display ','
|
|
||||||
end if
|
|
||||||
|
|
||||||
aux = 0
|
|
||||||
|
|
||||||
match =ON, _RESOLVE_EQUATES
|
|
||||||
\{
|
|
||||||
match args, args
|
|
||||||
\\{
|
|
||||||
if ~args eqtype ""
|
|
||||||
irps arg, args
|
|
||||||
\\\{
|
|
||||||
display ' ', \\\`arg
|
|
||||||
\\\}
|
|
||||||
else
|
|
||||||
display " '", args, "'"
|
|
||||||
end if
|
|
||||||
\\}
|
|
||||||
\}
|
|
||||||
match =OFF, _RESOLVE_EQUATES
|
|
||||||
\{
|
|
||||||
if ~args eqtype ""
|
|
||||||
irps arg, args
|
|
||||||
\\{
|
|
||||||
display ' ', \\`arg
|
|
||||||
\\}
|
|
||||||
else
|
|
||||||
display " '", args, "'"
|
|
||||||
end if
|
|
||||||
\}
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;; INSTRUCTIONS & PREFIXES MACROSES ;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
macro prefix mnemonic
|
|
||||||
{
|
|
||||||
local aux
|
|
||||||
|
|
||||||
macro mnemonic [args]
|
|
||||||
\{
|
|
||||||
\common
|
|
||||||
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
|
|
||||||
match =equ, args\\{_LISTING equ 0\\}
|
|
||||||
match =equ any, args\\{_LISTING equ 0\\}
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_address $
|
|
||||||
aux = $
|
|
||||||
\\}
|
|
||||||
|
|
||||||
mnemonic
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_bytes aux
|
|
||||||
|
|
||||||
display \`mnemonic
|
|
||||||
display CRLF
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
|
|
||||||
match =equ, args\\{restore _LISTING\\}
|
|
||||||
match =equ any, args\\{restore _LISTING\\}
|
|
||||||
|
|
||||||
def_prefix mnemonic
|
|
||||||
args
|
|
||||||
purge mnemonic
|
|
||||||
\}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro def_prefix mnemonic
|
|
||||||
{
|
|
||||||
macro def_prefix mnemonic
|
|
||||||
\{
|
|
||||||
prefix mnemonic
|
|
||||||
\}
|
|
||||||
def_prefix mnemonic
|
|
||||||
}
|
|
||||||
|
|
||||||
macro instruction mnemonic
|
|
||||||
{
|
|
||||||
local aux
|
|
||||||
|
|
||||||
macro mnemonic [args]
|
|
||||||
\{
|
|
||||||
\common
|
|
||||||
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
|
|
||||||
match =equ, args\\{_LISTING equ 0\\}
|
|
||||||
match =equ any, args\\{_LISTING equ 0\\}
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_address $
|
|
||||||
aux = $
|
|
||||||
\\}
|
|
||||||
|
|
||||||
mnemonic args
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_bytes aux
|
|
||||||
|
|
||||||
display \`mnemonic
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
db \`mnemonic
|
|
||||||
repeat 11 - $
|
|
||||||
display ' '
|
|
||||||
end repeat
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
display_args args
|
|
||||||
display CRLF
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
|
|
||||||
match =equ, args\\{restore _LISTING\\}
|
|
||||||
match =equ any, args\\{restore _LISTING\\}
|
|
||||||
\}
|
|
||||||
}
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
macro data_define mnemonic
|
|
||||||
{
|
|
||||||
local aux
|
|
||||||
macro mnemonic [args]
|
|
||||||
\{
|
|
||||||
\common
|
|
||||||
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
|
|
||||||
match =equ, args\\{_LISTING equ 0\\}
|
|
||||||
match =equ any, args\\{_LISTING equ 0\\}
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_address $
|
|
||||||
aux = $
|
|
||||||
\\}
|
|
||||||
|
|
||||||
mnemonic args
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_bytes aux
|
|
||||||
|
|
||||||
display \`mnemonic
|
|
||||||
|
|
||||||
display_args args
|
|
||||||
display CRLF
|
|
||||||
|
|
||||||
aux = aux + MAX_BYTES
|
|
||||||
|
|
||||||
repeat ($ - aux + MAX_BYTES - 1) / MAX_BYTES
|
|
||||||
display_address aux
|
|
||||||
display_bytes aux
|
|
||||||
display CRLF
|
|
||||||
|
|
||||||
aux = aux + MAX_BYTES
|
|
||||||
end repeat
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
|
|
||||||
match =equ, args\\{restore _LISTING\\}
|
|
||||||
match =equ any, args\\{restore _LISTING\\}
|
|
||||||
\}
|
|
||||||
|
|
||||||
struc mnemonic [args]
|
|
||||||
\{
|
|
||||||
\common
|
|
||||||
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
|
|
||||||
match =equ, args\\{_LISTING equ 0\\}
|
|
||||||
match =equ any, args\\{_LISTING equ 0\\}
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_address $
|
|
||||||
aux = $
|
|
||||||
\\}
|
|
||||||
|
|
||||||
. mnemonic args
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_bytes aux
|
|
||||||
|
|
||||||
display \`., ' ', \`mnemonic
|
|
||||||
|
|
||||||
display_args args
|
|
||||||
display CRLF
|
|
||||||
|
|
||||||
aux = aux + MAX_BYTES
|
|
||||||
|
|
||||||
repeat ($ - aux + MAX_BYTES - 1) / MAX_BYTES
|
|
||||||
display_address aux
|
|
||||||
display_bytes aux
|
|
||||||
display CRLF
|
|
||||||
|
|
||||||
aux = aux + MAX_BYTES
|
|
||||||
end repeat
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
|
|
||||||
match =equ, args\\{restore _LISTING\\}
|
|
||||||
match =equ any, args\\{restore _LISTING\\}
|
|
||||||
\}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro data_reserve mnemonic
|
|
||||||
{
|
|
||||||
local aux
|
|
||||||
macro mnemonic [args]
|
|
||||||
\{
|
|
||||||
\common
|
|
||||||
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
|
|
||||||
match =equ, args\\{_LISTING equ 0\\}
|
|
||||||
match =equ any, args\\{_LISTING equ 0\\}
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_address $
|
|
||||||
aux = $
|
|
||||||
\\}
|
|
||||||
|
|
||||||
mnemonic args
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
times MAX_BYTES display ' '
|
|
||||||
|
|
||||||
display \`mnemonic
|
|
||||||
|
|
||||||
display_args args
|
|
||||||
display CRLF
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
|
|
||||||
match =equ, args\\{restore _LISTING\\}
|
|
||||||
match =equ any, args\\{restore _LISTING\\}
|
|
||||||
\}
|
|
||||||
|
|
||||||
struc mnemonic [args]
|
|
||||||
\{
|
|
||||||
\common
|
|
||||||
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
|
|
||||||
match =equ, args\\{_LISTING equ 0\\}
|
|
||||||
match =equ any, args\\{_LISTING equ 0\\}
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
display_address $
|
|
||||||
aux = $
|
|
||||||
\\}
|
|
||||||
|
|
||||||
. mnemonic args
|
|
||||||
|
|
||||||
match =1, _LISTING
|
|
||||||
\\{
|
|
||||||
times MAX_BYTES display ' '
|
|
||||||
|
|
||||||
display \`., ' ', \`mnemonic
|
|
||||||
|
|
||||||
display_args args
|
|
||||||
display CRLF
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
|
|
||||||
match =equ, args\\{restore _LISTING\\}
|
|
||||||
match =equ any, args\\{restore _LISTING\\}
|
|
||||||
\}
|
|
||||||
}
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;; LISTING CONTROL MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
macro virtual [args]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
_ON_VIRTUAL equ 1
|
|
||||||
|
|
||||||
virtual args
|
|
||||||
}
|
|
||||||
|
|
||||||
macro end [args]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
match =virtual, args\{restore _ON_VIRTUAL\}
|
|
||||||
|
|
||||||
end args
|
|
||||||
}
|
|
||||||
|
|
||||||
macro enable_listing
|
|
||||||
{
|
|
||||||
detect_mode
|
|
||||||
|
|
||||||
match =0, _MACROSES_INSTALLED
|
|
||||||
\{
|
|
||||||
match instructions, INSTRUCTIONS
|
|
||||||
\\{
|
|
||||||
irps ins, instructions
|
|
||||||
\\\{
|
|
||||||
instruction ins
|
|
||||||
\\\}
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match prefixes, PREFIXES
|
|
||||||
\\{
|
|
||||||
irps prefix, prefixes
|
|
||||||
\\\{
|
|
||||||
def_prefix prefix
|
|
||||||
\\\}
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match data_definitors, DATA_DEFINITORS
|
|
||||||
\\{
|
|
||||||
irps def, data_definitors
|
|
||||||
\\\{
|
|
||||||
data_define def
|
|
||||||
\\\}
|
|
||||||
\\}
|
|
||||||
|
|
||||||
match data_reservers, DATA_RESERVERS
|
|
||||||
\\{
|
|
||||||
irps def, data_reservers
|
|
||||||
\\\{
|
|
||||||
data_reserve def
|
|
||||||
\\\}
|
|
||||||
\\}
|
|
||||||
\}
|
|
||||||
|
|
||||||
_MACROSES_INSTALLED equ 1
|
|
||||||
_LISTING equ 1
|
|
||||||
}
|
|
||||||
|
|
||||||
macro disable_listing
|
|
||||||
{
|
|
||||||
_LISTING equ 0
|
|
||||||
}
|
|
||||||
|
|
||||||
macro enable [feature*]
|
|
||||||
{
|
|
||||||
forward
|
|
||||||
UNKNOWN equ 1
|
|
||||||
|
|
||||||
match =resolve_equates, feature
|
|
||||||
\{
|
|
||||||
restore _RESOLVE_EQUATES
|
|
||||||
_RESOLVE_EQUATES equ ON
|
|
||||||
UNKNOWN equ 0
|
|
||||||
\}
|
|
||||||
|
|
||||||
match =listing, feature
|
|
||||||
\{
|
|
||||||
enable_listing
|
|
||||||
UNKNOWN equ 0
|
|
||||||
\}
|
|
||||||
|
|
||||||
match =1, UNKNOWN
|
|
||||||
\{
|
|
||||||
display 'ERROR: Unknown "',`feature, '" feature', 13, 10
|
|
||||||
err
|
|
||||||
\}
|
|
||||||
|
|
||||||
restore UNKNOWN
|
|
||||||
restore UNKNOWN
|
|
||||||
}
|
|
||||||
|
|
||||||
macro disable [feature*]
|
|
||||||
{
|
|
||||||
UNKNOWN equ 1
|
|
||||||
|
|
||||||
match =resolve_equates, feature
|
|
||||||
\{
|
|
||||||
restore _RESOLVE_EQUATES
|
|
||||||
_RESOLVE_EQUATES equ OFF
|
|
||||||
UNKNOWN equ 0
|
|
||||||
\}
|
|
||||||
|
|
||||||
match =listing, feature
|
|
||||||
\{
|
|
||||||
disable_listing
|
|
||||||
UNKNOWN equ 0
|
|
||||||
\}
|
|
||||||
|
|
||||||
match =1, UNKNOWN
|
|
||||||
\{
|
|
||||||
display 'ERROR: Unknown "',`feature, '" feature', 13, 10
|
|
||||||
err
|
|
||||||
\}
|
|
||||||
|
|
||||||
restore UNKNOWN
|
|
||||||
restore UNKNOWN
|
|
||||||
}
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INITIALIZATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
_MACROSES_INSTALLED equ 0
|
|
||||||
_ON_VIRTUAL equ 0
|
|
||||||
|
|
||||||
disable resolve_equates
|
|
@ -1,317 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
;start of the project 13.02.2008 year.
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;Secondary Loader copyright Alexey Teplov nickname <Lrz>
|
|
||||||
;if you need log preproc
|
|
||||||
;/////////////
|
|
||||||
;include 'listing.inc'
|
|
||||||
;enable listing
|
|
||||||
;////////////
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;start of code: ;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
use16
|
|
||||||
org 0x0
|
|
||||||
jmp start
|
|
||||||
include 'sl_equ.inc' ; â ôàéëå ðàçìåùåíû âñå equ ïðåäîïðåäåëåíèÿ
|
|
||||||
include 'boot_st.inc'
|
|
||||||
include 'debug_msg.inc' ;here is message from debug
|
|
||||||
include 'parse_dat.inc'
|
|
||||||
include 'sl_proc.inc'
|
|
||||||
include 'parse.inc'
|
|
||||||
include 'parse_loader.inc'
|
|
||||||
include 'parse_any.inc'
|
|
||||||
include 'parse_def_sect.inc'
|
|
||||||
include 'parse_err.inc'
|
|
||||||
|
|
||||||
file_data dw 0x0,ini_data_ ;ôîðìàò: ñìåùåíèå: ñåãìåíò ò.ê. èñïîëüçóåòñÿ les
|
|
||||||
size_data dw 16 ;16 áëîêîâ ïî 4 êá ò.å ïðåäåë äî 64 êá
|
|
||||||
name_ini_f db 'kord/startos.ini',0
|
|
||||||
|
|
||||||
;////////////
|
|
||||||
loader_callback dd ?
|
|
||||||
load_drive dw ?
|
|
||||||
load_ft dw ?
|
|
||||||
;Start code
|
|
||||||
|
|
||||||
start:
|
|
||||||
; Save far pointer to callback procedure, ds:si is point
|
|
||||||
mov word [cs:loader_callback], si
|
|
||||||
mov word [cs:loader_callback+2], ds
|
|
||||||
; Save type of drive
|
|
||||||
mov word [cs:load_drive],ax
|
|
||||||
; Save type of FT
|
|
||||||
mov word [cs:load_ft],bx
|
|
||||||
; set up stack
|
|
||||||
mov ax, cs
|
|
||||||
mov ss, ax
|
|
||||||
xor sp, sp
|
|
||||||
; set up segment registers
|
|
||||||
mov ds,ax
|
|
||||||
mov es,ax
|
|
||||||
; just to be sure: force DF=0, IF=1
|
|
||||||
cld
|
|
||||||
sti
|
|
||||||
|
|
||||||
; set videomode
|
|
||||||
mov ax,3
|
|
||||||
int 0x10
|
|
||||||
|
|
||||||
mov si,version
|
|
||||||
call printplain
|
|
||||||
mov al,'#'
|
|
||||||
mov cx,80
|
|
||||||
;input cx=size al=char áóäåò âûâäåí ñèìâîë ñêîëüêî ðàç óêàçàíî â cx
|
|
||||||
@@:
|
|
||||||
call putchar
|
|
||||||
loop @b
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
pushad
|
|
||||||
mov ax,cs
|
|
||||||
shl eax,4 ; â äåñÿòè÷íîé ñèñòåìå àäðåñ ñåãìåíòà
|
|
||||||
mov cx,0xa
|
|
||||||
mov di,cseg_msg
|
|
||||||
call decode
|
|
||||||
;***************
|
|
||||||
mov si,cseg_msg
|
|
||||||
call printplain
|
|
||||||
popad
|
|
||||||
end if
|
|
||||||
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
mov si,stack_msg
|
|
||||||
call printplain
|
|
||||||
end if
|
|
||||||
|
|
||||||
; Require 586 or higher processor (cpuid and rdtsc,rdmsr/wrmsr commands)
|
|
||||||
; install int 6 (#UD) handler
|
|
||||||
xor bx, bx
|
|
||||||
mov ds, bx
|
|
||||||
push word [bx+6*4+2]
|
|
||||||
push word [bx+6*4]
|
|
||||||
mov word [bx+6*4], ud16
|
|
||||||
mov word [bx+6*4+2], cs
|
|
||||||
; issue CPUID command
|
|
||||||
xor eax, eax ; N.B.: will cause #UD before 386
|
|
||||||
cpuid ; N.B.: will cause #UD before later 486s
|
|
||||||
test eax, eax
|
|
||||||
jz cpubad
|
|
||||||
; get processor features
|
|
||||||
xor eax, eax
|
|
||||||
inc ax
|
|
||||||
cpuid
|
|
||||||
test dl, 10h ; CPUID[1].edx[4] - TSC support
|
|
||||||
jz cpubad
|
|
||||||
test dl, 20h ; CPUID[1].edx[5] - MSR support
|
|
||||||
jnz cpugood
|
|
||||||
|
|
||||||
ud16: ; #UD handler, called if processor did not recognize some commands
|
|
||||||
cpubad:
|
|
||||||
; restore int 6 (#UD) handler
|
|
||||||
pop word [6*4]
|
|
||||||
pop word [6*4+2]
|
|
||||||
; say error
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
mov si, badprocessor
|
|
||||||
sayerr:
|
|
||||||
call printplain
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
cpugood:
|
|
||||||
; restore int 6 (#UD) handler
|
|
||||||
pop dword [6*4]
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
; set up esp
|
|
||||||
movzx esp, sp
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; init memory
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Load startos.ini
|
|
||||||
mov cx,loop_read_startos_file ;êîë-âî ïîïûòîê ÷òåíèÿ ôàéëà êîíôèãóðàöèè startos.ini
|
|
||||||
align 4
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; Load startos.ini ;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
load_startos_file:
|
|
||||||
|
|
||||||
xor ax,ax
|
|
||||||
mov di,file_data
|
|
||||||
inc ax ;function 1 - read file
|
|
||||||
push cx
|
|
||||||
call far dword [loader_callback]
|
|
||||||
pop cx
|
|
||||||
push cs
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
pop es
|
|
||||||
|
|
||||||
test bx,bx
|
|
||||||
jz check_conf_file
|
|
||||||
dec cx
|
|
||||||
jnz load_startos_file
|
|
||||||
|
|
||||||
;SET DEFAULT Not use ini file
|
|
||||||
error_ini:
|
|
||||||
mov si, error_ini_f1 ;Error: cannot load ini file, buffer is full
|
|
||||||
dec bx
|
|
||||||
jz err_show_ini
|
|
||||||
mov si, error_ini_f2 ;Error: ini file not found
|
|
||||||
dec bx
|
|
||||||
jz err_show_ini
|
|
||||||
mov si, error_ini_f3 ;Error: cannot read ini file
|
|
||||||
dec bx
|
|
||||||
jz err_show_ini
|
|
||||||
|
|
||||||
mov si, error_ini_nf ;Error: unrecognized error when loading ini file
|
|
||||||
err_show_ini:
|
|
||||||
call printplain
|
|
||||||
mov si, error_ini_common
|
|
||||||
call printplain
|
|
||||||
; wait for keypress
|
|
||||||
xor ax,ax
|
|
||||||
int 16h
|
|
||||||
|
|
||||||
ini_loaded:
|
|
||||||
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
align 4
|
|
||||||
check_conf_file:
|
|
||||||
;Check config file in current dir
|
|
||||||
push ax ;save size file
|
|
||||||
if DEBUG
|
|
||||||
mov cx,0x0a
|
|
||||||
mov di,show_decode
|
|
||||||
call decode
|
|
||||||
;Show size
|
|
||||||
mov si,show_string
|
|
||||||
call printplain
|
|
||||||
end if
|
|
||||||
|
|
||||||
|
|
||||||
;Show message
|
|
||||||
mov si,load_ini
|
|
||||||
call printplain
|
|
||||||
|
|
||||||
pop cx ;restore size file
|
|
||||||
use_parse ;parsing startos.ini
|
|
||||||
;
|
|
||||||
jmp ini_loaded
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;DATA
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; table for move to extended memory (int 15h, ah=87h)
|
|
||||||
align 4
|
|
||||||
table_15_87:
|
|
||||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
|
||||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
|
||||||
|
|
||||||
db 0xff,0xff
|
|
||||||
db 0x0,0x10
|
|
||||||
db 0x00,0x93,0x0,0x0
|
|
||||||
|
|
||||||
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
|
|
||||||
|
|
||||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
|
||||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
|
||||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
|
||||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
|
||||||
|
|
||||||
fat12_buffer:
|
|
||||||
.BS_jmpBoot db 0x90,0x90,0x90 ;3 áàéòà NOP èíñòðóêöèÿ - íè÷åãî íå äåëàòü
|
|
||||||
.BS_OEMName db 'K SyS 64' ;8 áàéò
|
|
||||||
.BPB_BytsPerSec dw 512 ;êîë-âî áàéòîâ â ñåêòîðå ìîæåò áûòü ëþáîå 512 1024 2048 4096 2 áàéòà
|
|
||||||
.BPB_SecPerClus db 0x1 ;êîë-âî ñåêòîðîâ â êëàñòåðå
|
|
||||||
.BPB_RsvdSecCnt dw 0x1 ;äëÿ FAt12/16 òîëüêî 1, äëÿ FAT32 îáû÷íî 32
|
|
||||||
.BPB_NumFATs db 0x1 ;êîë-âî ôàò òàáëèö, íà òîò ñëó÷àé åñëè áóäåò ñáðîñ íà äèñêåòó îáðàçà ðàì äèñêà
|
|
||||||
.BPB_RootEntCnt dw 512 ;äëÿ ìàê ñîâìåñòèìîñòè ñ fat16
|
|
||||||
.BPB_TotSec16 dw 0x0 ;êë-âî ñåêòîðîâ
|
|
||||||
.BPB_Media db 0xF0
|
|
||||||
.BPB_FATSz16 dw 0x0
|
|
||||||
.BPB_SecPerTrk dw 0x0 ;ñîäåðæèò ãåîìåòðèþ äèñêà äëÿ RAMFS íà êàê áû áåç ðàçíèöû, ïîêà ïóñòîå ïîëå, ïîçæå âíåñòè ðåàëüíûå çíà÷åíèÿ.
|
|
||||||
.BPB_NumHeads dw 0x0
|
|
||||||
.BPB_HiddSec dd 0x0 ;êîë-âî ñêðûòûõ ñåêòîðîâ
|
|
||||||
.BPB_TotSec32 dd 0x0
|
|
||||||
.BS_DrvNum db 'R' ;îò ñëîâà RAM
|
|
||||||
.BS_Reserved1 db 0x0
|
|
||||||
.BS_BootSig db 0x29
|
|
||||||
.BS_VolID db 'RFKS'
|
|
||||||
.BS_VolLab db 'RAM DISK FS' ;11 ñèìâîëîâ
|
|
||||||
.BS_FilSysType db 'FAT12 ' ;8 ñèìâîëîâ
|
|
||||||
;62 áàéòà ñòðóêòóðà fat12.
|
|
||||||
db (512-($-fat12_buffer))dup(0x90)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;ñòðóêòóðà äëÿ äèððåêòîðèè fat
|
|
||||||
struc FAT_32_entry ;Byte Directory Entry Structure
|
|
||||||
{
|
|
||||||
.DIR_Name rb 11
|
|
||||||
.DIR_Attr db ?
|
|
||||||
.DIR_NTRes db ?
|
|
||||||
.DIR_CrtTimeTenth db ?
|
|
||||||
.DIR_CrtTime dw ?
|
|
||||||
.DIR_CrtDate dw ?
|
|
||||||
.DIR_LstAccDate dw ?
|
|
||||||
.DIR_FstClusHI dw ?
|
|
||||||
.DIR_WrtTime dw ?
|
|
||||||
.DIR_WrtDate dw ?
|
|
||||||
.DIR_FstClusLO dw ?
|
|
||||||
.DIR_FileSize dd ?
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
;Òóò áóäóò ðàñïîëîãàòñüÿ äàííûå, êîòîðûå çàòðóäíèòåëüíî ðàñïîëîãàòü â ñòåêîâîé îáëàñòè....
|
|
||||||
;;;
|
|
||||||
;timer
|
|
||||||
shot_name_fat rb 11 ;âðåìåííûé áóôåð äëÿ fat12, â íåì õðàíÿòüñÿ èìåíà ôàéëîâ ïðèâåäåííûå ê ïðàâèëàì FAT /* âäàëüíåéøåì ïåðåíåñòè â ñòýê
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
rb 1 ;íóæåí äëÿ îòëàäêè è âûâîäà èìåíè ôàéëà ïîñëå ïðåîáðàçîâàíèÿ
|
|
||||||
dest_name_fat db 24 dup('_');12
|
|
||||||
db 0x0
|
|
||||||
end if
|
|
||||||
|
|
||||||
value_timeout rw 1 ;value to timeout
|
|
||||||
old_timer rd 1 ;ñòàðîå çíà÷åíèå âåêòîðà òàéìåðà
|
|
||||||
start_timer rd 1 ;çíà÷åíèå òàéìåðà
|
|
||||||
timer_ rd 1 ;íîâîå çíà÷åíèå âåêòîðà òàéìåðà ò.å. SL
|
|
||||||
start_stack rw 1 ;save stack
|
|
||||||
save_bp_from_timer rw 1 ;save bp from timer
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,118 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
; Ìîäóëü ïàðñèíãà - ýòî ñòàíäàðòíûé êîìïîíåíò, âñòðàèâàåìûé âî âòîðè÷íûé çàãðóç÷èê.
|
|
||||||
; Äàííûé ìîäóëü ïîçâîëÿåò ñòàíäàðòíî ïðîèçâåñòè ðàçáîð ini ôàéëà
|
|
||||||
; (è ñ èñïîëüçîâàíèåì ïîëó÷åííûõ äàííûõ ÎÑ áóäåò çàãðóæàòüñÿ äàëüøå).
|
|
||||||
;  íà÷àëå íàéäåì îòêðûâàþùèé "[" - ýòî áóäåò óêàçûâàòü íà íà÷àëî
|
|
||||||
; ñåêöèè. Ïîääåðæèâàåòñÿ 1 ñåêöèÿ ýòî [loader], îñòàëüíûå ñåêöèè ìîãóò èìåòü
|
|
||||||
; ëþáûå èìåíà, íî îíè äîëæíû áûòü çàêëþ÷åíû â â ñêîáêè []
|
|
||||||
macro use_parse
|
|
||||||
{
|
|
||||||
;input cx=size of ini file
|
|
||||||
parse_start:
|
|
||||||
;es:di as 2000:0000 new segment
|
|
||||||
;óñòàíîâèì óêàçàòåëü íà çàãðóæåííûé áëîê
|
|
||||||
enter 256,0 ;set 16 byte for current task in stack
|
|
||||||
;we are is not use bp because bp is pointer on array 16 byte
|
|
||||||
mov word [save_bp_from_timer],bp ;save point to own data array
|
|
||||||
mov save_cx,cx ;it's placed size of ini file
|
|
||||||
les di,dword [file_data]
|
|
||||||
;îáíóëèì âñå ïåðåìåííûå âûäåëåííûå èç ñòåêà
|
|
||||||
;init flag
|
|
||||||
xor ax,ax
|
|
||||||
mov status_flag,ax
|
|
||||||
;set data size
|
|
||||||
mov info_real_mode_size,ini_data_ +0x1000 ;èçìåíèì çíà÷åíèå çàíÿòîñòè ïàìÿòè
|
|
||||||
|
|
||||||
;ïîèñê íà÷àëà áëîêà.
|
|
||||||
;///////////check [loader]
|
|
||||||
cld
|
|
||||||
|
|
||||||
mov ret_on_ch,.start ;set return
|
|
||||||
mov al,byte [es:di]
|
|
||||||
push word .first_ret
|
|
||||||
cmp al,' '
|
|
||||||
jz .first_sp_1
|
|
||||||
jmp get_firs_sym.not_space
|
|
||||||
.first_sp_1:
|
|
||||||
jmp get_firs_sym.first_sp
|
|
||||||
|
|
||||||
.start:
|
|
||||||
call get_firs_sym ;get first symbol on new line
|
|
||||||
.first_ret: ;ïåðâûé âîçâðàò
|
|
||||||
; jcxz .end_file ;.end_loader ;found or not found parametrs in section exit in section
|
|
||||||
test cx,cx
|
|
||||||
jz error.not_loader
|
|
||||||
cmp al,'['
|
|
||||||
jz .parse_loader
|
|
||||||
jmp .start
|
|
||||||
;////// ïðîâåðêà íà íàëè÷åå ñåêöèè loader
|
|
||||||
use_parse_loader
|
|
||||||
;pause
|
|
||||||
if DEBUG
|
|
||||||
xor ax,ax
|
|
||||||
int 16h
|
|
||||||
end if
|
|
||||||
;////// âûâîä ãðàôè÷åñêîãî ýêðàíà, âûáîð, ñåêöèè ïîä äåôîëòó
|
|
||||||
use_any_sec
|
|
||||||
;ïàðñèíã âûáðàíîé èëè äåôîëòíîé ñåêöèè ò.å. ðàçáîð ïàðàìåòðîâ âûïîëíåíèå ñöåíàðèÿ
|
|
||||||
use_parse_def_sect
|
|
||||||
|
|
||||||
;//////////////////
|
|
||||||
;/end parse block
|
|
||||||
;//////////////////
|
|
||||||
;.end_bl:
|
|
||||||
; mov cx,bx
|
|
||||||
;
|
|
||||||
; jmp .start
|
|
||||||
|
|
||||||
.exit:
|
|
||||||
|
|
||||||
; mov si,parse_ini_end
|
|
||||||
; call printplain
|
|
||||||
;
|
|
||||||
;if DEBUG
|
|
||||||
; pusha
|
|
||||||
; mov ax,cx
|
|
||||||
; mov cx,0x0a
|
|
||||||
; mov di,show_db1_dec
|
|
||||||
; mov dword[ds:di],' '
|
|
||||||
; call decode
|
|
||||||
;Show size
|
|
||||||
; mov si,show_db1
|
|
||||||
; call printplain
|
|
||||||
;
|
|
||||||
; popa
|
|
||||||
;end if
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
;///////////////////procedure //////////
|
|
||||||
;input es:di - is pointer to date
|
|
||||||
;cx - counter
|
|
||||||
;return: cx - status if =0 - end of date else es:di point to first symbol on new line
|
|
||||||
|
|
||||||
}
|
|
@ -1,683 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
;òóò ðàñïîëîãàåòñÿ ìîäóëü ñ ïîìîùüþ êîòîðîãî áóäóò ïàðñèòüñÿ âñå îñòàëüíûå ñåêöèè
|
|
||||||
color_sym_black equ 0
|
|
||||||
color_sym_blue equ 1
|
|
||||||
color_sym_green equ 2
|
|
||||||
color_sym_turquoise equ 3
|
|
||||||
color_sym_red equ 4
|
|
||||||
|
|
||||||
color_sym_lightgray equ 7
|
|
||||||
|
|
||||||
color_sym_lightblue equ 9
|
|
||||||
color_sym_lettuce equ 10
|
|
||||||
color_sym_pink equ 12
|
|
||||||
color_sym_yellow equ 14
|
|
||||||
|
|
||||||
macro use_any_sec
|
|
||||||
{
|
|
||||||
;óçíàåì ðàáîòó ïðåäûäóùåãî øàãà ò.å. ÷åìó = timeout, åñëè îí 0, òî âèçóàëüíàÿ ÷àñòü íå áóäåò îòîáðàæåíà íà äèñïëåå ñ âûáîðîì çàãðóçî÷íûõ ñåêöèé.
|
|
||||||
;èíà÷å ìû åå äîëæíû îòîáðàçèòü è æäàòü çàÿâëåíîå âðåìÿ äëÿ âûáîðà è êîíèãóðèðîâàíèÿ ïóêíêòîâ ñåêöèè îò ïîëüçîâàòåëÿ.
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
pusha
|
|
||||||
mov ax,word [value_timeout] ;èäåò ïðîâåðêà íà íàëè÷åå çíà÷åíèÿ timeout, äëÿ áîëåå áûñòðîé ðàáîòû, ýòîò ïàðàìåòð äîëæåí áûòü óæå îáðàáîòàí,ò.å. â ýòîì ñëó÷àå ïðè åãî =0 áóäåò ñôîðìèðîâàí óêàçàòåëü òîëüêî íà äåôîëòíóþ ñåêöèþ, èíà÷å èíôîðìàöèÿ áóäåò ñîáðàíà ïî âñåì ñåêöèÿì è ñîñòàâëåíû óêàçàòåëè â áëîêå ïàìÿòè
|
|
||||||
; mov ax,cx
|
|
||||||
mov cx,0x0a
|
|
||||||
mov di,show_db1
|
|
||||||
mov dword[ds:di],' '
|
|
||||||
mov word [ds:di+4],' '
|
|
||||||
call decode
|
|
||||||
;Show size
|
|
||||||
mov si,show_db1
|
|
||||||
call printplain
|
|
||||||
;
|
|
||||||
popa
|
|
||||||
end if
|
|
||||||
|
|
||||||
test ax,ax
|
|
||||||
jz .parse_run_only
|
|
||||||
|
|
||||||
;îòîáðàçèì ïîëíûé ñïèñîê âñåõ íàéäåíûõ ñåêöèé.
|
|
||||||
if DEBUG
|
|
||||||
pusha
|
|
||||||
mov si,show_all_sect
|
|
||||||
call printplain
|
|
||||||
popa
|
|
||||||
end if
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
mov al, 0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
|
|
||||||
out 0x60, al
|
|
||||||
xor cx, cx
|
|
||||||
.wait_loop: ; variant 2
|
|
||||||
; reading state of port of 8042 controller
|
|
||||||
in al, 64h
|
|
||||||
and al, 00000010b ; ready flag
|
|
||||||
; wait until 8042 controller is ready
|
|
||||||
loopnz .wait_loop
|
|
||||||
|
|
||||||
|
|
||||||
; set keyboard typematic rate & delay
|
|
||||||
mov al, 0xf3
|
|
||||||
out 0x60, al
|
|
||||||
xor cx, cx
|
|
||||||
@@:
|
|
||||||
in al, 64h
|
|
||||||
test al, 2
|
|
||||||
loopnz @b
|
|
||||||
mov al, 0
|
|
||||||
out 0x60, al
|
|
||||||
xor cx, cx
|
|
||||||
@@:
|
|
||||||
in al, 64h
|
|
||||||
test al, 2
|
|
||||||
loopnz @b
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; get start time
|
|
||||||
call gettime
|
|
||||||
mov dword [start_timer],eax
|
|
||||||
mov word [timer_],newtimer
|
|
||||||
mov word [timer_+2],cs
|
|
||||||
;óñòàíîâèòü ñâîå ïðåðûâàíèå íà òàéìåð ò.å. êîä áóäåò ïåððûâàòüñÿ ~18 ðàç â ñåê è ïåðåõîäèòü íà îáðàáîò÷èê
|
|
||||||
cli
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
push dword [es:8*4]
|
|
||||||
pop dword [old_timer]
|
|
||||||
push dword [timer_]
|
|
||||||
pop dword [es:8*4]
|
|
||||||
sti
|
|
||||||
|
|
||||||
;ïðîöåäóðà ôîðìèðîâàíèÿ áóôåðà äëÿ ñêðîëèíãà ñåêöèé
|
|
||||||
;if DEBUG
|
|
||||||
; pusha
|
|
||||||
; mov ax,point_default
|
|
||||||
; mov ax,cx
|
|
||||||
; mov cx,0x0a
|
|
||||||
; mov di,show_db1
|
|
||||||
; mov dword[ds:di],' '
|
|
||||||
; mov word [ds:di+4],' '
|
|
||||||
; call decode
|
|
||||||
;Show size
|
|
||||||
; mov si,show_db1
|
|
||||||
; call printplain
|
|
||||||
;
|
|
||||||
; xor ax,ax
|
|
||||||
; int 0x16
|
|
||||||
; popa
|
|
||||||
;end if
|
|
||||||
;;;;;;;;;;;;;ðàçìåð ïðåäûäóùåé ñåöèè óñòàíîâèì =0
|
|
||||||
mov save_descript_size,18
|
|
||||||
;îòîáðàçèòü black screen
|
|
||||||
show_bl_sc ;es=0xb800
|
|
||||||
.show_all_scr:
|
|
||||||
get_frame_buffer ;es=0x2000
|
|
||||||
;îòîáðàæåíèå ñåêöèé
|
|
||||||
call show_bl_sc_sect ;es=0xb800
|
|
||||||
;îòîáðàçèòü àêòèâíûé êóðñîð
|
|
||||||
.show_active_cursor:
|
|
||||||
show_act_cursor
|
|
||||||
show_descript ;ìàêðîñ ïî îòîáðàæåíèþ îïèñàíèÿ ñåêöèè
|
|
||||||
|
|
||||||
;îòîáðàçèòü Press any key ....
|
|
||||||
mov eax,dword [old_timer]
|
|
||||||
cmp eax,dword [timer_]
|
|
||||||
jz .interrupt_16
|
|
||||||
|
|
||||||
show_timer_message
|
|
||||||
mov word [start_stack],sp
|
|
||||||
.interrupt_16:
|
|
||||||
xor ax,ax ;ïîëó÷èì èíôîðìàöèþ î òîì ÷òî íàæàòî
|
|
||||||
int 0x16
|
|
||||||
;check on change
|
|
||||||
mov ebx,dword [old_timer]
|
|
||||||
cmp ebx,dword [timer_]
|
|
||||||
jz @f
|
|
||||||
;restore timer interrupt
|
|
||||||
cli
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
; mov eax,dword [old_timer] ; âîññòàíîâèì ïðåæäíåå ïðåðûâàíèå
|
|
||||||
mov [es:8*4],ebx
|
|
||||||
mov dword [timer_],ebx
|
|
||||||
sti
|
|
||||||
|
|
||||||
push ax
|
|
||||||
clear_timer_msg
|
|
||||||
pop ax
|
|
||||||
@@:
|
|
||||||
call clean_active_cursor ;clean old cursor ;es=0xb800
|
|
||||||
|
|
||||||
cmp ah,0x48 ;ðåàêöèÿ ñèñòåìû íà ñîáûòèÿ
|
|
||||||
jz .up
|
|
||||||
cmp ah,0x50
|
|
||||||
jz .down
|
|
||||||
cmp ah,0x49
|
|
||||||
jz .pgup
|
|
||||||
cmp ah,0x51
|
|
||||||
jz .pgdown
|
|
||||||
cmp ah,0x47
|
|
||||||
jz .home
|
|
||||||
cmp ah,0x4f
|
|
||||||
jz .end
|
|
||||||
|
|
||||||
cmp al,0xD
|
|
||||||
jnz .show_active_cursor
|
|
||||||
|
|
||||||
jmp .end_show_all ;ïàðñèíã ñåêöèè êîòîðàÿ óêàçàíà â point_default
|
|
||||||
.up:
|
|
||||||
mov si,point_to_point_def ;çíà÷åíèå óêàçàòåëÿ
|
|
||||||
add si,2
|
|
||||||
lea ax,point_to_hframe
|
|
||||||
|
|
||||||
cmp si,ax
|
|
||||||
ja @f
|
|
||||||
|
|
||||||
mov point_to_point_def,si
|
|
||||||
mov ax,[si]
|
|
||||||
mov point_default,ax
|
|
||||||
jmp .show_active_cursor
|
|
||||||
@@:
|
|
||||||
call find_before_sect
|
|
||||||
jmp .show_all_scr
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.down:
|
|
||||||
mov si,point_to_point_def ;çíà÷åíèå óêàçàòåëÿ
|
|
||||||
mov ax,point_to_eframe ;óêàçàòåëü íà ïîñëåäíèé ýëåìåíò
|
|
||||||
sub si,2
|
|
||||||
cmp si,ax
|
|
||||||
jb @f
|
|
||||||
|
|
||||||
mov point_to_point_def,si
|
|
||||||
mov ax,[si]
|
|
||||||
mov point_default,ax
|
|
||||||
jmp .show_active_cursor
|
|
||||||
|
|
||||||
@@: call find_next_sect
|
|
||||||
jmp .show_all_scr
|
|
||||||
|
|
||||||
.pgup:
|
|
||||||
mov cx,size_show_section
|
|
||||||
@@:
|
|
||||||
push cx
|
|
||||||
call find_before_sect
|
|
||||||
pop cx
|
|
||||||
loop @b
|
|
||||||
jmp .show_all_scr
|
|
||||||
|
|
||||||
|
|
||||||
.pgdown:
|
|
||||||
mov cx,size_show_section
|
|
||||||
@@:
|
|
||||||
push cx
|
|
||||||
call find_next_sect
|
|
||||||
pop cx
|
|
||||||
loop @b
|
|
||||||
jmp .show_all_scr
|
|
||||||
|
|
||||||
.home:
|
|
||||||
xor di,di
|
|
||||||
call find_next_sect.h
|
|
||||||
jmp .show_all_scr
|
|
||||||
|
|
||||||
.end:
|
|
||||||
mov di,save_cx
|
|
||||||
call find_before_sect.e
|
|
||||||
jmp .show_all_scr
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; òóò ìû áóäåì ïàðñèòü òîëüêî äåôîëòíóþ ñåêöèþ è âûïîëíÿòü åå íè÷åãî íå ïðåäëàãàÿ ïîëüçîâàòåëþ èç äèàëîãîâ.
|
|
||||||
.parse_run_only:
|
|
||||||
if DEBUG
|
|
||||||
pusha
|
|
||||||
mov si,no_show_only_w
|
|
||||||
call printplain
|
|
||||||
popa
|
|
||||||
end if
|
|
||||||
|
|
||||||
|
|
||||||
.end_show_all:
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;show black screen SL
|
|
||||||
macro show_bl_sc
|
|
||||||
{
|
|
||||||
;;;;;;;;;;;;;;;
|
|
||||||
;î÷èñòèì ýêðàí è âûâåäåì ìåíþ
|
|
||||||
; draw frames
|
|
||||||
xor ax,ax
|
|
||||||
if DEBUG
|
|
||||||
mov ax,0x0720
|
|
||||||
end if
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
xor di, di
|
|
||||||
; draw top
|
|
||||||
mov cx, 25 * 80
|
|
||||||
rep stosw
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;; show 'Secondary Loader v0.xxx'
|
|
||||||
mov di,164
|
|
||||||
mov si,version
|
|
||||||
mov cx,version_end-version
|
|
||||||
mov ah,color_sym_yellow
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;; show firm ))
|
|
||||||
mov di,(2*160-(2*(soft_mes_end-soft_mes+4))) ;286
|
|
||||||
mov ah,color_sym_pink;color_sym_red
|
|
||||||
mov al,'K'
|
|
||||||
stosw
|
|
||||||
mov al,' '
|
|
||||||
stosw
|
|
||||||
mov ah,color_sym_lightgray;color_sym_lightblue;color_sym_pink
|
|
||||||
mov si,soft_mes
|
|
||||||
mov cx,soft_mes_end- soft_mes
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;; show '__________________________'
|
|
||||||
mov di,480
|
|
||||||
mov ah,color_sym_yellow
|
|
||||||
mov al,'Ä'
|
|
||||||
mov cx,61
|
|
||||||
rep stosw
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;; show 'Select section'
|
|
||||||
mov di,804
|
|
||||||
mov si,select_section
|
|
||||||
mov cx,select_section_end - select_section
|
|
||||||
mov ah,color_sym_lightgray
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;; show 'Section description'
|
|
||||||
mov di,880
|
|
||||||
mov si,section_description
|
|
||||||
mov cx,section_description_end - section_description
|
|
||||||
; mov ah,color_sym_lightgray
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
macro show_timer_message
|
|
||||||
{
|
|
||||||
;;;;;;;;;;;;;;;;;;;;; show Press any key
|
|
||||||
;;;;;;;;;;;;;;;;;;;;; show ramk
|
|
||||||
|
|
||||||
xor ax,ax
|
|
||||||
mov di,3360
|
|
||||||
mov cx,80*4
|
|
||||||
rep stosw
|
|
||||||
|
|
||||||
mov di,3362
|
|
||||||
mov ah,color_sym_pink
|
|
||||||
mov al,0xDA
|
|
||||||
stosw
|
|
||||||
mov al,0xc4
|
|
||||||
mov cx,76
|
|
||||||
rep stosw
|
|
||||||
mov al,0xBF
|
|
||||||
stosw
|
|
||||||
add di,4
|
|
||||||
mov al,0xb3
|
|
||||||
stosw
|
|
||||||
add di,152
|
|
||||||
stosw
|
|
||||||
add di,4
|
|
||||||
stosw
|
|
||||||
add di,152
|
|
||||||
stosw
|
|
||||||
add di,4
|
|
||||||
mov al,0xc0
|
|
||||||
stosw
|
|
||||||
mov al,0xc4
|
|
||||||
mov cx,76
|
|
||||||
rep stosw
|
|
||||||
mov al,0xd9
|
|
||||||
stosw
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;ramk is complete show
|
|
||||||
;show first message
|
|
||||||
mov si,start_msg
|
|
||||||
mov cx,start_msg_e-start_msg
|
|
||||||
mov di,3526
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
;;;;;;;;;;;;;;;;;;;; show press Enter to....
|
|
||||||
add di,44
|
|
||||||
mov si,time_msg
|
|
||||||
mov cx,time_msg_e-time_msg
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
macro get_frame_buffer
|
|
||||||
{
|
|
||||||
mov cx,save_cx ;it's placed size of ini file
|
|
||||||
les di,dword [file_data]
|
|
||||||
|
|
||||||
mov si,di ;point frame
|
|
||||||
mov bx,cx
|
|
||||||
mov dx,size_show_section
|
|
||||||
; mov point_to_hframe,di ; âíåñåì çíà÷åíèå, òàê ïîäñòðàõîâêà íå áîëåå
|
|
||||||
|
|
||||||
mov al,byte [es:di]
|
|
||||||
push word .first_ret_bl_sc
|
|
||||||
cmp al,' '
|
|
||||||
jz .first_bl_sc
|
|
||||||
jmp get_firs_sym.not_space
|
|
||||||
.first_bl_sc:
|
|
||||||
jmp get_firs_sym.first_sp
|
|
||||||
|
|
||||||
.start_hbl:
|
|
||||||
call get_firs_sym ;get first symbol on new line
|
|
||||||
test cx,cx
|
|
||||||
jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before
|
|
||||||
cmp al,'['
|
|
||||||
jnz .start_hbl
|
|
||||||
|
|
||||||
mov si,di ;point frame
|
|
||||||
mov bx,cx
|
|
||||||
mov dx,size_show_section
|
|
||||||
jmp .analisist_al
|
|
||||||
|
|
||||||
|
|
||||||
.start_bl:
|
|
||||||
call get_firs_sym ;get first symbol on new line
|
|
||||||
.first_ret_bl_sc: ;ïåðâûé âîçâðàò
|
|
||||||
test cx,cx
|
|
||||||
jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before
|
|
||||||
.analisist_al:
|
|
||||||
cmp al,'['
|
|
||||||
jnz .start_bl
|
|
||||||
;ïðîñìàòðèâàåì ini ôàéë ñ íà÷àëà â ïîèñêàõ ñåêöèè óêàçàíîé êàê default
|
|
||||||
;ïîèñê ôðåéìà â êîòîðîì ñîäåðæèòüñÿ çíà÷åíèå default
|
|
||||||
.found_sect_bl:
|
|
||||||
cmp di,point_loader
|
|
||||||
jz .start_bl
|
|
||||||
cmp di,point_default
|
|
||||||
jz .save_point_def
|
|
||||||
|
|
||||||
dec dx
|
|
||||||
jnz .start_bl
|
|
||||||
|
|
||||||
jmp .start_hbl
|
|
||||||
|
|
||||||
|
|
||||||
.save_point_def:
|
|
||||||
;èòàê äàëåå ìû äîëæíû çàïîëíèòü frame áóôåð àäðåñîâ ñåêöèé, ÷òî áû ïîòîì ïî íåìó áûñòðî ïåðåìåùàòüñÿ íå âû÷èñëÿÿ ñíîâà àäðåñà
|
|
||||||
mov di,si ;óêàçàòåëü íà íà÷àëî
|
|
||||||
mov cx,bx
|
|
||||||
lea si,point_to_hframe
|
|
||||||
mov dx,size_show_section+1 ;ò.ê. ó íàñ ñòðóêòóðà ñîäåðæèò ðàçìåð ìåæäó ïåðâûì è âòîðûì óêàçàòåëåì, òî íàì íóæíî íà 1 àäðåñ áîëüøå îáñ÷èòàòü ñåêöèé.
|
|
||||||
;ïåðåõîäèì íà îáðàáîòêó çíà÷åíèÿ óêàçàòåëÿ
|
|
||||||
mov al,byte [es:di]
|
|
||||||
push word .first_ret_mfb
|
|
||||||
cmp al,' '
|
|
||||||
jz .first_bl_mbf
|
|
||||||
jmp get_firs_sym.not_space
|
|
||||||
.first_bl_mbf:
|
|
||||||
jmp get_firs_sym.first_sp
|
|
||||||
|
|
||||||
.start_mfb:
|
|
||||||
call get_firs_sym ;get first symbol on new line
|
|
||||||
.first_ret_mfb: ;ïåðâûé âîçâðàò
|
|
||||||
jcxz .val_buff_comp ;.end_loader ;found or not found parametrs in section exit in section
|
|
||||||
cmp al,'['
|
|
||||||
jnz .start_mfb
|
|
||||||
|
|
||||||
.found_sect_mfb:
|
|
||||||
cmp di,point_loader ;if we have section loader
|
|
||||||
jz .start_mfb
|
|
||||||
|
|
||||||
mov [si],di
|
|
||||||
|
|
||||||
sub si,2
|
|
||||||
dec dx
|
|
||||||
jnz .start_mfb
|
|
||||||
;bufer is full
|
|
||||||
jmp @f
|
|
||||||
.val_buff_comp:
|
|
||||||
push save_cx
|
|
||||||
pop word [si]
|
|
||||||
sub si,2
|
|
||||||
@@:
|
|
||||||
|
|
||||||
add si,4
|
|
||||||
mov point_to_eframe,si
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
macro show_act_cursor
|
|
||||||
{
|
|
||||||
;îòîáðàæåíèå êóðñîðà ïî óìîë÷àíèþ
|
|
||||||
lea si,point_to_hframe
|
|
||||||
mov di,962-160
|
|
||||||
mov ax,point_default
|
|
||||||
mov cx,size_show_section
|
|
||||||
.home_show_cur:
|
|
||||||
mov bx,[si]
|
|
||||||
add di,160
|
|
||||||
cmp bx,ax
|
|
||||||
jz .show_cursor_activ
|
|
||||||
sub si,2
|
|
||||||
loop .home_show_cur
|
|
||||||
|
|
||||||
.show_cursor_activ:
|
|
||||||
; push 0xb800
|
|
||||||
; pop es
|
|
||||||
mov point_to_point_def,si
|
|
||||||
mov ax,(color_sym_red*0x100+0x10)
|
|
||||||
stosw
|
|
||||||
add di,68
|
|
||||||
inc ax
|
|
||||||
stosw
|
|
||||||
}
|
|
||||||
|
|
||||||
macro clear_timer_msg
|
|
||||||
{
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
xor ax,ax
|
|
||||||
if DEBUG
|
|
||||||
mov ax,0x0720
|
|
||||||
end if
|
|
||||||
;;;;;;;;;;;;;;;;;;;;; show Press any key
|
|
||||||
mov di,3360
|
|
||||||
mov cx,80*4
|
|
||||||
rep stosw
|
|
||||||
|
|
||||||
;show sect
|
|
||||||
push ini_data_
|
|
||||||
pop es
|
|
||||||
call show_bl_sc_sect ;es=0xb800
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
macro show_descript
|
|
||||||
;Ýòîò ìàêðîñ ïîêàçûâàåò êðàòêîå îïèñàíèå, åñëè îíî åñòü ó ñåêöèè â ïóíêòå
|
|
||||||
;Section description
|
|
||||||
{
|
|
||||||
local .start_p_sh_d
|
|
||||||
local .exit
|
|
||||||
local .rest_value_loop_sh_d
|
|
||||||
local .end_sh_desc_sec
|
|
||||||
local .loop_message
|
|
||||||
local .show_mess_prev_eq
|
|
||||||
mov di,point_default
|
|
||||||
push ini_data_
|
|
||||||
mov si,point_to_point_def
|
|
||||||
pop es
|
|
||||||
sub si,2
|
|
||||||
mov cx,[si] ;çàãðóçèì óêàçàòåëü íàñëåäóþùèþ ñåêöèþ
|
|
||||||
sub cx,di ;âîò òåïåðü èìååì èñòèíûé ðàçìåð
|
|
||||||
;di - óêàçàòåëü íà äåôîëòíóþ ñåêöèþ ò.å. âûáðàííóþ cx - ðàçìåð îáëàñòè. äëÿ ïðîñìîòðà
|
|
||||||
|
|
||||||
.start_p_sh_d:
|
|
||||||
call get_firs_sym ;get first symbol on new line
|
|
||||||
test cx,cx
|
|
||||||
jz .exit ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
|
|
||||||
cmp al,'d'
|
|
||||||
jnz .start_p_sh_d
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
mov bx,cx
|
|
||||||
mov ax,di
|
|
||||||
|
|
||||||
mov si,parse_descript
|
|
||||||
mov cx,parse_descript_e - parse_descript
|
|
||||||
repe cmpsb
|
|
||||||
jnz .rest_value_loop_sh_d ;is not compare
|
|
||||||
|
|
||||||
sub bx,parse_descript_e - parse_descript ;correct cx
|
|
||||||
add bx,cx
|
|
||||||
mov cx,bx
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ðàçáîð àëÿ ' = '
|
|
||||||
mov ax,0x3d20 ;cut al=' ' ah='='
|
|
||||||
repe scasb
|
|
||||||
jcxz .rest_value_loop_sh_d ;not found param timeout
|
|
||||||
|
|
||||||
cmp ah,byte [es:di-1] ;find '='
|
|
||||||
jnz .rest_value_loop_sh_d
|
|
||||||
|
|
||||||
repe scasb ;cut ' '
|
|
||||||
inc cx
|
|
||||||
dec di
|
|
||||||
;;;;;;;;;;;;;;;;;;;;di óêàçûâàåò íà ñòðî÷êó, êîòîðóþ íàì íóæíî âûâîäèòü.
|
|
||||||
;ñòðî÷êà áóäåò âûâîäèòüñÿ áëîêàìè ïî 37 ñèìâîëîâ.
|
|
||||||
;íàñòðîèì êóäà áóäåì âûâîäèòü ò.å. íà÷àëî
|
|
||||||
;es:di - óêàçûâàþò íà ñòðî÷êó èç êîòîðîé ìû áåðåì ñèìâîë, ds:si êóäà áóäåì âûâîäèòü
|
|
||||||
push di
|
|
||||||
pop si
|
|
||||||
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
|
|
||||||
mov di,1040
|
|
||||||
mov bx,18
|
|
||||||
mov find_sec_di,di
|
|
||||||
mov save_cx_d,bx
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;clean string
|
|
||||||
|
|
||||||
push di
|
|
||||||
xor ax,ax
|
|
||||||
|
|
||||||
@@: mov cx,38
|
|
||||||
push di
|
|
||||||
rep stosw
|
|
||||||
pop di
|
|
||||||
|
|
||||||
cmp save_descript_size,bx
|
|
||||||
jz @f
|
|
||||||
|
|
||||||
|
|
||||||
add di,160
|
|
||||||
dec bx
|
|
||||||
jnz @b
|
|
||||||
|
|
||||||
@@: pop di
|
|
||||||
;enter in mess
|
|
||||||
.show_mess_prev_eq:
|
|
||||||
lodsb
|
|
||||||
mov ah,color_sym_lettuce;color_sym_turquoise
|
|
||||||
; sub di,2
|
|
||||||
cmp al,'"'
|
|
||||||
jz .loop_message
|
|
||||||
cmp al,"'"
|
|
||||||
jnz .end_sh_desc_sec
|
|
||||||
|
|
||||||
.loop_message:
|
|
||||||
mov cx,38
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
cmp al,'"'
|
|
||||||
jz .end_sh_desc_sec
|
|
||||||
cmp al,"'"
|
|
||||||
jz .end_sh_desc_sec
|
|
||||||
stosw
|
|
||||||
loop @b
|
|
||||||
|
|
||||||
add find_sec_di,160
|
|
||||||
mov di,find_sec_di
|
|
||||||
dec save_cx_d
|
|
||||||
cmp save_cx_d,0
|
|
||||||
jnz .loop_message
|
|
||||||
|
|
||||||
.end_sh_desc_sec:
|
|
||||||
push save_cx_d
|
|
||||||
pop save_descript_size
|
|
||||||
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
jmp .exit
|
|
||||||
|
|
||||||
|
|
||||||
.rest_value_loop_sh_d:
|
|
||||||
mov di,ax
|
|
||||||
mov cx,bx
|
|
||||||
jmp .start_p_sh_d
|
|
||||||
|
|
||||||
.exit:
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
;Òóò ïðåäñòàâëåííû òåãè, äëÿ ñðàâíåíèÿ
|
|
||||||
parse_loader db '[loader]'
|
|
||||||
parse_loader_e:
|
|
||||||
parse_l_timeout db 'timeout'
|
|
||||||
parse_l_timeout_e:
|
|
||||||
parse_l_default db 'default'
|
|
||||||
parse_l_default_e:
|
|
||||||
parse_name db 'ame'
|
|
||||||
parse_name_e:
|
|
||||||
parse_descript db 'descript'
|
|
||||||
parse_descript_e:
|
|
||||||
|
|
||||||
parse_LoaderModule db 'LoaderModule'
|
|
||||||
parse_LoaderModule_e:
|
|
||||||
parse_RamdiskSize db 'RamdiskSize'
|
|
||||||
parse_RamdiskSize_e:
|
|
||||||
parse_RamdiskFS db 'RamdiskFS'
|
|
||||||
parse_RamdiskFS_e:
|
|
||||||
parse_RamdiskSector db 'RamdiskSector'
|
|
||||||
parse_RamdiskSector_e:
|
|
||||||
parse_RamdiskCluster db 'RamdiskCluster'
|
|
||||||
parse_RamdiskCluster_e:
|
|
||||||
parse_RFS_FAT db 'FAT'
|
|
||||||
parse_RFS_FAT_e:
|
|
||||||
parse_RFS_KRFS db 'KRFS'
|
|
||||||
parse_RFS_KRFS_e:
|
|
||||||
parse_Loader_Image db 'LoaderImage'
|
|
||||||
parse_Loader_Image_e:
|
|
||||||
parse_RamdiskFile db 'RamdiskFile'
|
|
||||||
parse_RamdiskFile_e:
|
|
File diff suppressed because it is too large
Load Diff
@ -1,66 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
error:
|
|
||||||
.rest_value:
|
|
||||||
mov di,ax ;restore value after repe cmpsb
|
|
||||||
mov cx,bx
|
|
||||||
jmp ret_on_ch ;return
|
|
||||||
|
|
||||||
;///// îøèáêà ïðè íàõîäæåíèè äëèííû ñåêöèè â ïàðàìåòðå default
|
|
||||||
.error_get_size_d_sect:
|
|
||||||
leave ;clear array in stack
|
|
||||||
mov si,not_found_def_sect
|
|
||||||
jmp err_show_ini
|
|
||||||
|
|
||||||
;/////ERROR
|
|
||||||
.not_loader:
|
|
||||||
leave ;clear array in stack
|
|
||||||
mov si,not_found_sec_loader
|
|
||||||
jmp err_show_ini
|
|
||||||
|
|
||||||
.default_eq_loader: ;êðèòè÷åñêàÿ îøèáêà default ñåêöèÿ = loader
|
|
||||||
leave
|
|
||||||
mov si,default_eq_loader
|
|
||||||
jmp err_show_ini
|
|
||||||
.correct_exit_bl:
|
|
||||||
leave
|
|
||||||
mov si,point_to_default_sec_not_found
|
|
||||||
jmp err_show_ini
|
|
||||||
.incorect_section_def:
|
|
||||||
leave
|
|
||||||
mov si,incorect_section_define
|
|
||||||
jmp err_show_ini
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;show message error
|
|
||||||
.LoaderModule:
|
|
||||||
push word 0xb800
|
|
||||||
pop es
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ret
|
|
@ -1,332 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
;áëîê ìàêðîñîâ ïî îáðàáîòêå ñåêöèè [loader]
|
|
||||||
;âõîäíûå äàííûå:
|
|
||||||
;es:di - óêàçàòåëü íà ñåêöèþ íà÷èíàþùèþñÿ ñ '[' âñòå÷àþùèþñÿ ïîñëå 0õa
|
|
||||||
;cx - ñ÷åò÷èê êîë-âî áàéò äëÿ ïðîâåðêå â êàäðå
|
|
||||||
;
|
|
||||||
macro use_parse_loader
|
|
||||||
{
|
|
||||||
.parse_loader:
|
|
||||||
;//////////////////
|
|
||||||
;/ parse [loader]
|
|
||||||
;//////////////////
|
|
||||||
mov bx,cx ;cîõðàíèì â ðåãèñòðû çíà÷åíèÿ ñ÷åò÷èêà è óêàçàòåëÿ
|
|
||||||
mov ax,di
|
|
||||||
|
|
||||||
; mov word [bp-4],.start ;is alredy set, see up
|
|
||||||
mov si,parse_loader
|
|
||||||
mov cx,parse_loader_e - parse_loader
|
|
||||||
repe cmpsb
|
|
||||||
jnz error.rest_value ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå ò.å. áóäåì ñíîâà èñêàòü))
|
|
||||||
|
|
||||||
;ñîõðàíèì óêàçàòåëüíà loader, ÷òî áû ïîòîì áîëüøå åãî íå èñêàòü
|
|
||||||
mov point_loader,ax
|
|
||||||
sub bx,parse_loader_e - parse_loader ;correct cx
|
|
||||||
add bx,cx
|
|
||||||
mov cx,bx
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
pusha
|
|
||||||
mov si,lm_l_found
|
|
||||||
call printplain
|
|
||||||
popa
|
|
||||||
end if
|
|
||||||
;/////////////////end check [loader]. [loader] is found
|
|
||||||
;parsing section [loader]
|
|
||||||
;first found end section,let's found '[' -it's start next section
|
|
||||||
;in previosly steep bx =cx we are not need save cx, save only di - point
|
|
||||||
mov dx,di
|
|
||||||
@@:
|
|
||||||
call get_firs_sym
|
|
||||||
jcxz .loader_f_end ;.end_loader ; end äàæå åñëè ìû íå íàøëè ñåêöèþ ïðåäïîëîæèì ÷òî ñåêöèÿ [loader] ñòîèò â êîíöå
|
|
||||||
cmp al,'['
|
|
||||||
jnz @b
|
|
||||||
|
|
||||||
.loader_f_end:
|
|
||||||
sub bx,cx ;bx = n byte presend in section [loader]
|
|
||||||
mov di,dx ;restore di
|
|
||||||
;////////////////parse parametrs in section [loader]
|
|
||||||
;//timeout=5
|
|
||||||
;//default=main
|
|
||||||
; mov di,dx ;set pointer on section [loader] i think it's not need
|
|
||||||
mov cx,bx ;set counter for parsing section [loader] cx= êîë-âó ñèìâîëîâ â ñåêöèè [loader]
|
|
||||||
mov ret_on_ch,.get_next_str ; return point
|
|
||||||
;;;;;;; parse timeout & default
|
|
||||||
.get_next_str:
|
|
||||||
call get_firs_sym ;get first symbol on new line
|
|
||||||
|
|
||||||
test cx,cx
|
|
||||||
jz .end_loader
|
|
||||||
; jcxz .end_loader ;çàâåðøåíèå ïàðñèíãà çíà÷åíèé timeout & default
|
|
||||||
cmp al,'t'
|
|
||||||
jz .loader_timeout
|
|
||||||
cmp al,'d'
|
|
||||||
jnz .get_next_str
|
|
||||||
;//////[loader].default
|
|
||||||
;input di point to data cx=size [loader]
|
|
||||||
mov bx,cx
|
|
||||||
mov ax,di
|
|
||||||
|
|
||||||
mov si,parse_l_default
|
|
||||||
mov cx,parse_l_default_e - parse_l_default
|
|
||||||
repe cmpsb
|
|
||||||
|
|
||||||
jnz error.rest_value ;is not compare öåïî÷êà íå ñîâïàëà
|
|
||||||
|
|
||||||
sub bx,parse_l_default_e - parse_l_default ;correct cx
|
|
||||||
add bx,cx
|
|
||||||
mov cx,bx
|
|
||||||
|
|
||||||
test status_flag,flag_found_default
|
|
||||||
jz .correct_is_not_set
|
|
||||||
|
|
||||||
mov si,found_equal_default ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
|
|
||||||
call printplain
|
|
||||||
jmp .get_next_str
|
|
||||||
|
|
||||||
.correct_is_not_set:
|
|
||||||
mov ax,0x3d20 ;cut al=' ' ah='='
|
|
||||||
repe scasb
|
|
||||||
test cx,cx
|
|
||||||
jz .end_loader
|
|
||||||
|
|
||||||
cmp ah,byte [es:di-1] ;find '='
|
|
||||||
jnz .get_next_str
|
|
||||||
|
|
||||||
repe scasb ;cut ' '
|
|
||||||
inc cx
|
|
||||||
dec di
|
|
||||||
;ñåé÷àñ es:di óêàçûâàþò íà íàçâàíèå ñåêöèè, èìÿ ñåêöèè ïî äåôîëòó íå äîëæíî áûòü loader ò.å. èíà÷å âîçìîæíî çàöèêëèâàíèå
|
|
||||||
;óñòàíîâèì óêàçàòåëü si íà ýòî çíà÷åíèå è ñíà÷àëà ïðîâåðèì
|
|
||||||
|
|
||||||
;ïîëó÷åíèå äëèííû ñåêöèè
|
|
||||||
; cx=bx ñîäåðæèò äëèííó îñòàòêà ñåêöèè
|
|
||||||
; di=ax óêàçàòåëü íà òåêóùèþ ñåêöèþ
|
|
||||||
mov bx,cx
|
|
||||||
mov dx,di
|
|
||||||
|
|
||||||
@@: mov al,byte [es:di]
|
|
||||||
inc di
|
|
||||||
dec cx
|
|
||||||
test cx,cx
|
|
||||||
jz error.error_get_size_d_sect ;ïåðåõîä íà îáðàáîòêó îøèáêè ïî íàõîæäåíèþ äëèíû äåôîëòíîé ñåêöèè
|
|
||||||
cmp al,' '
|
|
||||||
jz @b
|
|
||||||
cmp al,0xd
|
|
||||||
jz .found_size_d_sect
|
|
||||||
cmp al,0xa
|
|
||||||
jnz @b
|
|
||||||
.found_size_d_sect:
|
|
||||||
;
|
|
||||||
inc cx ;correct cx
|
|
||||||
mov ax,bx
|
|
||||||
sub bx,cx ; â bx äëèíà ñåêöèè êîòîðàÿ îïðåäåëåíà ïî äåôîëòó
|
|
||||||
mov save_cx_d,bx
|
|
||||||
mov di,dx
|
|
||||||
|
|
||||||
mov cx,bx ;set size default section
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ïðîâåðêà íà =loader
|
|
||||||
;save in reg point and ñ÷åò÷èê
|
|
||||||
;check on loader
|
|
||||||
mov bx,ax
|
|
||||||
mov ax,dx
|
|
||||||
|
|
||||||
mov si,parse_loader
|
|
||||||
inc si ;set only loader and 6 char in counter
|
|
||||||
repe cmpsb
|
|
||||||
jnz .check_section ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå )) çíà÷èò íå èñêëþ÷åíèå
|
|
||||||
|
|
||||||
jmp error.default_eq_loader ;error êðèòè÷åñêàÿ îøèáêà ò.å. â äåôîëòå ïðèñóòñòâóåò èìÿ [loader]
|
|
||||||
|
|
||||||
.check_section: ;ïîèñê ñîîòâåòñòâóþùåé ñåêöèè íàì íóæíî áóäåò óçíàòü àäðåñ ýòîé ñåêöèè
|
|
||||||
mov cx,bx
|
|
||||||
mov di,ax
|
|
||||||
|
|
||||||
;/////////////////////////////
|
|
||||||
; mov ret_on_ch,.start_d ;set return
|
|
||||||
mov si,di ;óñòàíîâèì óêàçàòåëü íà íàøó ñåêöèþ, êîòîðàÿ ïî äåôîëòó
|
|
||||||
|
|
||||||
push di ;save point di
|
|
||||||
|
|
||||||
push cx ;save cx
|
|
||||||
;óñòàíîâèì óêàçàòåëü es:di íà íà÷àëî ini ôàéëà
|
|
||||||
mov cx,save_cx ;it's placed size of ini file
|
|
||||||
les di,dword [file_data]
|
|
||||||
|
|
||||||
|
|
||||||
mov al,byte [es:di]
|
|
||||||
push word .first_ret_d
|
|
||||||
cmp al,' '
|
|
||||||
jz .first_sp_1_d
|
|
||||||
jmp get_firs_sym.not_space
|
|
||||||
.first_sp_1_d:
|
|
||||||
jmp get_firs_sym.first_sp
|
|
||||||
|
|
||||||
.start_d:
|
|
||||||
call get_firs_sym ;get first symbol on new line
|
|
||||||
.first_ret_d: ;ïåðâûé âîçâðàò
|
|
||||||
jcxz .correct_exit ;.end_loader ;found or not found parametrs in section exit in section
|
|
||||||
cmp al,'['
|
|
||||||
jz .found_sect_d
|
|
||||||
jmp .start_d
|
|
||||||
;ïðîñìàòðèâàåì ini ôàéë ñ íà÷àëà â ïîèñêàõ ñåêöèè óêàçàíîé êàê default
|
|
||||||
;èäåò ïðîâåðêà íà íàëè÷åå çíà÷åíèÿ timeout, äëÿ áîëåå áûñòðîé ðàáîòû, ýòîò ïàðàìåòð äîëæåí áûòü óæå îáðàáîòàí,ò.å. â ýòîì ñëó÷àå ïðè åãî =0 áóäåò ñôîðìèðîâàí óêàçàòåëü òîëüêî íà äåôîëòíóþ ñåêöèþ, èíà÷å èíôîðìàöèÿ áóäåò ñîáðàíà ïî âñåì ñåêöèÿì è ñîñòàâëåíû óêàçàòåëè â áëîêå ïàìÿòè
|
|
||||||
.found_sect_d:
|
|
||||||
|
|
||||||
;check on name section
|
|
||||||
mov bx,cx
|
|
||||||
mov ax,di
|
|
||||||
push si ;save point
|
|
||||||
|
|
||||||
; mov si,parse_loader
|
|
||||||
mov cx,save_cx_d ;load size section
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
inc di
|
|
||||||
repe cmpsb
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
pop si
|
|
||||||
|
|
||||||
jnz .not_compare_d_s ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå )) çíà÷èò íå èñêëþ÷åíèå
|
|
||||||
cmp byte[es:di],']'
|
|
||||||
jnz .not_compare_d_s ;íåò â êîíöå íàøåé ñåêöèè çàâåðøàþùåãî ñèìâîëà :(
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;set flag -we have found default -not enter again in this prosedure
|
|
||||||
or status_flag,flag_found_default
|
|
||||||
pop cx
|
|
||||||
pop di
|
|
||||||
mov point_default,ax ;point to [
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
pusha
|
|
||||||
mov si,lm_lf_default_f
|
|
||||||
call printplain
|
|
||||||
popa
|
|
||||||
end if
|
|
||||||
|
|
||||||
jmp .get_next_str
|
|
||||||
|
|
||||||
.not_compare_d_s:
|
|
||||||
|
|
||||||
mov cx,bx
|
|
||||||
mov di,ax
|
|
||||||
jmp .start_d
|
|
||||||
|
|
||||||
.correct_exit:
|
|
||||||
pop cx ;âîññòàíîâèì çíà÷åíèå ñ÷åò÷èêà
|
|
||||||
pop di
|
|
||||||
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
pusha
|
|
||||||
mov si,lm_lf_default
|
|
||||||
call printplain
|
|
||||||
popa
|
|
||||||
end if
|
|
||||||
jmp .get_next_str
|
|
||||||
|
|
||||||
;//////////[loader].timeout
|
|
||||||
.loader_timeout:
|
|
||||||
mov bx,cx
|
|
||||||
mov ax,di
|
|
||||||
|
|
||||||
mov si,parse_l_timeout
|
|
||||||
mov cx,parse_l_timeout_e - parse_l_timeout
|
|
||||||
repe cmpsb
|
|
||||||
jnz error.rest_value ;is not compare
|
|
||||||
|
|
||||||
sub bx,parse_l_timeout_e - parse_l_timeout ;correct cx
|
|
||||||
add bx,cx
|
|
||||||
mov cx,bx
|
|
||||||
|
|
||||||
test status_flag,flag_found_timeout
|
|
||||||
jz .correct_is_not_set_t
|
|
||||||
|
|
||||||
mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
|
|
||||||
call printplain
|
|
||||||
jmp .get_next_str
|
|
||||||
|
|
||||||
.correct_is_not_set_t:
|
|
||||||
mov ax,0x3d20 ;cut al=' ' ah='='
|
|
||||||
repe scasb
|
|
||||||
jcxz .timeout_sec_end_d ;not found param timeout
|
|
||||||
|
|
||||||
cmp ah,byte [es:di-1] ;find '='
|
|
||||||
jnz .get_next_str
|
|
||||||
|
|
||||||
repe scasb ;cut ' '
|
|
||||||
inc cx
|
|
||||||
dec di
|
|
||||||
;get timeout value
|
|
||||||
;2 çíàêa ìîæåò áûòü îáðàáîòàíî ò.å. çíà÷åíèå îò 0 äî 99 ñåêóíä
|
|
||||||
push cx
|
|
||||||
xor bx,bx
|
|
||||||
mov cx,2
|
|
||||||
@@: mov al,byte [es:di]
|
|
||||||
cmp al,'0'
|
|
||||||
jb .end_get_val_t
|
|
||||||
cmp al,'9'
|
|
||||||
ja .end_get_val_t
|
|
||||||
imul bx,10
|
|
||||||
xor al,0x30
|
|
||||||
add bl,al
|
|
||||||
.end_get_val_t:
|
|
||||||
inc di
|
|
||||||
loop @b
|
|
||||||
mov word [value_timeout],bx
|
|
||||||
; pop cx
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
pusha
|
|
||||||
mov si,lm_lf_timeout
|
|
||||||
call printplain
|
|
||||||
popa
|
|
||||||
end if
|
|
||||||
|
|
||||||
jmp @f
|
|
||||||
.timeout_sec_end_d:
|
|
||||||
mov word [value_timeout],default_timeout_value
|
|
||||||
mov si,set_default_timeout_val
|
|
||||||
call printplain
|
|
||||||
@@: pop cx
|
|
||||||
jmp .get_next_str
|
|
||||||
|
|
||||||
;///////here end block loader
|
|
||||||
.end_loader:
|
|
||||||
if DEBUG
|
|
||||||
pusha
|
|
||||||
mov si,lm_l_end
|
|
||||||
call printplain
|
|
||||||
popa
|
|
||||||
end if
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
; Copyright (c) 2008-2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
; Ïðåäîïðåäåëåíèÿ
|
|
||||||
DEBUG equ 1 ;êîìïèëÿöèÿ ñ îòëàäî÷íîé èíôîðìàöèåé =1 áåç îòëàäî÷íîé èíôîðàöèè =0
|
|
||||||
loop_read_startos_file equ 3 ;êîë-âî ïîïûòîê ñ÷èòàòü ÷åðåç callback ñåðâèñ ôàéë êîíôèãóðàöèè áëîê2
|
|
||||||
root_dir_entry_count equ 224 ;êîë-âî ýëåìåíòîâ â êîðíåâîé äèððåêòîðèè
|
|
||||||
;point_to_fat_struc equ 0xA000 ;âðåìåííûé áóôåð, êóäà áóäåò ðàçìåùåíà Fat òàáëèöà, è çàòåì ïåðåíåñåíà çà 1 ìá
|
|
||||||
ini_data_ equ 0x2000 ;ôàéë ãäå ðàçìåùåí ôàéë ñöåíàðèÿ çàãðóçêè, òàì ïðîèñõîäèò ñèíòàêñè÷åñêèé ðàçáîð
|
|
||||||
size_show_section equ 18
|
|
||||||
default_timeout_value equ 5 ;default value to timeout is will was some errors
|
|
||||||
flag_found_default equ 0x1 ;default value is found
|
|
||||||
flag_found_timeout equ 0x2 ;timeout value is found
|
|
||||||
flag_found_LM equ 0x1 ;found LM value
|
|
||||||
flag_found_RS equ 0x2 ;found RS value
|
|
||||||
flag_found_GTRFMS equ 0x4 ;found type RamFS
|
|
||||||
flag_found_RamdiskSector equ 0x8 ;found RamdiskSector
|
|
||||||
flag_found_RamdiskCluster equ 0x16 ;found RamdiskCluster
|
|
||||||
;statick data ýòè äàííûå íå ïðåäîïðåäåëÿþòñÿ â òå÷åíèè âûïîëíåíèÿ âñåé ïðîãðàììû.
|
|
||||||
save_cx equ word [bp-2] ;save cx size ini file
|
|
||||||
ret_on_ch equ word [bp-4] ;point to return ðàçðóøàåìîå çíà÷åíèå
|
|
||||||
save_cx_d equ word [bp-6] ;save cx - size default section and working section
|
|
||||||
status_flag equ word [bp-8] ;status flag
|
|
||||||
point_loader equ word [bp-10]
|
|
||||||
point_default equ word [bp-12] ;point to default
|
|
||||||
|
|
||||||
;äàííûå êîòîðûå çàâèñèìû îò âåòêè âûïîëíåíèÿ è êîòîðûå ìîãóò áûòü ïåðåîïðåäåëåíû â ïðîöåññå âûïîëíåíèÿ ïðîãðàììû.
|
|
||||||
point_to_hframe equ word [bp-14] ;point on start frame (for change section)
|
|
||||||
point_to_1 equ word [bp-16]
|
|
||||||
point_to_2 equ word [bp-18]
|
|
||||||
point_to_3 equ word [bp-20]
|
|
||||||
point_to_4 equ word [bp-22]
|
|
||||||
point_to_5 equ word [bp-24]
|
|
||||||
point_to_6 equ word [bp-26]
|
|
||||||
point_to_7 equ word [bp-28]
|
|
||||||
point_to_8 equ word [bp-30]
|
|
||||||
point_to_9 equ word [bp-32]
|
|
||||||
point_to_10 equ word [bp-34]
|
|
||||||
point_to_11 equ word [bp-36]
|
|
||||||
point_to_12 equ word [bp-38]
|
|
||||||
point_to_13 equ word [bp-40]
|
|
||||||
point_to_14 equ word [bp-42]
|
|
||||||
point_to_15 equ word [bp-44]
|
|
||||||
point_to_16 equ word [bp-46]
|
|
||||||
point_to_16 equ word [bp-48]
|
|
||||||
point_to_17 equ word [bp-50]
|
|
||||||
point_to_18 equ word [bp-52]
|
|
||||||
;here array for fast scroling 16 word - poin to start section
|
|
||||||
point_to_point_def equ word [bp-54]
|
|
||||||
point_to_eframe equ word [bp-56] ;point on point frame
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; òóò ðàñïîëîæåíî âðåìåííîå õðàíèëèùå äëÿ cx è di ïðè ïåðåõîäå íà ñëåäóþùèé áóôåð ïðè ïîèñêå ñåêöèé
|
|
||||||
find_sec_di equ word [bp-58] ;òóò áóäåò õðàíèòüñÿ di
|
|
||||||
info_real_mode_size equ word [bp-60];òóò õðàíèòüñÿ èíôîðìàöèÿ î çàíÿòîé îáëàñòè ò.å. ðàçìåð, ìîæíî óçíàòü ñêîëüêî îñòàëîñü ìåñòà âû÷èñëèâ
|
|
||||||
free_ad_memory equ word [bp-62] ;ñêîëüêî ó íàñ ðàñøèðåííîé ïàìÿòè äëÿ ôîðìèðîâàíèÿ ðàì äèñêà è çàãðóçêè ìîäóëåé
|
|
||||||
show_errors_sect equ word [bp-64] ;ïåðåìåíàÿ êîòîðàÿ õðàíèò áèòû îøèáîê äëÿ êàæäîé ëîãè÷åñêîé ñåêöèè.
|
|
||||||
save_descript_size equ word [bp-66] ;save descript size previos section ñîõðàíèì ðàçìåð ïðåäûäóùåé ñåêöèè êîòîðóþ âûâîäèëè
|
|
||||||
save_ramdisksize equ dword [bp-70] ;save size of ramdisk in byte
|
|
||||||
save_file_size equ dword [bp-74] ;save size of reading file
|
|
||||||
set_ramfs equ word [bp-76] ;îïðåäåëåííûé òèï ôàéëîâîé ñèñòåìû,íóæíî äëÿ ôîðìèðîâàíèÿ ðàì äèñêà
|
|
||||||
point_next_fat_str equ word [bp-78] ;óêàçàòåëü íà ñëåäóþùèé ýëåìåíò fat òàáëèöû
|
|
||||||
size_root_dir equ word [bp-80] ;êîë-âî ýëåìåíòîâ â ñåêòîðàõ ïî 512 áàéò êîðíåâîé äèðåêòîðèè
|
|
||||||
firstDataSect equ word [bp-82] ;ïåðâûé ñåêòîð äàííûõ â ñåòîðàõ îò 0
|
|
||||||
DataClasters equ word [bp-84] ;ðàçìåð ìàññèâà äîñòóïíîé äëÿ çàïèñè äàííûõ â êëàñòåðàõ.
|
|
||||||
point_to_free_root equ word [bp-86] ;óêàçàòåëü íà ñëåäóþùèé ïóñòóþ çàïèñü â ðóò äèð
|
|
||||||
point_to_dest_file_name equ word [bp-88] ;óêàçûâàåò íà íà÷àëî èìåíè ôàéëà íàçíà÷åíèÿ. â ôîðìàòå es:point_to_dest_file_name, ãäå es =0x2000
|
|
||||||
data_offset equ word [bp-90] ;ñìåùåíèå â êëàñòåðàõ äëÿ çàïèñàííûõ äàííûõ ò.å ïåðåêèíóòûõ çà 1-é ìá
|
|
||||||
first_input equ word [bp-92] ;ïîëå äëÿ ôëàãîâ â ïðåîáðàçîâàíèè èìåíè.
|
|
||||||
save_di_RAMDISK equ word [bp-94] ;ñîõðàíèì di -óêàçàòåëÿ ïðè îáðàáîòêå ñåêöèè
|
|
||||||
save_cx_RAMDISK equ word [bp-96] ;ñîõðàíèì ðàçìåð îñòàòêà ñåêöèè
|
|
||||||
status_flag_loader_f equ word [bp-98] ;ñîõðàíèì ðåçóëüòàò âûïîëåíåíèÿ çàãðóçêè ôàéëà
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;äàííûå êîòîðûå èñïîëüçóþòñÿ ïðè îáðàáîòêå ñåêöèè, ò.å. ïîñëå íàæàòèÿ Enter, óæå íå âîçìîæíî âåðíóòüñÿ â ïåðâîíà÷àëüíûé ýêðàí
|
|
||||||
;äëÿ âîçâðàòà, íåîáõîäèìî ïåðåçàïóñòèòü ïîëíîñòüþ êîä ò.å. ñòàðòîâàòü ñ 0õ1000:0000
|
|
@ -1,524 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
; òóò îïèñûâàþòñÿ ïðîöåäóðû êîòîðûå èñïîëüçóþòñÿ â secondary loader
|
|
||||||
color_sym_black equ 0
|
|
||||||
color_sym_blue equ 1
|
|
||||||
color_sym_green equ 2
|
|
||||||
color_sym_turquoise equ 3
|
|
||||||
color_sym_red equ 4
|
|
||||||
|
|
||||||
color_sym_lightgray equ 7
|
|
||||||
|
|
||||||
color_sym_lightblue equ 9
|
|
||||||
color_sym_lettuce equ 10
|
|
||||||
color_sym_pink equ 12
|
|
||||||
color_sym_yellow equ 14
|
|
||||||
color_sym_white equ 15
|
|
||||||
if DEBUG
|
|
||||||
decode:
|
|
||||||
;input eax - ÷èñëî, es:di êóäà ïèñàòü, cx=10
|
|
||||||
cmp eax,ecx
|
|
||||||
jb @f
|
|
||||||
xor edx,edx
|
|
||||||
div ecx
|
|
||||||
push edx
|
|
||||||
call decode
|
|
||||||
pop eax
|
|
||||||
@@: or al,0x30
|
|
||||||
mov [ds:di],al
|
|
||||||
inc di
|
|
||||||
ret
|
|
||||||
|
|
||||||
end if
|
|
||||||
|
|
||||||
|
|
||||||
putchar:
|
|
||||||
; in: al=character
|
|
||||||
mov ah, 0Eh
|
|
||||||
mov bh, 0
|
|
||||||
int 10h
|
|
||||||
ret
|
|
||||||
|
|
||||||
printplain:
|
|
||||||
; in: si->string
|
|
||||||
pushad
|
|
||||||
lodsb
|
|
||||||
@@:
|
|
||||||
call putchar
|
|
||||||
lodsb
|
|
||||||
test al,al
|
|
||||||
jnz @b
|
|
||||||
mov al,13
|
|
||||||
call putchar
|
|
||||||
|
|
||||||
mov al,10
|
|
||||||
call putchar
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
getkey:
|
|
||||||
; get number in range [bl,bh] (bl,bh in ['0'..'9'])
|
|
||||||
; in: bx=range
|
|
||||||
; out: ax=digit (1..9, 10 for 0)
|
|
||||||
mov ah, 0
|
|
||||||
int 16h
|
|
||||||
cmp al, bl
|
|
||||||
jb getkey
|
|
||||||
cmp al, bh
|
|
||||||
ja getkey
|
|
||||||
push ax
|
|
||||||
call putchar
|
|
||||||
pop ax
|
|
||||||
and ax, 0Fh
|
|
||||||
jnz @f
|
|
||||||
mov al, 10
|
|
||||||
@@:
|
|
||||||
ret
|
|
||||||
|
|
||||||
;setcursor:
|
|
||||||
; in: dl=column, dh=row
|
|
||||||
; mov ah, 2
|
|
||||||
; mov bh, 0
|
|
||||||
; int 10h
|
|
||||||
; ret
|
|
||||||
|
|
||||||
;macro _setcursor row,column
|
|
||||||
;{
|
|
||||||
; mov dx, row*256 + column
|
|
||||||
; call setcursor
|
|
||||||
;}
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
get_firs_sym:
|
|
||||||
.start:
|
|
||||||
mov al,byte [es:di]
|
|
||||||
inc di
|
|
||||||
dec cx
|
|
||||||
jcxz .exit
|
|
||||||
|
|
||||||
cmp al,0xa ;cmp al,0xa
|
|
||||||
jz ._entry
|
|
||||||
|
|
||||||
cmp al,';'
|
|
||||||
jnz .start
|
|
||||||
|
|
||||||
.first_com:
|
|
||||||
|
|
||||||
mov al,0xa
|
|
||||||
repnz scasb
|
|
||||||
jcxz .exit
|
|
||||||
._entry:
|
|
||||||
mov al,byte [es:di]
|
|
||||||
.first_sp:
|
|
||||||
cmp al,' '
|
|
||||||
jnz .not_space
|
|
||||||
|
|
||||||
; mov al,' ' ;cut ' '
|
|
||||||
repe scasb
|
|
||||||
dec di
|
|
||||||
inc cx
|
|
||||||
mov al,byte [es:di]
|
|
||||||
.not_space:
|
|
||||||
cmp al,';'
|
|
||||||
jz .first_com
|
|
||||||
.exit: ret
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
show_name_section:
|
|
||||||
push si
|
|
||||||
push ini_data_
|
|
||||||
pop es
|
|
||||||
|
|
||||||
|
|
||||||
mov al,']'
|
|
||||||
repnz scasb
|
|
||||||
test cx,cx
|
|
||||||
jz error.incorect_section_def
|
|
||||||
.find_val_name_fb1:
|
|
||||||
mov al,'n'
|
|
||||||
.find_val_name_fb:
|
|
||||||
repnz scasb
|
|
||||||
jcxz .not_name_sec_fb
|
|
||||||
|
|
||||||
mov si,parse_name
|
|
||||||
|
|
||||||
push cx
|
|
||||||
push di
|
|
||||||
|
|
||||||
mov cx,parse_name_e -parse_name
|
|
||||||
repe cmpsb
|
|
||||||
pop di
|
|
||||||
pop cx
|
|
||||||
jz .yaaa_find_value
|
|
||||||
|
|
||||||
|
|
||||||
jmp .find_val_name_fb
|
|
||||||
|
|
||||||
.yaaa_find_value:
|
|
||||||
sub cx,parse_name_e -parse_name
|
|
||||||
add di,parse_name_e -parse_name
|
|
||||||
|
|
||||||
mov ax,0x3d20 ; ah='='
|
|
||||||
repe scasb
|
|
||||||
test cx,cx
|
|
||||||
jz .not_name_sec_fb
|
|
||||||
|
|
||||||
cmp ah,byte [es:di-1] ;find '='
|
|
||||||
jnz .find_val_name_fb1
|
|
||||||
|
|
||||||
repe scasb ;cut ' '
|
|
||||||
inc cx
|
|
||||||
dec di
|
|
||||||
|
|
||||||
|
|
||||||
;âñå âûðåçàëè è âñå ãîòîâî äëÿ âûâîäà èìåíè ñåêöèè ))
|
|
||||||
push es
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
.def_sect_name:
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
;clear array for message
|
|
||||||
xor ax,ax
|
|
||||||
if DEBUG
|
|
||||||
mov ax,0x0720
|
|
||||||
end if
|
|
||||||
|
|
||||||
mov cx,39
|
|
||||||
mov si,di
|
|
||||||
mov di,dx
|
|
||||||
sub di,2
|
|
||||||
rep stosw
|
|
||||||
;//////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
mov di,dx
|
|
||||||
mov ah,color_sym_white;color_sym_lightblue
|
|
||||||
mov cx,36
|
|
||||||
lodsb
|
|
||||||
sub di,2
|
|
||||||
cmp al,'"'
|
|
||||||
jz @f
|
|
||||||
cmp al,"'"
|
|
||||||
jnz .end_sh_name_sec
|
|
||||||
@@: lodsb
|
|
||||||
@@:
|
|
||||||
stosw
|
|
||||||
lodsb
|
|
||||||
cmp al,'"'
|
|
||||||
jz .end_sh_name_sec
|
|
||||||
cmp al,"'"
|
|
||||||
jz .end_sh_name_sec
|
|
||||||
loop @b
|
|
||||||
|
|
||||||
mov al,'}'
|
|
||||||
mov ah,color_sym_yellow
|
|
||||||
stosw
|
|
||||||
.end_sh_name_sec:
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
pop si
|
|
||||||
ret
|
|
||||||
|
|
||||||
.not_name_sec_fb: ;íåò èìåíè â íàçâàíèè ñåêöèè - çíà÷èò òàê è ñêàæåì îá ýòîì
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
mov di,default_section_name
|
|
||||||
jmp .def_sect_name
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;ïðîöåäóðà ïîèñêà ââåðõ ñëåäóþùåé ñåêöèè
|
|
||||||
;â point_default ñîäåðæèòüñÿ óêàçàòåëü íà äåôàóëò ñåêöèþ, è â ïðåäåëàõ âðåéìà ìû áåãàåì ïî çàðàíåå ïðîïàðñåíûìè çíà÷åíèÿì óêàçàòåëåé
|
|
||||||
;äëÿ òîãî ÷òî áû îòîáðàçèòü è ïðîïàðñèòü ñëåäóþùèé ôðåéì, íàì íóæíî ïîëó÷èòü çà ïåðäûäóùèé èëè ñëåäóþùèé óêàçàòåëü
|
|
||||||
find_before_sect:
|
|
||||||
mov di,point_default
|
|
||||||
.e:
|
|
||||||
push ini_data_
|
|
||||||
pop es
|
|
||||||
mov cx,di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê íà÷àëó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ
|
|
||||||
mov bx,cx ;êîïèÿ
|
|
||||||
|
|
||||||
;íàñòðîèëè óêàçàòåëü íà äåôàóëò ñåêöèþ
|
|
||||||
;áóäåì èñêàòü ââåðõ
|
|
||||||
.find_start_section:
|
|
||||||
std ;óñòàíîâêà ôëàãà íàïðàâëåíèÿ - áóäåì ïðîñìàòèðâàòü ê íà÷àëó íàøåãî èíè ôàéëà
|
|
||||||
;áóäåì èñêàòü íà÷àëî ñåêöèè ò.å. '[' ýòîò ñèìâîë
|
|
||||||
mov al,0xa
|
|
||||||
repnz scasb ;ïðîñêàíèðóåì íà íàëè÷åå ñèìâîëà íà÷àëà ñåêöèè
|
|
||||||
jcxz .go_ ;ìû ïðîñìîòðåëè äî íà÷àëà ôàéëà, íî òàê è íè÷åãî íå íàøëè ;(( ïî òèõîìó âûéäåì )
|
|
||||||
|
|
||||||
mov find_sec_di,di ;ñîõðàíèì äàííûå
|
|
||||||
mov cx,di ;
|
|
||||||
|
|
||||||
sub bx,cx
|
|
||||||
mov cx,bx ;â ñx çíà÷åíèå - êîë-âî ñèìâîëîâ
|
|
||||||
cld
|
|
||||||
call get_firs_sym
|
|
||||||
.ret_go:
|
|
||||||
jcxz ._not_section ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå
|
|
||||||
|
|
||||||
cmp di,point_loader ; ñåêöèþ loader ìû íå çàíîñèì èíà÷å êðàõ
|
|
||||||
jz ._not_section
|
|
||||||
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé
|
|
||||||
cmp al,'['
|
|
||||||
jnz ._not_section
|
|
||||||
mov point_default,di
|
|
||||||
.exit_scan_sect:
|
|
||||||
ret
|
|
||||||
;;;;;;;; âîññòàíîâèì çíà÷åíèÿ è ïðîäîëæèì ïîèñêè íà÷àëà ñåêöèè êîòîðàÿ íàñ óñòðîèò ))
|
|
||||||
._not_section:
|
|
||||||
mov di,find_sec_di
|
|
||||||
mov cx,di
|
|
||||||
mov bx,cx
|
|
||||||
jmp .find_start_section
|
|
||||||
.go_:
|
|
||||||
cld
|
|
||||||
mov cx,bx ;â ñx çíà÷åíèå - êîë-âî ñèìâîëîâ
|
|
||||||
|
|
||||||
mov al,byte [es:di]
|
|
||||||
push word .f_go
|
|
||||||
cmp al,' '
|
|
||||||
jz @f
|
|
||||||
jmp get_firs_sym.not_space
|
|
||||||
@@:
|
|
||||||
jmp get_firs_sym.first_sp
|
|
||||||
|
|
||||||
.f_go:
|
|
||||||
jcxz .exit_scan_sect ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå
|
|
||||||
|
|
||||||
cmp di,point_loader ; ñåêöèþ loader ìû íå çàíîñèì èíà÷å êðàõ
|
|
||||||
jz .exit_scan_sect
|
|
||||||
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé
|
|
||||||
cmp al,'['
|
|
||||||
jnz .exit_scan_sect
|
|
||||||
mov point_default,di
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
find_next_sect:
|
|
||||||
mov di,point_default
|
|
||||||
push ini_data_
|
|
||||||
pop es
|
|
||||||
mov cx,save_cx;di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê êîíöó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ
|
|
||||||
sub cx,di ;ñåé÷àñ â cx îñòàòîê ò.å. ñêîëüêî ìîæíî êðóòèòü äî êîíöà è íå âûëàçèòü íà íà÷àëî
|
|
||||||
jmp .let_s_go
|
|
||||||
.h:
|
|
||||||
push ini_data_
|
|
||||||
pop es
|
|
||||||
mov cx,save_cx;di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê êîíöó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ
|
|
||||||
; sub cx,di ;ñåé÷àñ â cx îñòàòîê ò.å. ñêîëüêî ìîæíî êðóòèòü äî êîíöà è íå âûëàçèòü íà íà÷àëî
|
|
||||||
|
|
||||||
mov al,byte [es:di]
|
|
||||||
push word .let_s_go_ret
|
|
||||||
cmp al,' '
|
|
||||||
jz @f
|
|
||||||
jmp get_firs_sym.not_space
|
|
||||||
@@:
|
|
||||||
jmp get_firs_sym.first_sp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;íàñòðîèëè óêàçàòåëü íà äåôàóëò ñåêöèþ
|
|
||||||
;áóäåì èñêàòü âíèç
|
|
||||||
.let_s_go:
|
|
||||||
call get_firs_sym
|
|
||||||
.let_s_go_ret:
|
|
||||||
jcxz .exit_scan_sect ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå
|
|
||||||
cmp al,'['
|
|
||||||
jnz .let_s_go
|
|
||||||
cmp di,point_loader
|
|
||||||
jz .let_s_go
|
|
||||||
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé
|
|
||||||
mov point_default,di
|
|
||||||
.exit_scan_sect:
|
|
||||||
ret
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;clean old cursor
|
|
||||||
clean_active_cursor:
|
|
||||||
;íå èçìåíÿåò çíà÷åíèå ax
|
|
||||||
;îòîáðàæåíèå êóðñîðà ïî óìîë÷àíèþ
|
|
||||||
lea si,point_to_hframe
|
|
||||||
mov di,962-160
|
|
||||||
mov dx,point_default
|
|
||||||
mov cx,18
|
|
||||||
.clean_show_cur:
|
|
||||||
mov bx,[si]
|
|
||||||
add di,160
|
|
||||||
cmp bx,dx
|
|
||||||
jz .clean_cursor_
|
|
||||||
sub si,2
|
|
||||||
loop .clean_show_cur
|
|
||||||
|
|
||||||
; jmp $
|
|
||||||
|
|
||||||
.clean_cursor_:
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
push ax
|
|
||||||
mov point_to_point_def,si
|
|
||||||
xor ax,ax
|
|
||||||
if DEBUG
|
|
||||||
mov ax,0x0720
|
|
||||||
end if
|
|
||||||
stosw
|
|
||||||
add di,68
|
|
||||||
stosw
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;óñòàíîâêà òàéìåðà è îòîáðàæåíèå ñ÷åò÷èêà âðåìåíè
|
|
||||||
gettime:
|
|
||||||
mov ah,0
|
|
||||||
int 1Ah
|
|
||||||
xchg ax, cx
|
|
||||||
shl eax, 10h
|
|
||||||
xchg ax, dx
|
|
||||||
ret
|
|
||||||
newtimer:
|
|
||||||
push ds
|
|
||||||
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
pushf
|
|
||||||
call far dword [old_timer]
|
|
||||||
|
|
||||||
pushad
|
|
||||||
call gettime
|
|
||||||
|
|
||||||
sub eax, dword[start_timer]
|
|
||||||
mov bx, word [value_timeout]
|
|
||||||
imul bx,18
|
|
||||||
sub bx, ax
|
|
||||||
jbe .timergo
|
|
||||||
|
|
||||||
push es
|
|
||||||
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
mov ax,bx
|
|
||||||
|
|
||||||
mov bx, 18
|
|
||||||
xor dx, dx
|
|
||||||
div bx
|
|
||||||
|
|
||||||
mov bx,10
|
|
||||||
mov di,3734
|
|
||||||
call .decode
|
|
||||||
|
|
||||||
xor ax,ax
|
|
||||||
stosw
|
|
||||||
|
|
||||||
; wait 5/4/3/2 seconds, 1 second
|
|
||||||
pop es
|
|
||||||
popad
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
iret
|
|
||||||
.timergo:
|
|
||||||
push 0
|
|
||||||
pop es
|
|
||||||
mov eax,dword [old_timer]
|
|
||||||
mov [es:8*4], eax
|
|
||||||
mov dword [timer_],eax
|
|
||||||
mov sp, word [start_stack]
|
|
||||||
mov bp,word [save_bp_from_timer]
|
|
||||||
;;íå âîññòàíîâëåíûé ñòåê :(
|
|
||||||
sti
|
|
||||||
jmp parse_start.parse_run_only
|
|
||||||
|
|
||||||
|
|
||||||
.decode:
|
|
||||||
;input ax - ÷èñëî, es:di êóäà ïèñàòü, bx=10
|
|
||||||
cmp ax,bx
|
|
||||||
jb @f
|
|
||||||
xor dx,dx
|
|
||||||
div bx
|
|
||||||
push dx
|
|
||||||
call .decode
|
|
||||||
pop ax
|
|
||||||
@@: or al,0x30
|
|
||||||
push ax
|
|
||||||
mov ah,9
|
|
||||||
stosw
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
show_bl_sc_sect:
|
|
||||||
;1) îòîáðàæåíèå ñïèñêà ñåêöèé. Åñëè ñåêöèÿ íå èìåò èìÿ - îøèáêà - âûâîä Section unname
|
|
||||||
;ïðîâåðêà íà íàëè÷åå èìåíè.
|
|
||||||
;âõîäíûå äàííûå es:di -óêàçàòåëü íà ñåêöèþ - cx ðàçìåð ñåêöèè
|
|
||||||
; push bp
|
|
||||||
mov bx,point_to_eframe
|
|
||||||
lea si,point_to_hframe
|
|
||||||
mov dx,966
|
|
||||||
|
|
||||||
.home_show_fb:
|
|
||||||
cmp si,bx
|
|
||||||
jb ._show_space_fb
|
|
||||||
mov di,[si]
|
|
||||||
sub si,2
|
|
||||||
mov cx,[si]
|
|
||||||
sub cx,di ;home first section it's end before section
|
|
||||||
call show_name_section
|
|
||||||
add dx,160
|
|
||||||
jmp .home_show_fb
|
|
||||||
._show_space_fb:
|
|
||||||
sub dx,4
|
|
||||||
push 0xb800
|
|
||||||
pop es
|
|
||||||
@@:
|
|
||||||
cmp dx,0xE64
|
|
||||||
ja .exit_show_fb
|
|
||||||
mov di,dx
|
|
||||||
;clear array for message
|
|
||||||
xor ax,ax
|
|
||||||
if DEBUG
|
|
||||||
mov ax,0x0720
|
|
||||||
end if
|
|
||||||
mov cx,39
|
|
||||||
rep stosw
|
|
||||||
;//////////////////////
|
|
||||||
|
|
||||||
add dx,160
|
|
||||||
jmp @b
|
|
||||||
.exit_show_fb:
|
|
||||||
; pop bp
|
|
||||||
ret
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
|||||||
; Copyright (c) 2009, <Lrz>
|
|
||||||
; All rights reserved.
|
|
||||||
;
|
|
||||||
; Redistribution and use in source and binary forms, with or without
|
|
||||||
; modification, are permitted provided that the following conditions are met:
|
|
||||||
; * Redistributions of source code must retain the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer.
|
|
||||||
; * Redistributions in binary form must reproduce the above copyright
|
|
||||||
; notice, this list of conditions and the following disclaimer in the
|
|
||||||
; documentation and/or other materials provided with the distribution.
|
|
||||||
; * Neither the name of the <organization> nor the
|
|
||||||
; names of its contributors may be used to endorse or promote products
|
|
||||||
; derived from this software without specific prior written permission.
|
|
||||||
;
|
|
||||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
|
||||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
;*****************************************************************************
|
|
||||||
|
|
||||||
; ýòî êîììåíòàðèé
|
|
||||||
[loader]
|
|
||||||
; ñåêöèÿ [loader] ñîäåðæèò ïàðàìåòðû çàãðóç÷èêà
|
|
||||||
; â òå÷åíèå timeout ñåêóíä çàãðóç÷èê áóäåò æäàòü ðåàêöèè ïîëüçîâàòåëÿ,
|
|
||||||
; åñëè å¸ íå ïîñëåäóåò, áóäåò çàãðóæåíà êîíôèãóðàöèÿ, óêàçàííàÿ â default
|
|
||||||
timeout=5
|
|
||||||
default=kolibri_EE
|
|
||||||
; ïðî÷èå ñåêöèè - ïî îäíîé íà êàæäóþ êîíôèãóðàöèþ
|
|
||||||
; è ïî îäíîé íà êàæäûé âòîðè÷íûé ìîäóëü
|
|
||||||
[main]
|
|
||||||
name="Kord OS v 0.00001"
|
|
||||||
descript="This is x64 OS microkernel"
|
|
||||||
kernel=kord/kord001.ker
|
|
||||||
module=kord/fat.mod
|
|
||||||
module=kord/ntfs.mod
|
|
||||||
RamdiskFS=fat
|
|
||||||
RamdiskSector=512
|
|
||||||
RamdiskCluster=1
|
|
||||||
RamdiskSize=1440K
|
|
||||||
RamdiskFile=kord/launcher,launcher
|
|
||||||
RamdiskFile=kord/filema~1/kfar,"File Managers/kfar"
|
|
||||||
[beta]
|
|
||||||
name="Kord OS v 0.00002 beta"
|
|
||||||
descript="This is x64 OS microkernel version 2"
|
|
||||||
kernel=kord/kord002.ker
|
|
||||||
module=kord/fat.mod
|
|
||||||
module=kord/ntfs.mod
|
|
||||||
RamdiskFS=fat
|
|
||||||
RamdiskSector=512
|
|
||||||
RamdiskCluster=1
|
|
||||||
RamdiskSize=1440K
|
|
||||||
RamdiskFile=kord/launcher,launcher
|
|
||||||
RamdiskFile=kord/filema~1/kfar,"File Managers/kfar"
|
|
||||||
[kolibri_EE]
|
|
||||||
name="KOLIBRY EXCLUSIVE EDITION"
|
|
||||||
descript="KOLIBRY EXCLUSIVE EDITION BEST OF THE BEST opetation system"
|
|
||||||
LoaderModule=kolibri/kolibri.ldm
|
|
||||||
RamdiskFS=FAT
|
|
||||||
RamdiskSector=512
|
|
||||||
RamdiskCluster=1
|
|
||||||
RamdiskSize=1440K
|
|
||||||
LoaderRamImage=kolibri.img
|
|
||||||
RamdiskPATH=/kolibri/
|
|
||||||
RamdiskFile=@menu,@menu
|
|
||||||
RamdiskFile=@PANEL,@PANEL
|
|
||||||
RamdiskFile=@RB,@PANEL
|
|
||||||
|
|
||||||
[legacy_kolibri]
|
|
||||||
name="KolibriOS"
|
|
||||||
descript="Standart KolibriOS"
|
|
||||||
LoaderModule=kord/kolibri.ldm
|
|
||||||
RamdiskFS=fat
|
|
||||||
RamdiskSector=512
|
|
||||||
RamdiskCluster=1
|
|
||||||
RamdiskSize=1440K
|
|
||||||
RamdiskPATH=/kolibri/
|
|
||||||
RamdiskFile=@menu,@menu
|
|
||||||
RamdiskFile=@PANEL,@PANEL
|
|
||||||
RamdiskFile=@RB,@RB
|
|
||||||
RamdiskFile=@rcher,@rcher
|
|
||||||
RamdiskFile=@ss,@ss
|
|
||||||
RamdiskFile=ac97snd,ac97snd
|
|
||||||
RamdiskFile=animage,animage
|
|
||||||
RamdiskFile=AUTOEXEC.CMD,AUTOEXEC.CMD
|
|
||||||
RamdiskFile=AUTORUN.DAT,AUTORUN.DAT
|
|
||||||
RamdiskFile=calc,calc
|
|
||||||
RamdiskFile=calendar,calendar
|
|
||||||
RamdiskFile=progs/cdp,cdp
|
|
||||||
RamdiskFile=cmd,cmd
|
|
||||||
RamdiskFile=config.inc,config.inc
|
|
||||||
RamdiskFile=copy2,copy2
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user